From 480ce8abca4ae262a4148fe757aebe3e0ddba6f6 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 16 Jul 2010 10:53:14 -0700 Subject: [PATCH] vlog: Make the vlog module catalog program-specific. Until now, the collection of vlog modules supported by a given OVS program was not specific to that program. That means that, for example, even though ovs-dpctl does not have anything to do with jsonrpc, it still has a vlog module for it. This is confusing, at best. This commit fixes the problem on some systems, in particular on ones that use GCC and the GNU linker. It uses the feature of the GNU linker described in its manual as: If an orphaned section's name is representable as a C identifier then the linker will automatically see PROVIDE two symbols: __start_SECNAME and __end_SECNAME, where SECNAME is the name of the section. These indicate the start address and end address of the orphaned section respectively. Systems that don't support these features retain the earlier behavior. This commit also fixes the annoyance that modifying lib/vlog-modules.def causes all sources files that #include "vlog.h" to recompile. --- build-aux/check-vlog-modules | 66 ++++++++++++++++ configure.ac | 1 + extras/ezio/ovs-switchui.c | 2 +- lib/automake.mk | 32 ++------ lib/stream.c | 2 +- lib/stream.h | 2 +- lib/vlog.c | 142 +++++++++++++++++++---------------- lib/vlog.h | 76 ++++++++++++------- m4/openvswitch.m4 | 75 ++++++++++++++++++ tests/test-lockfile.c | 3 +- tests/test-reconnect.c | 3 +- tests/test-stp.c | 2 + tests/test-vconn.c | 4 +- utilities/nlmon.c | 2 +- utilities/ovs-vsctl.c | 9 ++- vswitchd/ovs-brcompatd.c | 5 +- 16 files changed, 292 insertions(+), 134 deletions(-) create mode 100755 build-aux/check-vlog-modules diff --git a/build-aux/check-vlog-modules b/build-aux/check-vlog-modules new file mode 100755 index 00000000..d40c048e --- /dev/null +++ b/build-aux/check-vlog-modules @@ -0,0 +1,66 @@ +#! /bin/sh + +if test "$1" = --help; then + cat </dev/null 2>&1; then + : +else + exit 0 +fi + +# Get the list of modules declared in lib/vlog-modules.def. +vlog_modules=` + sed -n 's/^VLOG_MODULE(\([_a-zA-Z0-9]\{1,\}\)).*$/\1/p' \ + lib/vlog-modules.def \ + | LC_ALL=C sort -u | xargs echo` + +# Get the list of modules defined in some source file. +src_modules=` + git grep -h -E '^[ ]*VLOG_DEFINE(_THIS)?_MODULE\([_a-zA-Z0-9]+\)[ ]*$' \ + | sed 's/.*(\([_a-zA-Z0-9]\{1,\}\)).*/\1/' \ + | LC_ALL=C sort -u \ + | xargs echo` + +rc=0 + +for module in $vlog_modules; do + case " $src_modules " in + *" $module "*) ;; + *) echo "vlog module $module is declared in lib/vlog-modules.def but not defined by any source file"; + rc=1 ;; + esac +done + +for module in $src_modules; do + case " $vlog_modules " in + *" $module "*) ;; + *) echo "vlog module $module is defined in a source file but not declared in lib/vlog-modules.def"; + rc=1 ;; + esac +done + +exit $rc diff --git a/configure.ac b/configure.ac index 5dd6590e..dad2fb9e 100644 --- a/configure.ac +++ b/configure.ac @@ -66,6 +66,7 @@ OVS_CHECK_MALLOC_HOOKS OVS_CHECK_VALGRIND OVS_CHECK_TTY_LOCK_DIR OVS_CHECK_SOCKET_LIBS +OVS_CHECK_LINKER_SECTIONS AC_CHECK_FUNCS([strsignal]) diff --git a/extras/ezio/ovs-switchui.c b/extras/ezio/ovs-switchui.c index 092eb1e5..6f433a3f 100644 --- a/extras/ezio/ovs-switchui.c +++ b/extras/ezio/ovs-switchui.c @@ -149,7 +149,7 @@ main(int argc, char *argv[]) set_program_name(argv[0]); parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); - vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_EMER); + vlog_set_levels(NULL, VLF_CONSOLE, VLL_EMER); init_reboot_notifier(); argc -= optind; diff --git a/lib/automake.mk b/lib/automake.mk index 046e9ab6..3bf9da1c 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -263,30 +263,8 @@ lib/coverage-counters.c: $(COVERAGE_FILES) lib/coverage-scan.pl mv $@.tmp $@ EXTRA_DIST += lib/coverage-scan.pl - -# Make sure that every vlog module listed in vlog-modules.def is -# actually used somewhere. -ALL_LOCAL += check-for-unused-vlog-modules -check-for-unused-vlog-modules: - if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1; then \ - cd $(srcdir); \ - decl_vlog=`sed -n 's/^VLOG_MODULE(\([_a-z0-9]\{1,\}\)).*$$/\1/p' \ - lib/vlog-modules.def | \ - LC_ALL=C sort -u | \ - xargs echo`; \ - used_vlog=`git grep VLOG_DEFINE_THIS_MODULE | \ - sed -n 's/.*VLOG_DEFINE_THIS_MODULE(\([a-z_0-9]\{1,\}\)).*/\1/p' | \ - LC_ALL=C sort -u | \ - xargs echo`; \ - rc=0; \ - for decl in $$decl_vlog; do \ - case " $$used_vlog " in \ - *" $$decl "*) ;; \ - *) echo "vlog module $$decl is declared in lib/vlog-modules.def \ -but not used by any source file"; \ - rc=1 ;; \ - esac \ - done; \ - exit $$rc; \ - fi -.PHONY: check-for-unused-vlog-modules +ALL_LOCAL += check-vlog-modules +check-vlog-modules: + cd $(srcdir) && build-aux/check-vlog-modules +.PHONY: check-vlog-modules +EXTRA_DIST += build-aux/check-vlog-modules diff --git a/lib/stream.c b/lib/stream.c index 4d894e7e..43c95b6b 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -769,7 +769,7 @@ stream_content_type_to_string(enum stream_content_type type) void stream_report_content(const void *data, size_t size, enum stream_content_type expected_type, - enum vlog_module module, const char *stream_name) + struct vlog_module *module, const char *stream_name) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); enum stream_content_type actual_type; diff --git a/lib/stream.h b/lib/stream.h index 256667e6..5c536c6a 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -84,6 +84,6 @@ enum stream_content_type { }; void stream_report_content(const void *, size_t, enum stream_content_type, - enum vlog_module, const char *stream_name); + struct vlog_module *, const char *stream_name); #endif /* stream.h */ diff --git a/lib/vlog.c b/lib/vlog.c index 38871295..1c6d25bb 100644 --- a/lib/vlog.c +++ b/lib/vlog.c @@ -49,12 +49,24 @@ static int syslog_levels[VLL_N_LEVELS] = { #undef VLOG_LEVEL }; -/* Name for each logging module */ -static const char *module_names[VLM_N_MODULES] = { -#define VLOG_MODULE(NAME) #NAME, +/* The log modules. */ +#if USE_LINKER_SECTIONS +extern struct vlog_module *__start_vlog_modules[]; +extern struct vlog_module *__stop_vlog_modules[]; +#define vlog_modules __start_vlog_modules +#define n_vlog_modules (__stop_vlog_modules - __start_vlog_modules) +#else +#define VLOG_MODULE VLOG_DEFINE_MODULE__ +#include "vlog-modules.def" +#undef VLOG_MODULE + +struct vlog_module *vlog_modules[] = { +#define VLOG_MODULE(NAME) &VLM_##NAME, #include "vlog-modules.def" #undef VLOG_MODULE }; +#define n_vlog_modules ARRAY_SIZE(vlog_modules) +#endif /* Information about each facility. */ struct facility { @@ -68,21 +80,6 @@ static struct facility facilities[VLF_N_FACILITIES] = { #undef VLOG_FACILITY }; -/* Current log levels. */ -static int levels[VLM_N_MODULES][VLF_N_FACILITIES] = { -#define VLOG_MODULE(NAME) { VLL_INFO, VLL_INFO, VLL_INFO }, -#include "vlog-modules.def" -#undef VLOG_MODULE -}; - -/* For fast checking whether we're logging anything for a given module and - * level.*/ -enum vlog_level min_vlog_levels[VLM_N_MODULES] = { -#define VLOG_MODULE(NAME) VLL_INFO, -#include "vlog-modules.def" -#undef VLOG_MODULE -}; - /* Time at which vlog was initialized, in milliseconds. */ static long long int boot_time; @@ -93,7 +90,7 @@ static FILE *log_file; /* vlog initialized? */ static bool vlog_inited; -static void format_log_message(enum vlog_module, enum vlog_level, +static void format_log_message(const struct vlog_module *, enum vlog_level, enum vlog_facility, unsigned int msg_num, const char *message, va_list, struct ds *) PRINTF_FORMAT(5, 0); @@ -154,64 +151,76 @@ vlog_get_facility_val(const char *name) } /* Returns the name for logging module 'module'. */ -const char *vlog_get_module_name(enum vlog_module module) +const char * +vlog_get_module_name(const struct vlog_module *module) { - assert(module < VLM_N_MODULES); - return module_names[module]; + return module->name; } -/* Returns the logging module named 'name', or VLM_N_MODULES if 'name' is not - * the name of a logging module. */ -enum vlog_module -vlog_get_module_val(const char *name) +/* Returns the logging module named 'name', or NULL if 'name' is not the name + * of a logging module. */ +struct vlog_module * +vlog_module_from_name(const char *name) { - return search_name_array(name, module_names, ARRAY_SIZE(module_names)); + struct vlog_module **mp; + + for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) { + if (!strcasecmp(name, (*mp)->name)) { + return *mp; + } + } + return NULL; } /* Returns the current logging level for the given 'module' and 'facility'. */ enum vlog_level -vlog_get_level(enum vlog_module module, enum vlog_facility facility) +vlog_get_level(const struct vlog_module *module, enum vlog_facility facility) { - assert(module < VLM_N_MODULES); assert(facility < VLF_N_FACILITIES); - return levels[module][facility]; + return module->levels[facility]; } static void -update_min_level(enum vlog_module module) +update_min_level(struct vlog_module *module) { - enum vlog_level min_level = VLL_EMER; enum vlog_facility facility; + module->min_level = VLL_EMER; for (facility = 0; facility < VLF_N_FACILITIES; facility++) { if (log_file || facility != VLF_FILE) { - min_level = MAX(min_level, levels[module][facility]); + enum vlog_level level = module->levels[facility]; + if (level < module->min_level) { + module->min_level = level; + } } } - min_vlog_levels[module] = min_level; } static void -set_facility_level(enum vlog_facility facility, enum vlog_module module, +set_facility_level(enum vlog_facility facility, struct vlog_module *module, enum vlog_level level) { assert(facility >= 0 && facility < VLF_N_FACILITIES); assert(level < VLL_N_LEVELS); - if (module == VLM_ANY_MODULE) { - for (module = 0; module < VLM_N_MODULES; module++) { - levels[module][facility] = level; - update_min_level(module); + if (!module) { + struct vlog_module **mp; + + for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) { + (*mp)->levels[facility] = level; + update_min_level(*mp); } } else { - levels[module][facility] = level; + module->levels[facility] = level; update_min_level(module); } } -/* Sets the logging level for the given 'module' and 'facility' to 'level'. */ +/* Sets the logging level for the given 'module' and 'facility' to 'level'. A + * null 'module' or a 'facility' of VLF_ANY_FACILITY is treated as a wildcard + * across all modules or facilities, respectively. */ void -vlog_set_levels(enum vlog_module module, enum vlog_facility facility, +vlog_set_levels(struct vlog_module *module, enum vlog_facility facility, enum vlog_level level) { assert(facility < VLF_N_FACILITIES || facility == VLF_ANY_FACILITY); @@ -267,7 +276,7 @@ int vlog_set_log_file(const char *file_name) { char *old_log_file_name; - enum vlog_module module; + struct vlog_module **mp; int error; /* Close old log file. */ @@ -289,8 +298,8 @@ vlog_set_log_file(const char *file_name) /* Open new log file and update min_levels[] to reflect whether we actually * have a log_file. */ log_file = fopen(log_file_name, "a"); - for (module = 0; module < VLM_N_MODULES; module++) { - update_min_level(module); + for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) { + update_min_level(*mp); } /* Log success or failure. */ @@ -331,7 +340,7 @@ vlog_set_levels_from_string(const char *s_) for (module = strtok_r(s, ": \t", &save_ptr); module != NULL; module = strtok_r(NULL, ": \t", &save_ptr)) { - enum vlog_module e_module; + struct vlog_module *e_module; enum vlog_facility e_facility; facility = strtok_r(NULL, ":", &save_ptr); @@ -355,10 +364,10 @@ vlog_set_levels_from_string(const char *s_) enum vlog_level e_level; if (!strcmp(module, "ANY")) { - e_module = VLM_ANY_MODULE; + e_module = NULL; } else { - e_module = vlog_get_module_val(module); - if (e_module >= VLM_N_MODULES) { + e_module = vlog_module_from_name(module); + if (!e_module) { char *msg = xasprintf("unknown module \"%s\"", module); free(s); return msg; @@ -391,7 +400,7 @@ vlog_set_verbosity(const char *arg) ovs_fatal(0, "processing \"%s\": %s", arg, msg); } } else { - vlog_set_levels(VLM_ANY_MODULE, VLF_ANY_FACILITY, VLL_DBG); + vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG); } } @@ -473,17 +482,17 @@ char * vlog_get_levels(void) { struct ds s = DS_EMPTY_INITIALIZER; - enum vlog_module module; + struct vlog_module **mp; ds_put_format(&s, " console syslog file\n"); ds_put_format(&s, " ------- ------ ------\n"); - for (module = 0; module < VLM_N_MODULES; module++) { + for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) { ds_put_format(&s, "%-16s %4s %4s %4s\n", - vlog_get_module_name(module), - vlog_get_level_name(vlog_get_level(module, VLF_CONSOLE)), - vlog_get_level_name(vlog_get_level(module, VLF_SYSLOG)), - vlog_get_level_name(vlog_get_level(module, VLF_FILE))); + vlog_get_module_name(*mp), + vlog_get_level_name(vlog_get_level(*mp, VLF_CONSOLE)), + vlog_get_level_name(vlog_get_level(*mp, VLF_SYSLOG)), + vlog_get_level_name(vlog_get_level(*mp, VLF_FILE))); } return ds_cstr(&s); @@ -493,9 +502,9 @@ vlog_get_levels(void) * would cause some log output, false if that module and level are completely * disabled. */ bool -vlog_is_enabled(enum vlog_module module, enum vlog_level level) +vlog_is_enabled(const struct vlog_module *module, enum vlog_level level) { - return min_vlog_levels[module] >= level; + return module->min_level >= level; } static const char * @@ -514,7 +523,7 @@ fetch_braces(const char *p, const char *def, char *out, size_t out_size) } static void -format_log_message(enum vlog_module module, enum vlog_level level, +format_log_message(const struct vlog_module *module, enum vlog_level level, enum vlog_facility facility, unsigned int msg_num, const char *message, va_list args_, struct ds *s) { @@ -609,12 +618,12 @@ format_log_message(enum vlog_module module, enum vlog_level level, * * Guaranteed to preserve errno. */ void -vlog_valist(enum vlog_module module, enum vlog_level level, +vlog_valist(const struct vlog_module *module, enum vlog_level level, const char *message, va_list args) { - bool log_to_console = levels[module][VLF_CONSOLE] >= level; - bool log_to_syslog = levels[module][VLF_SYSLOG] >= level; - bool log_to_file = levels[module][VLF_FILE] >= level && log_file; + bool log_to_console = module->levels[VLF_CONSOLE] >= level; + bool log_to_syslog = module->levels[VLF_SYSLOG] >= level; + bool log_to_file = module->levels[VLF_FILE] >= level && log_file; if (log_to_console || log_to_syslog || log_to_file) { int save_errno = errno; static unsigned int msg_num; @@ -660,7 +669,8 @@ vlog_valist(enum vlog_module module, enum vlog_level level, } void -vlog(enum vlog_module module, enum vlog_level level, const char *message, ...) +vlog(const struct vlog_module *module, enum vlog_level level, + const char *message, ...) { va_list args; @@ -670,7 +680,7 @@ vlog(enum vlog_module module, enum vlog_level level, const char *message, ...) } bool -vlog_should_drop(enum vlog_module module, enum vlog_level level, +vlog_should_drop(const struct vlog_module *module, enum vlog_level level, struct vlog_rate_limit *rl) { if (!vlog_is_enabled(module, level)) { @@ -710,7 +720,7 @@ vlog_should_drop(enum vlog_module module, enum vlog_level level, } void -vlog_rate_limit(enum vlog_module module, enum vlog_level level, +vlog_rate_limit(const struct vlog_module *module, enum vlog_level level, struct vlog_rate_limit *rl, const char *message, ...) { if (!vlog_should_drop(module, level, rl)) { diff --git a/lib/vlog.h b/lib/vlog.h index 53e8f39a..7a55dea9 100644 --- a/lib/vlog.h +++ b/lib/vlog.h @@ -60,16 +60,25 @@ enum vlog_facility { const char *vlog_get_facility_name(enum vlog_facility); enum vlog_facility vlog_get_facility_val(const char *name); -/* VLM_ constant for each vlog module. */ -enum vlog_module { -#define VLOG_MODULE(NAME) VLM_##NAME, -#include "vlog-modules.def" - VLM_N_MODULES, - VLM_ANY_MODULE = -1 +/* A log module. */ +struct vlog_module { + const char *name; /* User-visible name. */ + int levels[VLF_N_FACILITIES]; /* Minimum log level for each facility. */ + int min_level; /* Minimum log level for any facility. */ }; -const char *vlog_get_module_name(enum vlog_module); -enum vlog_module vlog_get_module_val(const char *name); +/* Creates and initializes a global instance of a module named MODULE. */ +#if USE_LINKER_SECTIONS +#define VLOG_DEFINE_MODULE(MODULE) \ + VLOG_DEFINE_MODULE__(MODULE) \ + struct vlog_module *vlog_module_ptr_##MODULE \ + __attribute__((section("vlog_modules"))) = &VLM_##MODULE; +#else +#define VLOG_DEFINE_MODULE(MODULE) extern struct vlog_module VLM_##MODULE; +#endif + +const char *vlog_get_module_name(const struct vlog_module *); +struct vlog_module *vlog_module_from_name(const char *name); /* Rate-limiter for log messages. */ struct vlog_rate_limit { @@ -103,12 +112,13 @@ struct vlog_rate_limit { } /* Configuring how each module logs messages. */ -enum vlog_level vlog_get_level(enum vlog_module, enum vlog_facility); -void vlog_set_levels(enum vlog_module, enum vlog_facility, enum vlog_level); +enum vlog_level vlog_get_level(const struct vlog_module *, enum vlog_facility); +void vlog_set_levels(struct vlog_module *, + enum vlog_facility, enum vlog_level); char *vlog_set_levels_from_string(const char *); char *vlog_get_levels(void); -bool vlog_is_enabled(enum vlog_module, enum vlog_level); -bool vlog_should_drop(enum vlog_module, enum vlog_level, +bool vlog_is_enabled(const struct vlog_module *, enum vlog_level); +bool vlog_should_drop(const struct vlog_module *, enum vlog_level, struct vlog_rate_limit *); void vlog_set_verbosity(const char *arg); @@ -121,19 +131,25 @@ int vlog_reopen_log_file(void); /* Function for actual logging. */ void vlog_init(void); void vlog_exit(void); -void vlog(enum vlog_module, enum vlog_level, const char *format, ...) +void vlog(const struct vlog_module *, enum vlog_level, const char *format, ...) __attribute__((format(printf, 3, 4))); -void vlog_valist(enum vlog_module, enum vlog_level, const char *, va_list) +void vlog_valist(const struct vlog_module *, enum vlog_level, + const char *, va_list) __attribute__((format(printf, 3, 0))); -void vlog_rate_limit(enum vlog_module, enum vlog_level, +void vlog_rate_limit(const struct vlog_module *, enum vlog_level, struct vlog_rate_limit *, const char *, ...) __attribute__((format(printf, 4, 5))); -/* Defines THIS_MODULE as MODULE, for use with the convenience macros below. */ -#define VLOG_DEFINE_THIS_MODULE(MODULE) enum { THIS_MODULE = VLM_##MODULE }; +/* Creates and initializes a global instance of a module named MODULE, and + * defines a static variable named THIS_MODULE that points to it, for use with + * the convenience macros below. */ +#define VLOG_DEFINE_THIS_MODULE(MODULE) \ + VLOG_DEFINE_MODULE(MODULE) \ + static struct vlog_module *const THIS_MODULE = &VLM_##MODULE; -/* Convenience macros. These assume that THIS_MODULE is defined as the current - * module, as set up by e.g. the VLOG_DEFINE_MODULE macro above. +/* Convenience macros. These assume that THIS_MODULE points to a "struct + * vlog_module" for the current module, as set up by e.g. the + * VLOG_DEFINE_MODULE macro above. * * Guaranteed to preserve errno. */ @@ -180,20 +196,26 @@ void vlog_rate_limit(enum vlog_module, enum vlog_level, void vlog_usage(void); /* Implementation details. */ -#define VLOG(LEVEL, ...) \ - do { \ - if (min_vlog_levels[THIS_MODULE] >= LEVEL) { \ - vlog(THIS_MODULE, LEVEL, __VA_ARGS__); \ - } \ +#define VLOG(LEVEL, ...) \ + do { \ + if (THIS_MODULE->min_level >= LEVEL) { \ + vlog(THIS_MODULE, LEVEL, __VA_ARGS__); \ + } \ } while (0) #define VLOG_RL(RL, LEVEL, ...) \ do { \ - if (min_vlog_levels[THIS_MODULE] >= LEVEL) { \ + if (THIS_MODULE->min_level >= LEVEL) { \ vlog_rate_limit(THIS_MODULE, LEVEL, RL, __VA_ARGS__); \ } \ } while (0) -extern enum vlog_level min_vlog_levels[VLM_N_MODULES]; - +#define VLOG_DEFINE_MODULE__(MODULE) \ + struct vlog_module VLM_##MODULE = \ + { \ + #MODULE, /* name */ \ + { [ 0 ... VLF_N_FACILITIES - 1] = VLL_INFO }, /* levels */ \ + VLL_INFO, /* min_level */ \ + }; + #ifdef __cplusplus } #endif diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 index 0b22f64e..6fb86099 100644 --- a/m4/openvswitch.m4 +++ b/m4/openvswitch.m4 @@ -347,3 +347,78 @@ AC_DEFUN([OVS_CHECK_OVSDBMONITOR], AC_MSG_CHECKING([whether to build ovsdbmonitor]) AC_MSG_RESULT([$BUILD_OVSDBMONITOR]) AM_CONDITIONAL([BUILD_OVSDBMONITOR], [test $BUILD_OVSDBMONITOR = yes])]) + +# OVS_LINK2_IFELSE(SOURCE1, SOURCE2, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# ------------------------------------------------------------- +# Based on AC_LINK_IFELSE, but tries to link both SOURCE1 and SOURCE2 +# into a program. +# +# This macro is borrowed from acinclude.m4 in GNU PSPP, which has the +# following license: +# +# Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +m4_define([OVS_LINK2_IFELSE], +[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl +mv conftest.$ac_ext conftest1.$ac_ext +m4_ifvaln([$2], [AC_LANG_CONFTEST([$2])])dnl +mv conftest.$ac_ext conftest2.$ac_ext +rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext +ovs_link2='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest1.$ac_ext conftest2.$ac_ext $LIBS >&5' +AS_IF([_AC_DO_STDERR($ovs_link2) && { + test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + AS_TEST_X([conftest$ac_exeext]) + }], + [$3], + [echo "$as_me: failed source file 1 of 2 was:" >&5 +sed 's/^/| /' conftest1.$ac_ext >&5 +echo "$as_me: failed source file 2 of 2 was:" >&5 +sed 's/^/| /' conftest2.$ac_ext >&5 + $4]) +dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization) +dnl information created by the PGI compiler (conftest_ipa8_conftest.oo), +dnl as it would interfere with the next link command. +rm -rf conftest.dSYM conftest1.dSYM conftest2.dSYM +rm -f core conftest.err conftest1.err conftest2.err +rm -f conftest1.$ac_objext conftest2.$ac_objext conftest*_ipa8_conftest*.oo +rm -f conftest$ac_exeext +rm -f m4_ifval([$1], [conftest1.$ac_ext]) m4_ifval([$2], [conftest1.$ac_ext])[]dnl +])# OVS_LINK2_IFELSE + +dnl Defines USE_LINKER_SECTIONS to 1 if the compiler supports putting +dnl variables in sections with user-defined names and the linker +dnl automatically defines __start_SECNAME and __stop_SECNAME symbols +dnl that designate the start and end of the sections. +AC_DEFUN([OVS_CHECK_LINKER_SECTIONS], + [AC_CACHE_CHECK( + [for user-defined linker section support], + [ovs_cv_use_linker_sections], + [OVS_LINK2_IFELSE( + [AC_LANG_SOURCE( + [int a __attribute__((__section__("mysection"))) = 1; + int b __attribute__((__section__("mysection"))) = 2; + int c __attribute__((__section__("mysection"))) = 3;])], + [AC_LANG_PROGRAM( + [#include + extern int __start_mysection; + extern int __stop_mysection;], + [int n_ints = &__stop_mysection - &__start_mysection; + int *i; + for (i = &__start_mysection; i < &__start_mysection + n_ints; i++) { + printf("%d\n", *i); + }])], + [ovs_cv_use_linker_sections=yes], + [ovs_cv_use_linker_sections=no])]) + if test $ovs_cv_use_linker_sections = yes; then + AC_DEFINE([USE_LINKER_SECTIONS], [1], + [Define to 1 if the compiler support putting variables + into sections with user-defined names and the linker + automatically defines __start_SECNAME and __stop_SECNAME + symbols that designate the start and end of the section.]) + fi]) diff --git a/tests/test-lockfile.c b/tests/test-lockfile.c index f18e24e8..0feb2705 100644 --- a/tests/test-lockfile.c +++ b/tests/test-lockfile.c @@ -238,10 +238,11 @@ static const struct test tests[] = { int main(int argc, char *argv[]) { + extern struct vlog_module VLM_lockfile; size_t i; set_program_name(argv[0]); - vlog_set_levels(VLM_lockfile, VLF_ANY_FACILITY, VLL_ERR); + vlog_set_levels(&VLM_lockfile, VLF_ANY_FACILITY, VLL_ERR); if (argc != 2) { ovs_fatal(0, "exactly one argument required; use \"%s help\" for help", diff --git a/tests/test-reconnect.c b/tests/test-reconnect.c index 2bb59d5f..0f49d7f5 100644 --- a/tests/test-reconnect.c +++ b/tests/test-reconnect.c @@ -40,12 +40,13 @@ static void diff_stats(const struct reconnect_stats *old, int main(void) { + extern struct vlog_module VLM_reconnect; struct reconnect_stats prev; unsigned int old_max_tries; int old_time; char line[128]; - vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_EMER); + vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_EMER); now = 1000; reconnect = reconnect_create(now); diff --git a/tests/test-stp.c b/tests/test-stp.c index eab13d63..83d571de 100644 --- a/tests/test-stp.c +++ b/tests/test-stp.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include "stp.h" #include #include diff --git a/tests/test-vconn.c b/tests/test-vconn.c index 32228f89..12b69ca0 100644 --- a/tests/test-vconn.c +++ b/tests/test-vconn.c @@ -401,8 +401,8 @@ int main(int argc, char *argv[]) { set_program_name(argv[0]); - vlog_set_levels(VLM_ANY_MODULE, VLF_ANY_FACILITY, VLL_EMER); - vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_DBG); + vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_EMER); + vlog_set_levels(NULL, VLF_CONSOLE, VLL_DBG); signal(SIGPIPE, SIG_IGN); time_alarm(10); diff --git a/utilities/nlmon.c b/utilities/nlmon.c index 699df138..672fae47 100644 --- a/utilities/nlmon.c +++ b/utilities/nlmon.c @@ -42,7 +42,7 @@ main(int argc OVS_UNUSED, char *argv[]) int error; set_program_name(argv[0]); - vlog_set_levels(VLM_ANY_MODULE, VLF_ANY_FACILITY, VLL_DBG); + vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG); error = nl_sock_create(NETLINK_ROUTE, RTNLGRP_LINK, 0, 0, &sock); if (error) { diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index c18de47a..76e896a0 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -118,6 +118,7 @@ static void set_column(const struct vsctl_table_class *, int main(int argc, char *argv[]) { + extern struct vlog_module VLM_reconnect; struct ovsdb_idl *idl; struct vsctl_command *commands; size_t n_commands; @@ -125,8 +126,8 @@ main(int argc, char *argv[]) set_program_name(argv[0]); signal(SIGPIPE, SIG_IGN); - vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN); - vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN); + vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN); + vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN); ovsrec_init(); /* Log our arguments. This is often valuable for debugging systems. */ @@ -201,7 +202,7 @@ parse_options(int argc, char *argv[]) break; case OPT_NO_SYSLOG: - vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN); + vlog_set_levels(&VLM_vsctl, VLF_SYSLOG, VLL_WARN); break; case OPT_NO_WAIT: @@ -383,7 +384,7 @@ vsctl_fatal(const char *format, ...) message = xvasprintf(format, args); va_end(args); - vlog_set_levels(VLM_vsctl, VLF_CONSOLE, VLL_EMER); + vlog_set_levels(&VLM_vsctl, VLF_CONSOLE, VLL_EMER); VLOG_ERR("%s", message); ovs_error(0, "%s", message); vsctl_exit(EXIT_FAILURE); diff --git a/vswitchd/ovs-brcompatd.c b/vswitchd/ovs-brcompatd.c index 5e59373e..0b5ebb96 100644 --- a/vswitchd/ovs-brcompatd.c +++ b/vswitchd/ovs-brcompatd.c @@ -1287,6 +1287,7 @@ rtnl_recv_update(struct ovsdb_idl *idl, int main(int argc, char *argv[]) { + extern struct vlog_module VLM_reconnect; struct unixctl_server *unixctl; const char *remote; struct ovsdb_idl *idl; @@ -1294,8 +1295,8 @@ main(int argc, char *argv[]) proctitle_init(argc, argv); set_program_name(argv[0]); - vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN); - vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN); + vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN); + vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN); remote = parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); -- 2.30.2