From: Ethan Jackson Date: Fri, 5 Oct 2012 20:24:21 +0000 (-0700) Subject: config: Add explicit support for building on ESX. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=361906b1e2c6482d77280f345d3e42048d8c2700;p=openvswitch config: Add explicit support for building on ESX. 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 --- diff --git a/configure.ac b/configure.ac index 9ec55486..6fb30fd2 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/lib/automake.mk b/lib/automake.mk index d5927d69..f6b2aa1b 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -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 \ diff --git a/lib/command-line.c b/lib/command-line.c index ca443a34..76a4e748 100644 --- a/lib/command-line.c +++ b/lib/command-line.c @@ -92,7 +92,7 @@ run_command(int argc, char *argv[], const struct command commands[]) /* 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 */ diff --git a/lib/dpif.c b/lib/dpif.c index 7f859d77..fa9b30a6 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -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, diff --git a/lib/netdev.c b/lib/netdev.c index 394d8957..c135c6f2 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -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 index 00000000..fafad281 --- /dev/null +++ b/lib/route-table-stub.c @@ -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 +#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) +{ +} diff --git a/lib/socket-util.c b/lib/socket-util.c index f8b44cc1..a37dfe4a 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -39,7 +39,7 @@ #include "poll-loop.h" #include "util.h" #include "vlog.h" -#if AF_PACKET && __linux__ +#if AF_PACKET && LINUX_DATAPATH #include #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 } diff --git a/lib/timeval.c b/lib/timeval.c index 77247e80..d3b6685e 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -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(); } } diff --git a/lib/timeval.h b/lib/timeval.h index d9eb3c7a..cb5191c5 100644 --- a/lib/timeval.h +++ b/lib/timeval.h @@ -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); diff --git a/lib/vlandev.c b/lib/vlandev.c index ffb8e737..2440def5 100644 --- a/lib/vlandev.c +++ b/lib/vlandev.c @@ -28,7 +28,7 @@ VLOG_DEFINE_THIS_MODULE(vlandev); -#ifdef __linux__ +#ifdef LINUX_DATAPATH #include "rtnetlink-link.h" #include #include @@ -208,7 +208,7 @@ vlandev_del(const char *vlan_dev) } return error; } -#else /* !__linux__ */ +#else /* !LINUX_DATAPATH */ /* Stubs. */ int diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 index 939f2961..9d062a7d 100644 --- a/m4/openvswitch.m4 +++ b/m4/openvswitch.m4 @@ -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], diff --git a/tests/test-timeval.c b/tests/test-timeval.c index a58c0416..9896cf73 100644 --- a/tests/test-timeval.c +++ b/tests/test-timeval.c @@ -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); } diff --git a/utilities/automake.mk b/utilities/automake.mk index fdd26b82..890f8671 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -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) diff --git a/vswitchd/automake.mk b/vswitchd/automake.mk index 9092129b..fe513ac3 100644 --- a/vswitchd/automake.mk +++ b/vswitchd/automake.mk @@ -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 diff --git a/vswitchd/system-stats.c b/vswitchd/system-stats.c index e0937a39..90446f2e 100644 --- a/vswitchd/system-stats.c +++ b/vswitchd/system-stats.c @@ -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 -#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);