# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1248269850 -3600
# Node ID 9ced12c28e05fe5751b3d9950b76053bdfa44e71
# Parent 5adc108c0085c6901e67d0b7ceebb1022c2c0ffd
tools: xenbackendd for NetBSD
Attached patch introduces xenbackendd. It is used on NetBSD
to launch the hotplug scripts. Later xenbackendd can be improved to
also launch qemu-dm as child process and will notice when qemu-dm
crashes.
The changes the patch makes:
- rename hotplug scripts as xenbackendd expects them
(current names were taken from pkgsrc)
- install hotplug scripts as executable scripts
- introduce xenbackendd
- build/install/launch on NetBSD only
Signed-off-by: Christoph Egger <Christoph.Egger@xxxxxxx>
---
tools/hotplug/NetBSD/block-nbsd | 91 ---------
tools/hotplug/NetBSD/vif-bridge-nbsd | 38 ----
tools/hotplug/NetBSD/vif-ip-nbsd | 36 ---
tools/Makefile | 1
tools/hotplug/NetBSD/Makefile | 8
tools/hotplug/NetBSD/block | 91 +++++++++
tools/hotplug/NetBSD/vif-bridge | 38 ++++
tools/hotplug/NetBSD/vif-ip | 36 +++
tools/misc/xend | 11 +
tools/xenbackendd/Makefile | 41 ++++
tools/xenbackendd/xenbackendd.c | 319 +++++++++++++++++++++++++++++++++++
11 files changed, 541 insertions(+), 169 deletions(-)
diff -r 5adc108c0085 -r 9ced12c28e05 tools/Makefile
--- a/tools/Makefile Wed Jul 22 14:06:21 2009 +0100
+++ b/tools/Makefile Wed Jul 22 14:37:30 2009 +0100
@@ -25,6 +25,7 @@ SUBDIRS-$(CONFIG_Linux) += blktap2
SUBDIRS-$(CONFIG_Linux) += blktap2
SUBDIRS-$(CONFIG_NetBSD) += libaio
SUBDIRS-$(CONFIG_NetBSD) += blktap2
+SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
SUBDIRS-y += libfsimage
SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
SUBDIRS-$(CONFIG_Linux) += fs-back
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/Makefile
--- a/tools/hotplug/NetBSD/Makefile Wed Jul 22 14:06:21 2009 +0100
+++ b/tools/hotplug/NetBSD/Makefile Wed Jul 22 14:37:30 2009 +0100
@@ -3,9 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk
# Xen script dir and scripts to go there.
XEN_SCRIPTS =
-XEN_SCRIPTS += block-nbsd
-XEN_SCRIPTS += vif-bridge-nbsd
-XEN_SCRIPTS += vif-ip-nbsd
+XEN_SCRIPTS += block
+XEN_SCRIPTS += vif-bridge
+XEN_SCRIPTS += vif-ip
XEN_SCRIPT_DATA =
@@ -23,7 +23,7 @@ install-scripts:
$(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
set -e; for i in $(XEN_SCRIPTS); \
do \
- $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
done
set -e; for i in $(XEN_SCRIPT_DATA); \
do \
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/block
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/block Wed Jul 22 14:37:30 2009 +0100
@@ -0,0 +1,91 @@
+#!/bin/sh -e
+
+# $NetBSD: block-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: block xsdir_backend_path state
+
+DIR=$(dirname "$0")
+. "${DIR}/hotplugpath.sh"
+
+PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+error() {
+ echo "$@" >&2
+ xenstore_write $xpath/hotplug-status error
+ exit 1
+}
+
+
+xpath=$1
+xstatus=$2
+xtype=$(xenstore-read "$xpath/type")
+xparams=$(xenstore-read "$xpath/params")
+
+case $xstatus in
+6)
+ # device removed
+ case $xtype in
+ file)
+ vnd=$(xenstore-read "$xpath/vnd" || echo none)
+ if [ $vnd != none ]; then
+ vnconfig -u $vnd
+ fi
+ ;;
+ phy)
+ ;;
+ *)
+ echo "unknown type $xtype" >&2
+ ;;
+ esac
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ case $xtype in
+ file)
+ # Store the list of available vnd(4) devices in
+ #``available_disks'', and mark them as ``free''.
+ list=`ls -1 /dev/vnd[0-9]*d | sed "s,/dev/vnd,,;s,d,," | sort
-n`
+ for i in $list; do
+ disk="vnd$i"
+ available_disks="$available_disks $disk"
+ eval $disk=free
+ done
+ # Mark the used vnd(4) devices as ``used''.
+ for disk in `sysctl hw.disknames`; do
+ case $disk in
+ vnd[0-9]*) eval $disk=used ;;
+ esac
+ done
+ # Configure the first free vnd(4) device.
+ for disk in $available_disks; do
+ eval status=\$$disk
+ if [ "$status" = "free" ] && \
+ vnconfig /dev/${disk}d $xparams >/dev/null; then
+ device=/dev/${disk}d
+ echo vnconfig /dev/${disk}d $xparams
+ break
+ fi
+ done
+ if [ x$device = x ] ; then
+ error "no available vnd device"
+ fi
+ echo xenstore-write $xpath/vnd $device
+ xenstore-write $xpath/vnd $device
+ ;;
+ phy)
+ device=$xparams
+ ;;
+ esac
+ physical_device=$(stat -f '%r' "$device")
+ echo xenstore-write $xpath/physical-device $physical_device
+ xenstore-write $xpath/physical-device $physical_device
+ echo xenstore-write $xpath/hotplug-status connected
+ xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/block-nbsd
--- a/tools/hotplug/NetBSD/block-nbsd Wed Jul 22 14:06:21 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#!/bin/sh -e
-
-# $NetBSD: block-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
-# Called by xenbackendd
-# Usage: block xsdir_backend_path state
-
-DIR=$(dirname "$0")
-. "${DIR}/hotplugpath.sh"
-
-PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
-export PATH
-
-error() {
- echo "$@" >&2
- xenstore_write $xpath/hotplug-status error
- exit 1
-}
-
-
-xpath=$1
-xstatus=$2
-xtype=$(xenstore-read "$xpath/type")
-xparams=$(xenstore-read "$xpath/params")
-
-case $xstatus in
-6)
- # device removed
- case $xtype in
- file)
- vnd=$(xenstore-read "$xpath/vnd" || echo none)
- if [ $vnd != none ]; then
- vnconfig -u $vnd
- fi
- ;;
- phy)
- ;;
- *)
- echo "unknown type $xtype" >&2
- ;;
- esac
- xenstore-rm $xpath
- exit 0
- ;;
-2)
- case $xtype in
- file)
- # Store the list of available vnd(4) devices in
- #``available_disks'', and mark them as ``free''.
- list=`ls -1 /dev/vnd[0-9]*d | sed "s,/dev/vnd,,;s,d,," | sort
-n`
- for i in $list; do
- disk="vnd$i"
- available_disks="$available_disks $disk"
- eval $disk=free
- done
- # Mark the used vnd(4) devices as ``used''.
- for disk in `sysctl hw.disknames`; do
- case $disk in
- vnd[0-9]*) eval $disk=used ;;
- esac
- done
- # Configure the first free vnd(4) device.
- for disk in $available_disks; do
- eval status=\$$disk
- if [ "$status" = "free" ] && \
- vnconfig /dev/${disk}d $xparams >/dev/null; then
- device=/dev/${disk}d
- echo vnconfig /dev/${disk}d $xparams
- break
- fi
- done
- if [ x$device = x ] ; then
- error "no available vnd device"
- fi
- echo xenstore-write $xpath/vnd $device
- xenstore-write $xpath/vnd $device
- ;;
- phy)
- device=$xparams
- ;;
- esac
- physical_device=$(stat -f '%r' "$device")
- echo xenstore-write $xpath/physical-device $physical_device
- xenstore-write $xpath/physical-device $physical_device
- echo xenstore-write $xpath/hotplug-status connected
- xenstore-write $xpath/hotplug-status connected
- exit 0
- ;;
-*)
- exit 0
- ;;
-esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/vif-bridge
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/vif-bridge Wed Jul 22 14:37:30 2009 +0100
@@ -0,0 +1,38 @@
+#!/bin/sh -e
+
+# $NetBSD: vif-bridge-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: vif-bridge xsdir_backend_path state
+
+DIR=$(dirname "$0")
+. "${DIR}/hotplugpath.sh"
+
+PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+xpath=$1
+xstatus=$2
+
+case $xstatus in
+6)
+ # device removed
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ xbridge=$(xenstore-read "$xpath/bridge")
+ xfid=$(xenstore-read "$xpath/frontend-id")
+ xhandle=$(xenstore-read "$xpath/handle")
+ iface=xvif$xfid.$xhandle
+ echo ifconfig $iface up
+ ifconfig $iface up
+ brconfig $xbridge add $iface
+ echo brconfig $xbridge add $iface
+ xenstore-write $xpath/hotplug-status connected
+ echo xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/vif-bridge-nbsd
--- a/tools/hotplug/NetBSD/vif-bridge-nbsd Wed Jul 22 14:06:21 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#!/bin/sh -e
-
-# $NetBSD: vif-bridge-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
-# Called by xenbackendd
-# Usage: vif-bridge xsdir_backend_path state
-
-DIR=$(dirname "$0")
-. "${DIR}/hotplugpath.sh"
-
-PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
-export PATH
-
-xpath=$1
-xstatus=$2
-
-case $xstatus in
-6)
- # device removed
- xenstore-rm $xpath
- exit 0
- ;;
-2)
- xbridge=$(xenstore-read "$xpath/bridge")
- xfid=$(xenstore-read "$xpath/frontend-id")
- xhandle=$(xenstore-read "$xpath/handle")
- iface=xvif$xfid.$xhandle
- echo ifconfig $iface up
- ifconfig $iface up
- brconfig $xbridge add $iface
- echo brconfig $xbridge add $iface
- xenstore-write $xpath/hotplug-status connected
- echo xenstore-write $xpath/hotplug-status connected
- exit 0
- ;;
-*)
- exit 0
- ;;
-esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/vif-ip
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/vif-ip Wed Jul 22 14:37:30 2009 +0100
@@ -0,0 +1,36 @@
+#!/bin/sh -e
+
+# $NetBSD: vif-ip-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: vif-ip xsdir_backend_path state
+
+DIR=$(dirname "$0")
+. "${DIR}/hotplugpath.sh"
+
+PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+xpath=$1
+xstatus=$2
+
+case $xstatus in
+6)
+ # device removed
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ xip=$(xenstore-read "$xpath/ip")
+ xfid=$(xenstore-read "$xpath/frontend-id")
+ xhandle=$(xenstore-read "$xpath/handle")
+ iface=xvif$xfid.$xhandle
+ echo ifconfig $iface $xip up
+ ifconfig $iface $xip up
+ xenstore-write $xpath/hotplug-status connected
+ echo xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/hotplug/NetBSD/vif-ip-nbsd
--- a/tools/hotplug/NetBSD/vif-ip-nbsd Wed Jul 22 14:06:21 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#!/bin/sh -e
-
-# $NetBSD: vif-ip-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
-# Called by xenbackendd
-# Usage: vif-ip xsdir_backend_path state
-
-DIR=$(dirname "$0")
-. "${DIR}/hotplugpath.sh"
-
-PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
-export PATH
-
-xpath=$1
-xstatus=$2
-
-case $xstatus in
-6)
- # device removed
- xenstore-rm $xpath
- exit 0
- ;;
-2)
- xip=$(xenstore-read "$xpath/ip")
- xfid=$(xenstore-read "$xpath/frontend-id")
- xhandle=$(xenstore-read "$xpath/handle")
- iface=xvif$xfid.$xhandle
- echo ifconfig $iface $xip up
- ifconfig $iface $xip up
- xenstore-write $xpath/hotplug-status connected
- echo xenstore-write $xpath/hotplug-status connected
- exit 0
- ;;
-*)
- exit 0
- ;;
-esac
diff -r 5adc108c0085 -r 9ced12c28e05 tools/misc/xend
--- a/tools/misc/xend Wed Jul 22 14:06:21 2009 +0100
+++ b/tools/misc/xend Wed Jul 22 14:37:30 2009 +0100
@@ -107,6 +107,14 @@ def start_blktapctrl():
def start_blktapctrl():
start_daemon("blktapctrl", "")
+def start_xenbackendd():
+ XENBACKENDD_DEBUG = os.getenv("XENBACKENDD_DEBUG")
+ args = ""
+ if XENBACKENDD_DEBUG:
+ args += "-d"
+ if os.uname()[0] == 'NetBSD':
+ start_daemon("xenbackendd", args)
+
def main():
try:
check_logging()
@@ -121,11 +129,13 @@ def main():
if os.uname()[0] != "SunOS":
start_xenstored()
start_consoled()
+ start_xenbackendd()
start_blktapctrl()
return daemon.start()
elif sys.argv[1] == 'trace_start':
start_xenstored()
start_consoled()
+ start_xenbackendd()
start_blktapctrl()
return daemon.start(trace=1)
elif sys.argv[1] == 'stop':
@@ -135,6 +145,7 @@ def main():
elif sys.argv[1] == 'restart':
start_xenstored()
start_consoled()
+ start_xenbackendd()
start_blktapctrl()
return daemon.stop() or daemon.start()
elif sys.argv[1] == 'status':
diff -r 5adc108c0085 -r 9ced12c28e05 tools/xenbackendd/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenbackendd/Makefile Wed Jul 22 14:37:30 2009 +0100
@@ -0,0 +1,41 @@
+# Copyright (c) 2009 Advanced Micro Devices, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; under version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+XEN_ROOT=../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+CFLAGS += -Werror
+CFLAGS += $(CFLAGS_libxenstore)
+CPPFLAGS += -DXEN_SCRIPT_DIR="\"$(XEN_SCRIPT_DIR)\""
+LDFLAGS += $(LDFLAGS_libxenstore)
+
+SBIN = xenbackendd
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: $(SBIN)
+
+.PHONY: install
+install: build
+ $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
+ $(INSTALL_PROG) xenbackendd $(DESTDIR)$(SBINDIR)
+
+.PHONY: clean
+clean:
+ rm -f $(SBIN) $(DEPS)
+
+
+%: %.c Makefile
+ $(CC) $(CFLAGS) $(CPPFLAGS) $< $(LDFLAGS) -o $@
+
+-include $(DEPS)
diff -r 5adc108c0085 -r 9ced12c28e05 tools/xenbackendd/xenbackendd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenbackendd/xenbackendd.c Wed Jul 22 14:37:30 2009 +0100
@@ -0,0 +1,319 @@
+/* $NetBSD: xenbackendd.c,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $ */
+/*
+ * Copyright (C) 2006 Manuel Bouyer <bouyer@xxxxxxxxxx>
+ * Copyright (C) 2009 Christoph Egger <Christoph.Egger@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <xs.h>
+
+#define DEVTYPE_UNKNOWN 0
+#define DEVTYPE_VIF 1
+#define DEVTYPE_VBD 2
+
+#define DOMAIN_PATH "/local/domain/0"
+
+#ifndef XEN_SCRIPT_DIR
+#error XEN_SCRIPT_DIR not defined
+#endif
+
+#ifndef VBD_SCRIPT
+#define VBD_SCRIPT XEN_SCRIPT_DIR"/block"
+#endif
+#ifndef LOG_FILE
+#define LOG_FILE "/var/log/xen/xenbackendd.log"
+#endif
+#ifndef PID_FILE
+#define PID_FILE "/var/run/xenbackendd.pid"
+#endif
+
+
+struct xs_handle *xs;
+
+int fflag = 0;
+int dflag = 0;
+
+const char *vbd_script = NULL;
+const char *log_file = NULL;
+const char *pidfile = NULL;
+
+static void
+dolog(int pri, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ va_start(ap, fmt);
+ vsyslog(pri, fmt, ap);
+ va_end(ap);
+}
+
+static void
+dodebug(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (dflag == 0)
+ return;
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ printf("\n");
+ fflush(stdout);
+}
+
+static void
+doexec(const char *cmd, const char *arg1, const char *arg2)
+{
+ dodebug("exec %s %s %s", cmd, arg1, arg2);
+ switch(vfork()) {
+ case -1:
+ dolog(LOG_ERR, "can't vfork: %s", strerror(errno));
+ break;
+ case 0:
+ execl(cmd, cmd, arg1, arg2, NULL);
+ dolog(LOG_ERR, "can't exec %s: %s", cmd, strerror(errno));
+ exit(EXIT_FAILURE);
+ /* NOTREACHED */
+ break;
+ default:
+ wait(NULL);
+ break;
+ }
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: %s [-d] [-f] [-l log_file] [-p pif_file] [-s vbd_script]\n",
+ getprogname());
+ exit(EXIT_FAILURE);
+}
+
+static int
+xen_setup(void)
+{
+ xs = xs_daemon_open();
+ if (xs == NULL) {
+ dolog(LOG_ERR,
+ "Failed to contact xenstore (%s). Is it running?",
+ strerror(errno));
+ goto out;
+ }
+
+ if (!xs_watch(xs, DOMAIN_PATH, "backend")) {
+ dolog(LOG_ERR, "xenstore watch on backend fails.");
+ goto out;
+ }
+ return 0;
+
+ out:
+ if (xs) {
+ xs_daemon_close(xs);
+ xs = NULL;
+ }
+ return -1;
+}
+
+int
+main(int argc, char * const argv[])
+{
+ char **vec;
+ unsigned int num;
+ char *s;
+ int state;
+ char *sstate;
+ char *p;
+ char buf[80];
+ int type = DEVTYPE_UNKNOWN;
+ int ch;
+ int debug_fd;
+ FILE *pidfile_f;
+
+ while ((ch = getopt(argc, argv, "dfl:p:s:")) != -1) {
+ switch (ch) {
+ case 'd':
+ dflag = 1;
+ break;
+ case 'f':
+ fflag = 1;
+ break;
+ case 'l':
+ log_file = optarg;
+ break;
+ case 'p':
+ pidfile = pidfile;
+ case 's':
+ vbd_script = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (vbd_script == NULL)
+ vbd_script = VBD_SCRIPT;
+ if (pidfile == NULL)
+ pidfile = PID_FILE;
+ if (log_file == NULL)
+ log_file = LOG_FILE;
+
+ openlog("xenbackendd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
+
+ if (fflag == 0) {
+ /* open log file */
+ debug_fd = open(log_file, O_RDWR | O_CREAT | O_TRUNC, 0644);
+ if (debug_fd == -1) {
+ dolog(LOG_ERR, "can't open %s: %s",
+ log_file, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (fflag == 0) {
+ /* daemonize */
+ pidfile_f = fopen(pidfile, "w");
+ if (pidfile_f == NULL) {
+ dolog(LOG_ERR, "can't open %s: %s",
+ pidfile, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (daemon(0, 0) < 0) {
+ dolog(LOG_ERR, "can't daemonize: %s",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ fprintf(pidfile_f, "%d\n", (int)getpid());
+ fclose(pidfile_f);
+
+ /* redirect stderr to log file */
+ if (dup2(debug_fd, STDERR_FILENO) < 0) {
+ dolog(LOG_ERR, "can't redirect stderr to %s: %s\n",
+ log_file, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* also redirect stdout if we're in debug mode */
+ if (dflag) {
+ if (dup2(debug_fd, STDOUT_FILENO) < 0) {
+ dolog(LOG_ERR,
+ "can't redirect stdout to %s: %s\n",
+ log_file, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ close(debug_fd);
+ debug_fd = -1;
+ }
+
+ if (xen_setup() < 0)
+ exit(EXIT_FAILURE);
+
+ for (;;) {
+ vec = xs_read_watch(xs, &num);
+ if (!vec) {
+ dolog(LOG_ERR, "xs_read_watch: NULL\n");
+ continue;
+ }
+
+ if (strlen(vec[XS_WATCH_PATH]) < sizeof("state"))
+ goto next1;
+
+ /* find last component of path, check if it's "state" */
+ p = &vec[XS_WATCH_PATH][
+ strlen(vec[XS_WATCH_PATH]) - sizeof("state")];
+ if (p[0] != '/')
+ goto next1;
+ p[0] = '\0';
+ p++;
+ if (strcmp(p, "state") != 0)
+ goto next1;
+
+ snprintf(buf, sizeof(buf), "%s/state", vec[XS_WATCH_PATH]);
+ sstate = xs_read(xs, XBT_NULL, buf, 0);
+ if (sstate == NULL) {
+ dolog(LOG_ERR,
+ "Failed to read %s (%s)", buf, strerror(errno));
+ goto next1;
+ }
+
+ state = atoi(sstate);
+ snprintf(buf, sizeof(buf), "%s/hotplug-status",
+ vec[XS_WATCH_PATH]);
+ s = xs_read(xs, XBT_NULL, buf, 0);
+ if (s != NULL && state != 6 /* XenbusStateClosed */)
+ goto next2;
+
+ if (strncmp(vec[XS_WATCH_PATH],
+ DOMAIN_PATH "/backend/vif",
+ strlen(DOMAIN_PATH "/backend/vif")) == 0)
+ type = DEVTYPE_VIF;
+
+ if (strncmp(vec[XS_WATCH_PATH],
+ DOMAIN_PATH "/backend/vbd",
+ strlen(DOMAIN_PATH "/backend/vbd")) == 0)
+ type = DEVTYPE_VBD;
+
+ switch(type) {
+ case DEVTYPE_VIF:
+ if (s)
+ free(s);
+ snprintf(buf, sizeof(buf), "%s/script",
+ vec[XS_WATCH_PATH]);
+ s = xs_read(xs, XBT_NULL, buf, 0);
+ if (s == NULL) {
+ dolog(LOG_ERR,
+ "Failed to read %s (%s)", buf,
+ strerror(errno));
+ goto next2;
+ }
+ doexec(s, vec[XS_WATCH_PATH], sstate);
+ break;
+
+ case DEVTYPE_VBD:
+ doexec(vbd_script, vec[XS_WATCH_PATH], sstate);
+ break;
+
+ default:
+ break;
+ }
+
+next2:
+ if (s)
+ free(s);
+ free(sstate);
+
+next1:
+ free(vec);
+ }
+
+ return 0;
+}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|