[ovs-dev] [PATCH 1/2] xenserver: Gracefully refresh network UUIDs on pool join or leave.

Justin Pettit jpettit at nicira.com
Mon Apr 26 22:45:05 UTC 2010


Looks good.  Thanks.

--Justin


On Apr 26, 2010, at 2:18 PM, Ben Pfaff wrote:

> The vswitch database is supposed to maintain an up-to-date UUID for the
> system's networks in the Bridge table as external-ids:network-uuids.  On
> XenServer systems, /opt/xensource/libexec/interface-reconfigure updates
> these fields as bridges are brought up and down.  Most of the time, that is
> sufficient.  However, this is one exception: when a XenServer host enters
> or leaves a pool, interface-reconfigure is not invoked, and neither is any
> other script.  So this commit introduces a new, XenServer-specific daemon
> that monitors the XenServer's pool membership status and refreshes the
> network UUIDs (by invoking the refresh-network-uuids script) if it changes.
> 
> Bug #2097.
> ---
> lib/vlog-modules.def                               |    1 +
> xenserver/automake.mk                              |    8 +
> xenserver/etc_init.d_openvswitch                   |   30 +++-
> xenserver/openvswitch-xen.spec                     |    3 +
> xenserver/ovs-xenserverd.8.in                      |   40 ++++
> xenserver/ovs-xenserverd.c                         |  228 ++++++++++++++++++++
> ...sr_share_openvswitch_scripts_sysconfig.template |    8 +
> 7 files changed, 317 insertions(+), 1 deletions(-)
> create mode 100644 xenserver/ovs-xenserverd.8.in
> create mode 100644 xenserver/ovs-xenserverd.c
> 
> diff --git a/lib/vlog-modules.def b/lib/vlog-modules.def
> index 6c2be7b..5c836d6 100644
> --- a/lib/vlog-modules.def
> +++ b/lib/vlog-modules.def
> @@ -97,5 +97,6 @@ VLOG_MODULE(wcelim)
> VLOG_MODULE(vswitchd)
> VLOG_MODULE(vt)
> VLOG_MODULE(xenserver)
> +VLOG_MODULE(xenserverd)
> 
> #undef VLOG_MODULE
> diff --git a/xenserver/automake.mk b/xenserver/automake.mk
> index b451bbb..1340b0d 100644
> --- a/xenserver/automake.mk
> +++ b/xenserver/automake.mk
> @@ -25,3 +25,11 @@ EXTRA_DIST += \
> 	xenserver/usr_sbin_xen-bugtool \
> 	xenserver/usr_share_openvswitch_scripts_refresh-network-uuids \
> 	xenserver/usr_share_openvswitch_scripts_sysconfig.template
> +
> +noinst_PROGRAMS += xenserver/ovs-xenserverd
> +xenserver_ovs_xenserverd_SOURCES = xenserver/ovs-xenserverd.c
> +xenserver_ovs_xenserverd_LDADD = lib/libopenvswitch.a
> +
> +man_MANS += xenserver/ovs-xenserverd.8
> +DISTCLEANFILES += xenserver/ovs-xenserverd.8
> +EXTRA_DIST += xenserver/ovs-xenserverd.8.in
> diff --git a/xenserver/etc_init.d_openvswitch b/xenserver/etc_init.d_openvswitch
> index 51b1d50..5adf398 100755
> --- a/xenserver/etc_init.d_openvswitch
> +++ b/xenserver/etc_init.d_openvswitch
> @@ -81,11 +81,16 @@ fi
> : ${BRCOMPATD_VALGRIND_LOG:=}
> : ${BRCOMPATD_VALGRIND_OPT:=}
> 
> +# Config variables specific to ovs-xenserverd
> +: ${XENSERVERD_PIDFILE:=/var/run/openvswitch/ovs-xenserverd.pid}
> +: ${XENSERVERD_RUN_DIR:=/var/xen/openvswitch}
> +
> # Full paths to executables & modules
> ovsdb_server="/usr/sbin/ovsdb-server"
> ovsdb_tool="/usr/bin/ovsdb-tool"
> vswitchd="/usr/sbin/ovs-vswitchd"
> brcompatd="/usr/sbin/ovs-brcompatd"
> +xenserverd="/usr/sbin/ovs-xenserverd"
> dpctl="/usr/bin/ovs-dpctl"
> appctl="/usr/bin/ovs-appctl"
> ofctl="/usr/bin/ovs-ofctl"
> @@ -293,6 +298,17 @@ function start_brcompatd {
>     fi
> }
> 
> +function start_xenserverd {
> +    if [ ! -d "$XENSERVERD_RUN_DIR" ]; then
> +        install -d -m 755 -o root -g root "$XENSERVERD_RUN_DIR"
> +    fi
> +    cd "$XENSERVERD_RUN_DIR"
> +
> +    install -d -m 755 -o root -g root `dirname $XENSERVERD_PIDFILE`
> +    action "Starting ovs-xenserverd" "$xenserverd" --no-chdir --pidfile=$XENSERVERD_PIDFILE --detach $monitor_opt -vANY:CONSOLE:EMER
> +    fi
> +}
> +
> function stop_ovsdb_server {
>     if [ -f "$OVSDB_SERVER_PIDFILE" ]; then
>         local pid=$(cat "$OVSDB_SERVER_PIDFILE")
> @@ -317,6 +333,14 @@ function stop_brcompatd {
>     fi
> }
> 
> +function stop_xenserverd {
> +    if [ -f "$XENSERVERD_PIDFILE" ]; then
> +        local pid=$(cat "$XENSERVERD_PIDFILE")
> +        action "Killing ovs-xenserverd ($pid)" kill -TERM $pid
> +        rm -f "$XENSERVERD_PIDFILE"
> +    fi
> +}
> +
> function restart_approval {
>     if test ! -t 0; then
>         # Don't prompt if invoked non-interactively.
> @@ -391,10 +415,12 @@ function start {
>     if [ "${ENABLE_BRCOMPAT}" = "y" ] ; then
>         start_brcompatd
>     fi
> +    start_xenserverd
>     touch /var/lock/subsys/openvswitch
> }
> 
> function stop {
> +    stop_xenserverd
>     stop_brcompatd
>     stop_vswitchd
>     stop_ovsdb_server
> @@ -430,12 +456,14 @@ case "$1" in
>         status -p "$OVSDB_SERVER_PIDFILE" ovsdb-server &&
>         status -p "$VSWITCHD_PIDFILE" ovs-vswitchd &&
>         (test "$ENABLE_BRCOMPAT" != "y" || 
> -            status -p "$BRCOMPATD_PIDFILE" ovs-brcompatd)
> +            status -p "$BRCOMPATD_PIDFILE" ovs-brcompatd) &&
> +        status -p "$XENSERVERD_PIDFILE" ovs-xenserverd
>         ;;
>     version)
>         /usr/sbin/ovsdb-server -V
>         /usr/sbin/ovs-vswitchd -V
>         /usr/sbin/ovs-brcompatd -V
> +        /usr/sbin/ovs-xenserverd -V
>         ;;
>     help)
>         printf "openvswitch [start|stop|restart|unload|status|version]\n"
> diff --git a/xenserver/openvswitch-xen.spec b/xenserver/openvswitch-xen.spec
> index c796a1b..bd9d27a 100644
> --- a/xenserver/openvswitch-xen.spec
> +++ b/xenserver/openvswitch-xen.spec
> @@ -79,6 +79,7 @@ install -m 755 xenserver/usr_sbin_xen-bugtool \
>              $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/xen-bugtool
> install -m 755 xenserver/usr_sbin_brctl \
>              $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/brctl
> +install -m 755 xenserver/ovs-xenserverd $RPM_BUILD_ROOT/usr/sbin/
> install -m 755 xenserver/usr_share_openvswitch_scripts_sysconfig.template \
>          $RPM_BUILD_ROOT/usr/share/openvswitch/scripts/sysconfig.template
> install -d -m 755 $RPM_BUILD_ROOT/usr/lib/xsconsole/plugins-base
> @@ -351,6 +352,7 @@ fi
> /usr/share/openvswitch/vswitch.ovsschema
> /usr/sbin/ovs-brcompatd
> /usr/sbin/ovs-vswitchd
> +/usr/sbin/ovs-xenserverd
> /usr/sbin/ovsdb-server
> /usr/bin/ovs-appctl
> /usr/bin/ovs-dpctl
> @@ -369,6 +371,7 @@ fi
> /usr/share/man/man8/ovs-ofctl.8.gz
> /usr/share/man/man8/ovs-vsctl.8.gz
> /usr/share/man/man8/ovs-vswitchd.8.gz
> +/usr/share/man/man8/ovs-xenserverd.8.gz
> /var/lib/openvswitch
> %exclude /usr/lib/xsconsole/plugins-base/*.pyc
> %exclude /usr/lib/xsconsole/plugins-base/*.pyo
> diff --git a/xenserver/ovs-xenserverd.8.in b/xenserver/ovs-xenserverd.8.in
> new file mode 100644
> index 0000000..87e76d8
> --- /dev/null
> +++ b/xenserver/ovs-xenserverd.8.in
> @@ -0,0 +1,40 @@
> +.\" -*- nroff -*-
> +.de IQ
> +.  br
> +.  ns
> +.  IP "\\$1"
> +..
> +.TH ovs\-xenserverd 8 "April 2010" "Open vSwitch" "Open vSwitch Manual"
> +.ds PN ovs\-xenserverd
> +.
> +.SH NAME
> +ovs\-xenserverd \- Open vSwitch daemon for XenServer-specific functionality
> +.
> +.SH SYNOPSIS
> +\fBovs\-xenserverd \fR[\fIoptions\fR]
> +.
> +.SH DESCRIPTION
> +A daemon that provides XenServer-specific functionality for Open
> +vSwitch.  Currently, its only purpose is to ensure that network UUIDs
> +in the Open vSwitch database are kept up-to-date when the XenServer
> +host joins or leaves a pool.  It does so by running
> +\fB at pkgdatadir@/scripts/refresh-network-uuids\fR.
> +.PP
> +\fBovs\-xenserverd\fR is useful only on Citrix XenServer hosts.
> +Running it on any other kind of host is harmless but not useful.
> +.SH OPTIONS
> +.so lib/daemon.man
> +.SS "Public Key Infrastructure Options"
> +.so lib/vlog.man
> +.so lib/common.man
> +.
> +.SH "RUNTIME MANAGEMENT COMMANDS"
> +\fBovs\-appctl\fR(8) can send commands to a running
> +\fBovs\-xenserverd\fR process.  The currently supported commands are
> +described below.
> +.so lib/vlog-unixctl.man
> +.SH "SEE ALSO"
> +.BR ovs\-appctl (8),
> +.BR ovs\-vswitchd (8),
> +.BR ovsdb\-server (1),
> +\fBINSTALL.Linux\fR in the Open vSwitch distribution.
> diff --git a/xenserver/ovs-xenserverd.c b/xenserver/ovs-xenserverd.c
> new file mode 100644
> index 0000000..72617ae
> --- /dev/null
> +++ b/xenserver/ovs-xenserverd.c
> @@ -0,0 +1,228 @@
> +/* Copyright (c) 2010 Nicira Networks
> + *
> + * 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 <errno.h>
> +#include <getopt.h>
> +#include <signal.h>
> +#include <stdlib.h>
> +#include <sys/stat.h>
> +
> +#include "command-line.h"
> +#include "daemon.h"
> +#include "dirs.h"
> +#include "poll-loop.h"
> +#include "process.h"
> +#include "socket-util.h"
> +#include "timeval.h"
> +#include "unixctl.h"
> +#include "util.h"
> +
> +#define THIS_MODULE VLM_xenserverd
> +#include "vlog.h"
> +
> +static void parse_options(int argc, char *argv[]);
> +static void usage(void) NO_RETURN;
> +
> +static void network_uuid_refresh_run(void);
> +static void network_uuid_refresh_wait(void);
> +
> +int
> +main(int argc, char *argv[])
> +{
> +    struct unixctl_server *unixctl;
> +    int retval;
> +
> +    proctitle_init(argc, argv);
> +    set_program_name(argv[0]);
> +    time_init();
> +    vlog_init();
> +    parse_options(argc, argv);
> +    signal(SIGPIPE, SIG_IGN);
> +    process_init();
> +
> +    die_if_already_running();
> +    daemonize_start();
> +
> +    retval = unixctl_server_create(NULL, &unixctl);
> +    if (retval) {
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    daemonize_complete();
> +
> +    for (;;) {
> +        network_uuid_refresh_run();
> +        unixctl_server_run(unixctl);
> +
> +        network_uuid_refresh_wait();
> +        unixctl_server_wait(unixctl);
> +
> +        poll_block();
> +    }
> +
> +    return 0;
> +}
> +
> +
> +static void
> +parse_options(int argc, char *argv[])
> +{
> +    enum {
> +        VLOG_OPTION_ENUMS
> +    };
> +    static struct option long_options[] = {
> +        {"help",        no_argument, 0, 'h'},
> +        {"version",     no_argument, 0, 'V'},
> +        DAEMON_LONG_OPTIONS,
> +        VLOG_LONG_OPTIONS,
> +        {0, 0, 0, 0},
> +    };
> +    char *short_options = long_options_to_short_options(long_options);
> +
> +    for (;;) {
> +        int c;
> +
> +        c = getopt_long(argc, argv, short_options, long_options, NULL);
> +        if (c == -1) {
> +            break;
> +        }
> +
> +        switch (c) {
> +        case 'H':
> +        case 'h':
> +            usage();
> +
> +        case 'V':
> +            OVS_PRINT_VERSION(0, 0);
> +            exit(EXIT_SUCCESS);
> +
> +        VLOG_OPTION_HANDLERS
> +        DAEMON_OPTION_HANDLERS
> +
> +        case '?':
> +            exit(EXIT_FAILURE);
> +
> +        default:
> +            abort();
> +        }
> +    }
> +    free(short_options);
> +
> +    if (optind != argc) {
> +        ovs_fatal(0, "no non-option arguments accepted");
> +    }
> +}
> +
> +static void
> +usage(void)
> +{
> +    printf("%s: Open vSwitch daemon for XenServer-specific functionality\n"
> +           "usage: %s [OPTIONS]\n", program_name, program_name);
> +    daemon_usage();
> +    vlog_usage();
> +    printf("\nOther options:\n"
> +           "  -h, --help              display this help message\n"
> +           "  -V, --version           display version information\n");
> +    exit(EXIT_SUCCESS);
> +}
> +
> +/* Network UUID refreshing.
> + *
> + * The vswitch database is supposed to maintain an up-to-date UUID for the
> + * system's networks in the Bridge table as external-ids:network-uuids.  On
> + * XenServer systems, /opt/xensource/libexec/interface-reconfigure updates
> + * these fields as bridges are brought up and down.  Most of the time, that is
> + * sufficient.  However, this is one exception: when a XenServer host enters or
> + * leaves a pool, interface-reconfigure is not invoked, and neither is any
> + * other script.  So we need to monitor the XenServer's pool membership status
> + * and refresh the network UUIDs (by invoking the refresh-network-uuids script)
> + * if it changes.
> + *
> + * This functionality should be harmless on non-XenServer systems, since they
> + * will have neither /etc/xensource/pool.conf nor refresh-network-uuids.
> + */
> +
> +/* Timestamp of /etc/xensource/pool.conf, or zeros if it does not exist. */
> +static struct timespec pool_conf_mtime;
> +
> +/* The executing instance of refresh-network-uuids, or NULL if none. */
> +static struct process *refresh_script;
> +
> +static void
> +network_uuid_refresh_run(void)
> +{
> +    struct timespec new_mtime;
> +
> +    /* If a script is running, don't do anything until it finishes. */
> +    if (refresh_script) {
> +        char *s;
> +
> +        if (!process_exited(refresh_script)) {
> +            return;
> +        }
> +
> +        s = process_status_msg(process_status(refresh_script));
> +        VLOG_INFO("refresh-network-uuids exited, %s", s);
> +        free(s);
> +
> +        process_destroy(refresh_script);
> +        refresh_script = NULL;
> +    }
> +
> +    /* Otherwise, check for a change in timestamp.
> +     *
> +     * (We will always detect a change in timestamp when we start up.  That's
> +     * good, since it means that the refresh-network-uuids script gets
> +     * thoroughly tested and we can't miss pool changes that happen when
> +     * ovs-vswitchd isn't running.)  */
> +    get_mtime("/etc/xensource/pool.conf", &new_mtime);
> +    if (new_mtime.tv_sec != pool_conf_mtime.tv_sec
> +        || new_mtime.tv_nsec != pool_conf_mtime.tv_nsec) {
> +        struct stat s;
> +        char *argv[2];
> +
> +        argv[0] = xasprintf("%s/scripts/refresh-network-uuids",
> +                            ovs_pkgdatadir);
> +        argv[1] = NULL;
> +
> +        if (!stat(argv[0], &s)) {
> +            int error = process_start(argv, NULL, 0, NULL, 0, &refresh_script);
> +            if (error) {
> +                VLOG_ERR("failed to refresh network UUIDs: %s could "
> +                         "not be started (%s)", argv[0], strerror(error));
> +            } else {
> +                VLOG_INFO("refreshing network UUIDs: started %s", argv[0]);
> +            }
> +        } else {
> +            VLOG_ERR("failed to refresh network UUIDs: could not stat %s (%s)",
> +                     argv[0], strerror(errno));
> +        }
> +
> +        pool_conf_mtime = new_mtime;
> +        free(argv[0]);
> +    }
> +}
> +
> +void
> +network_uuid_refresh_wait(void)
> +{
> +    if (refresh_script) {
> +        process_wait(refresh_script);
> +    } else if (pool_conf_mtime.tv_sec) {
> +        poll_timer_wait(1000);
> +    }
> +}
> diff --git a/xenserver/usr_share_openvswitch_scripts_sysconfig.template b/xenserver/usr_share_openvswitch_scripts_sysconfig.template
> index c639df8..6492931 100644
> --- a/xenserver/usr_share_openvswitch_scripts_sysconfig.template
> +++ b/xenserver/usr_share_openvswitch_scripts_sysconfig.template
> @@ -236,3 +236,11 @@
> #     This option's value is honored only when BRCOMPATD_VALGRIND_LOG is
> #     set to a nonempty string.
> # BRCOMPATD_VALGRIND_OPT=""
> +
> +# XENSERVERD_PIDFILE: File in which to store the pid of the running
> +#     ovs-xenserved.
> +# XENSERVERD_PIDFILE=/var/run/openvswitch/ovs-xenserverd.pid
> +
> +# XENSERVERD_RUN_DIR: Set the directory in which ovs-xenserverd should be
> +#     run.  This mainly affects where core files will be placed.
> +# XENSERVERD_RUN_DIR=/var/xen/openvswitch
> -- 
> 1.6.6.1
> 
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev_openvswitch.org





More information about the dev mailing list