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 9ec55486d4bf373861092787d88f2385d1da8343..6fb30fd26834a8d5679149469c4dbbca0a5cc3cf 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 d5927d69d2e7bf371f61a8951de2859ecaea880c..f6b2aa1b09a3d267b7322d3e131e04c483c9a439 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 ca443a344972e43da8681ca47175c08edd169426..76a4e748e25b764ba6519d69966e7fdbb8836956 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 7f859d77e34f4ddab7c0fde8ca6006e5a986511d..fa9b30a6abcb1609ef5dc864f3617d5e4258c9dc 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 394d8957f2488b3640be292c7a219066234e9cf3..c135c6f291210af316c657b80f086620b412790d 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 f8b44cc18741945cdd5ab7505e7dfbe4fe43389b..a37dfe4aa5cbf01572d87d69b0b3e6be2d6b7771 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 77247e80ac71583c9690522bf7e9153bfdfc7d26..d3b6685e00bb4d8b5f3b375a2f39079fc70c757a 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 d9eb3c7a61be526f245f08821577514e08a2aa46..cb5191c5ee26fdaa3e3fab513221ee2aa331516f 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 ffb8e737b7375f9a91a31a56753f0956ea8e61d2..2440def5a918977ae35f5b48a055a17dc2c6a775 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 939f29617e346a1932bfa6d6195c93a47f994bde..9d062a7dbae4c58a1ec9f8e4954b5e378d63ef03 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 a58c04169bad54dc53f85d7810ce5d62524aeec5..9896cf7372ff880b8af487c3819e47ee69c36c7b 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 fdd26b82579002dbddf19b631d07b91c91de4edb..890f8671d80b94b1fa2a57615380e5ee3a6fc3fd 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 9092129b0723db2c7df1c3cfad7cf477c65206f9..fe513ac3771f689dbc3b5dca6d1800edd542afb3 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 e0937a3931b5570326e5fcd2e9bb99e55faa689c..90446f2e2d1f585451eb646942358e96d0b77458 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);