config: Add explicit support for building on ESX.
authorEthan Jackson <ethan@nicira.com>
Fri, 5 Oct 2012 20:24:21 +0000 (13:24 -0700)
committerEthan Jackson <ethan@nicira.com>
Tue, 9 Oct 2012 22:23:47 +0000 (15:23 -0700)
The ESX userspace looks quite a bit like linux, but has some key
differences which need to be specially handled in the build.  To
distinguish between ESX and systems which use the linux datapath
module, this patch adds two new macros "ESX" and "LINUX_DATAPATH".
It uses these macros to disable building code on ESX which only
applies to a true Linux environment.  In addition, it adds a new
route-table-stub implementation which is required for the build to
complete successfully on ESX.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
15 files changed:
configure.ac
lib/automake.mk
lib/command-line.c
lib/dpif.c
lib/netdev.c
lib/route-table-stub.c [new file with mode: 0644]
lib/socket-util.c
lib/timeval.c
lib/timeval.h
lib/vlandev.c
m4/openvswitch.m4
tests/test-timeval.c
utilities/automake.mk
vswitchd/automake.mk
vswitchd/system-stats.c

index 9ec5548..6fb30fd 100644 (file)
@@ -45,6 +45,7 @@ AC_SEARCH_LIBS([clock_gettime], [rt])
 AC_SEARCH_LIBS([timer_create], [rt])
 AC_SEARCH_LIBS([pcap_open_live], [pcap])
 
+OVS_CHECK_ESX
 OVS_CHECK_COVERAGE
 OVS_CHECK_NDEBUG
 OVS_CHECK_NETLINK
@@ -112,4 +113,9 @@ AC_CONFIG_COMMANDS([include/openflow/openflow.h.stamp])
 AC_CONFIG_COMMANDS([ovsdb/ovsdbmonitor/dummy], [:])
 AC_CONFIG_COMMANDS([utilities/bugtool/dummy], [:])
 
+AM_CONDITIONAL([LINUX_DATAPATH], [test "$HAVE_NETLINK" = yes && test "$ESX" = no])
+if test "$HAVE_NETLINK" = yes && test "$ESX" = no; then
+    AC_DEFINE([LINUX_DATAPATH], [1], [System uses the linux datapath module.])
+fi
+
 AC_OUTPUT
index d5927d6..f6b2aa1 100644 (file)
@@ -227,7 +227,7 @@ if HAVE_WNO_UNUSED_PARAMETER
 lib_libsflow_a_CFLAGS += -Wno-unused-parameter
 endif
 
-if HAVE_NETLINK
+if LINUX_DATAPATH
 lib_libopenvswitch_a_SOURCES += \
        lib/dpif-linux.c \
        lib/dpif-linux.h \
@@ -246,6 +246,11 @@ lib_libopenvswitch_a_SOURCES += \
        lib/route-table.h
 endif
 
+if ESX
+lib_libopenvswitch_a_SOURCES += \
+        lib/route-table-stub.c
+endif
+
 if HAVE_IF_DL
 lib_libopenvswitch_a_SOURCES += \
        lib/netdev-bsd.c \
index ca443a3..76a4e74 100644 (file)
@@ -92,7 +92,7 @@ run_command(int argc, char *argv[], const struct command commands[])
 \f
 /* Process title. */
 
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
 static char *argv_start;       /* Start of command-line arguments in memory. */
 static size_t argv_size;       /* Number of bytes of command-line arguments. */
 static char *saved_proctitle;  /* Saved command-line arguments. */
@@ -179,7 +179,7 @@ proctitle_restore(void)
         saved_proctitle = NULL;
     }
 }
-#else  /* !__linux__ */
+#else  /* !LINUX_DATAPATH*/
 /* Stubs that don't do anything on non-Linux systems. */
 
 void
@@ -196,4 +196,4 @@ void
 proctitle_restore(void)
 {
 }
-#endif  /* !__linux__ */
+#endif  /* !LINUX_DATAPATH */
index 7f859d7..fa9b30a 100644 (file)
@@ -58,7 +58,7 @@ COVERAGE_DEFINE(dpif_execute);
 COVERAGE_DEFINE(dpif_purge);
 
 static const struct dpif_class *base_dpif_classes[] = {
-#ifdef HAVE_NETLINK
+#ifdef LINUX_DATAPATH
     &dpif_linux_class,
 #endif
     &dpif_netdev_class,
index 394d895..c135c6f 100644 (file)
@@ -75,7 +75,7 @@ netdev_initialize(void)
 
         fatal_signal_add_hook(close_all_netdevs, NULL, NULL, true);
 
-#ifdef HAVE_NETLINK
+#ifdef LINUX_DATAPATH
         netdev_register_provider(&netdev_linux_class);
         netdev_register_provider(&netdev_internal_class);
         netdev_register_provider(&netdev_tap_class);
diff --git a/lib/route-table-stub.c b/lib/route-table-stub.c
new file mode 100644 (file)
index 0000000..fafad28
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (c) 2012 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. */
+
+#include <config.h>
+#include "route-table.h"
+
+#include "compiler.h"
+
+bool
+route_table_get_name(ovs_be32 ip OVS_UNUSED, char name[IFNAMSIZ] OVS_UNUSED)
+{
+    name[0] = '\0';
+    return false;
+}
+
+bool
+route_table_get_ifindex(ovs_be32 ip OVS_UNUSED, int *ifindex)
+{
+    *ifindex = 0;
+    return false;
+}
+
+void
+route_table_register(void)
+{
+}
+
+void
+route_table_unregister(void)
+{
+}
+
+void
+route_table_run(void)
+{
+}
index f8b44cc..a37dfe4 100644 (file)
@@ -39,7 +39,7 @@
 #include "poll-loop.h"
 #include "util.h"
 #include "vlog.h"
-#if AF_PACKET && __linux__
+#if AF_PACKET && LINUX_DATAPATH
 #include <linux/if_packet.h>
 #endif
 #ifdef HAVE_NETLINK
@@ -51,11 +51,9 @@ VLOG_DEFINE_THIS_MODULE(socket_util);
 
 /* #ifdefs make it a pain to maintain code: you have to try to build both ways.
  * Thus, this file compiles all of the code regardless of the target, by
- * writing "if (LINUX)" instead of "#ifdef __linux__". */
-#ifdef __linux__
-#define LINUX 1
-#else
-#define LINUX 0
+ * writing "if (LINUX_DATAPATH)" instead of "#ifdef __linux__". */
+#ifndef LINUX_DATAPATH
+#define LINUX_DATAPATH 0
 #endif
 
 #ifndef O_DIRECTORY
@@ -266,7 +264,7 @@ drain_rcvbuf(int fd)
          *
          * On other Unix-like OSes, MSG_TRUNC has no effect in the flags
          * argument. */
-        char buffer[LINUX ? 1 : 2048];
+        char buffer[LINUX_DATAPATH ? 1 : 2048];
         ssize_t n_bytes = recv(fd, buffer, sizeof buffer,
                                MSG_TRUNC | MSG_DONTWAIT);
         if (n_bytes <= 0 || n_bytes >= rcvbuf) {
@@ -335,7 +333,7 @@ make_sockaddr_un(const char *name, struct sockaddr_un *un, socklen_t *un_len,
     if (strlen(name) > MAX_UN_LEN) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
 
-        if (LINUX) {
+        if (LINUX_DATAPATH) {
             /* 'name' is too long to fit in a sockaddr_un, but we have a
              * workaround for that on Linux: shorten it by opening a file
              * descriptor for the directory part of the name and indirecting
@@ -988,7 +986,7 @@ describe_sockaddr(struct ds *string, int fd,
             }
         }
 #endif
-#if AF_PACKET && __linux__
+#if AF_PACKET && LINUX_DATAPATH
         else if (ss.ss_family == AF_PACKET) {
             struct sockaddr_ll sll;
 
@@ -1018,7 +1016,7 @@ describe_sockaddr(struct ds *string, int fd,
 }
 
 
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
 static void
 put_fd_filename(struct ds *string, int fd)
 {
@@ -1062,7 +1060,7 @@ describe_fd(int fd)
                               : S_ISFIFO(s.st_mode) ? "FIFO"
                               : S_ISLNK(s.st_mode) ? "symbolic link"
                               : "unknown"));
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
         put_fd_filename(&string, fd);
 #endif
     }
index 77247e8..d3b6685 100644 (file)
@@ -40,15 +40,7 @@ VLOG_DEFINE_THIS_MODULE(timeval);
  * to CLOCK_REALTIME. */
 static clockid_t monotonic_clock;
 
-/* Controls whether or not calls to clock_gettime() are cached.  See
- * time_cached() for a detailed explanation. */
-#if defined __x86_64__ && defined __linux__
-static bool cache_time = false;
-#else
-static bool cache_time = true;
-#endif
-
-/* Has a timer tick occurred? Only relevant if cache_time is true.
+/* Has a timer tick occurred? Only relevant if CACHE_TIME is true.
  *
  * We initialize these to true to force time_init() to get called on the first
  * call to time_msec() or another function that queries the current time. */
@@ -154,15 +146,12 @@ set_up_timer(void)
     static timer_t timer_id;    /* "static" to avoid apparent memory leak. */
     struct itimerspec itimer;
 
-    if (!cache_time) {
+    if (!CACHE_TIME) {
         return;
     }
 
     if (timer_create(monotonic_clock, NULL, &timer_id)) {
-        VLOG_WARN("timer_create failed (%s), disabling cached timing",
-                  strerror(errno));
-        cache_time = false;
-        return;
+        VLOG_FATAL("timer_create failed (%s)", strerror(errno));
     }
 
     itimer.it_interval.tv_sec = 0;
@@ -215,7 +204,7 @@ refresh_monotonic(void)
 /* Forces a refresh of the current time from the kernel.  It is not usually
  * necessary to call this function, since the time will be refreshed
  * automatically at least every TIME_UPDATE_INTERVAL milliseconds.  If
- * cache_time is false, we will always refresh the current time so this
+ * CACHE_TIME is false, we will always refresh the current time so this
  * function has no effect. */
 void
 time_refresh(void)
@@ -356,7 +345,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
             break;
         }
 
-        if (!blocked && !cache_time) {
+        if (!blocked && !CACHE_TIME) {
             block_sigalrm(&oldsigs);
             blocked = true;
         }
@@ -370,23 +359,6 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
     return retval;
 }
 
-/* True on systems (particularly x86-64 Linux) where clock_gettime() is
- * inexpensive.  On these systems, we don't bother caching the current time.
- * Instead, we consult clock_gettime() directly when needed.
- *
- * False on systems where clock_gettime() is relatively expensive.  On these
- * systems, we cache the current time and set up a periodic SIGALRM to remind
- * us to update it.
- *
- * Also false on systems (e.g. ESX) that don't support setting up timers based
- * on a monotonically increasing clock. */
-bool
-time_cached(void)
-{
-    time_init();
-    return cache_time;
-}
-
 static void
 sigalrm_handler(int sig_nr OVS_UNUSED)
 {
@@ -397,7 +369,7 @@ sigalrm_handler(int sig_nr OVS_UNUSED)
 static void
 refresh_wall_if_ticked(void)
 {
-    if (!cache_time || wall_tick) {
+    if (!CACHE_TIME || wall_tick) {
         refresh_wall();
     }
 }
@@ -405,7 +377,7 @@ refresh_wall_if_ticked(void)
 static void
 refresh_monotonic_if_ticked(void)
 {
-    if (!cache_time || monotonic_tick) {
+    if (!CACHE_TIME || monotonic_tick) {
         refresh_monotonic();
     }
 }
index d9eb3c7..cb5191c 100644 (file)
@@ -44,6 +44,22 @@ BUILD_ASSERT_DECL(TYPE_IS_SIGNED(time_t));
  * much time will be wasted in signal handlers and calls to clock_gettime(). */
 #define TIME_UPDATE_INTERVAL 100
 
+/* True on systems (particularly x86-64 Linux) where clock_gettime() is
+ * inexpensive.  On these systems, we don't bother caching the current time.
+ * Instead, we consult clock_gettime() directly when needed.
+ *
+ * False on systems where clock_gettime() is relatively expensive.  On these
+ * systems, we cache the current time and set up a periodic SIGALRM to remind
+ * us to update it.
+ *
+ * Also false on systems (e.g. ESX) that don't support setting up timers based
+ * on a monotonically increasing clock. */
+#if defined ESX || (defined __x86_64__ && defined LINUX_DATAPATH)
+#define CACHE_TIME 0
+#else
+#define CACHE_TIME 1
+#endif
+
 void time_disable_restart(void);
 void time_enable_restart(void);
 void time_postfork(void);
index ffb8e73..2440def 100644 (file)
@@ -28,7 +28,7 @@
 
 VLOG_DEFINE_THIS_MODULE(vlandev);
 
-#ifdef __linux__
+#ifdef LINUX_DATAPATH
 #include "rtnetlink-link.h"
 #include <linux/if_vlan.h>
 #include <linux/sockios.h>
@@ -208,7 +208,7 @@ vlandev_del(const char *vlan_dev)
     }
     return error;
 }
-#else  /* !__linux__ */
+#else  /* !LINUX_DATAPATH */
 /* Stubs. */
 
 int
index 939f296..9d062a7 100644 (file)
@@ -46,6 +46,16 @@ AC_DEFUN([OVS_CHECK_NDEBUG],
      [ndebug=false])
    AM_CONDITIONAL([NDEBUG], [test x$ndebug = xtrue])])
 
+dnl Checks for ESX.
+AC_DEFUN([OVS_CHECK_ESX],
+  [AC_CHECK_HEADER([vmware.h],
+                   [ESX=yes],
+                   [ESX=no])
+   AM_CONDITIONAL([ESX], [test "$ESX" = yes])
+   if test "$ESX" = yes; then
+      AC_DEFINE([ESX], [1], [Define to 1 if building on ESX.])
+   fi])
+
 dnl Checks for Netlink support.
 AC_DEFUN([OVS_CHECK_NETLINK],
   [AC_CHECK_HEADER([linux/netlink.h],
index a58c041..9896cf7 100644 (file)
@@ -99,7 +99,7 @@ main(int argc, char *argv[])
     } else if (!strcmp(argv[1], "plain")) {
         /* If we're not caching time there isn't much to test and SIGALRM won't
          * be around to pull us out of the select() call, so just skip out */
-        if (!time_cached()) {
+        if (!CACHE_TIME) {
             exit (77);
         }
 
@@ -110,7 +110,7 @@ main(int argc, char *argv[])
         char cwd[1024], *pidfile;
         FILE *success;
 
-        if (!time_cached()) {
+        if (!CACHE_TIME) {
             exit (77);
         }
 
index fdd26b8..890f867 100644 (file)
@@ -108,7 +108,7 @@ utilities_ovs_ofctl_LDADD = \
 utilities_ovs_vsctl_SOURCES = utilities/ovs-vsctl.c
 utilities_ovs_vsctl_LDADD = lib/libopenvswitch.a $(SSL_LIBS)
 
-if HAVE_NETLINK
+if LINUX_DATAPATH
 sbin_PROGRAMS += utilities/ovs-vlan-bug-workaround
 utilities_ovs_vlan_bug_workaround_SOURCES = utilities/ovs-vlan-bug-workaround.c
 utilities_ovs_vlan_bug_workaround_LDADD = lib/libopenvswitch.a $(SSL_LIBS)
index 9092129..fe513ac 100644 (file)
@@ -24,7 +24,7 @@ EXTRA_DIST += vswitchd/INTERNALS
 MAN_ROOTS += vswitchd/ovs-vswitchd.8.in
 
 if BUILD_BRCOMPAT
-if HAVE_NETLINK
+if LINUX_DATAPATH
 sbin_PROGRAMS += vswitchd/ovs-brcompatd
 vswitchd_ovs_brcompatd_SOURCES = \
        vswitchd/ovs-brcompatd.c
index e0937a3..90446f2 100644 (file)
@@ -48,13 +48,12 @@ VLOG_DEFINE_THIS_MODULE(system_stats);
 
 /* #ifdefs make it a pain to maintain code: you have to try to build both ways.
  * Thus, this file tries to compile as much of the code as possible regardless
- * of the target, by writing "if (LINUX)" instead of "#ifdef __linux__" where
- * this is possible. */
-#ifdef __linux__
+ * of the target, by writing "if (LINUX_DATAPATH)" instead of "#ifdef
+ * __linux__" where this is possible. */
+#ifdef LINUX_DATAPATH
 #include <asm/param.h>
-#define LINUX 1
 #else
-#define LINUX 0
+#define LINUX_DATAPATH 0
 #endif
 
 static void
@@ -97,7 +96,7 @@ get_page_size(void)
 static void
 get_memory_stats(struct smap *stats)
 {
-    if (!LINUX) {
+    if (!LINUX_DATAPATH) {
         unsigned int pagesize = get_page_size();
         long int phys_pages = sysconf(_SC_PHYS_PAGES);
 #ifdef _SC_AVPHYS_PAGES
@@ -170,7 +169,7 @@ get_boot_time(void)
     static long long int cache_expiration = LLONG_MIN;
     static long long int boot_time;
 
-    assert(LINUX);
+    assert(LINUX_DATAPATH);
 
     if (time_msec() >= cache_expiration) {
         static const char stat_file[] = "/proc/stat";
@@ -202,7 +201,7 @@ get_boot_time(void)
 static unsigned long long int
 ticks_to_ms(unsigned long long int ticks)
 {
-    assert(LINUX);
+    assert(LINUX_DATAPATH);
 
 #ifndef USER_HZ
 #define USER_HZ 100
@@ -235,7 +234,7 @@ get_raw_process_info(pid_t pid, struct raw_process_info *raw)
     FILE *stream;
     int n;
 
-    assert(LINUX);
+    assert(LINUX_DATAPATH);
 
     sprintf(file_name, "/proc/%lu/stat", (unsigned long int) pid);
     stream = fopen(file_name, "r");
@@ -320,7 +319,7 @@ count_crashes(pid_t pid)
     int crashes = 0;
     FILE *stream;
 
-    assert(LINUX);
+    assert(LINUX_DATAPATH);
 
     sprintf(file_name, "/proc/%lu/cmdline", (unsigned long int) pid);
     stream = fopen(file_name, "r");
@@ -363,7 +362,7 @@ get_process_info(pid_t pid, struct process_info *pinfo)
 {
     struct raw_process_info child;
 
-    assert(LINUX);
+    assert(LINUX_DATAPATH);
     if (!get_raw_process_info(pid, &child)) {
         return false;
     }
@@ -428,7 +427,7 @@ get_process_stats(struct smap *stats)
         key = xasprintf("process_%.*s",
                         (int) (extension - de->d_name), de->d_name);
         if (!smap_get(stats, key)) {
-            if (LINUX && get_process_info(pid, &pinfo)) {
+            if (LINUX_DATAPATH && get_process_info(pid, &pinfo)) {
                 smap_add_format(stats, key, "%lu,%lu,%lld,%d,%lld,%lld",
                                 pinfo.vsz, pinfo.rss, pinfo.cputime,
                                 pinfo.crashes, pinfo.booted, pinfo.uptime);