aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-07-22 14:37:30 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-07-22 14:37:30 +0100
commit9fe075decce7db2045261794f9ab897a82cba408 (patch)
tree3200a9352121ff405b109fed0f01188c6d302f14
parent5e3d36c2c840c5da77065b0676c0f2a64fee638a (diff)
downloadxen-9fe075decce7db2045261794f9ab897a82cba408.tar.gz
xen-9fe075decce7db2045261794f9ab897a82cba408.tar.bz2
xen-9fe075decce7db2045261794f9ab897a82cba408.zip
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@amd.com>
-rw-r--r--tools/Makefile1
-rw-r--r--tools/hotplug/NetBSD/Makefile8
-rw-r--r--tools/hotplug/NetBSD/block (renamed from tools/hotplug/NetBSD/block-nbsd)0
-rw-r--r--tools/hotplug/NetBSD/vif-bridge (renamed from tools/hotplug/NetBSD/vif-bridge-nbsd)0
-rw-r--r--tools/hotplug/NetBSD/vif-ip (renamed from tools/hotplug/NetBSD/vif-ip-nbsd)0
-rw-r--r--tools/misc/xend11
-rw-r--r--tools/xenbackendd/Makefile41
-rw-r--r--tools/xenbackendd/xenbackendd.c319
8 files changed, 376 insertions, 4 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 89ee9710de..78b3990604 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -25,6 +25,7 @@ SUBDIRS-$(CONFIG_Linux) += blktap
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 --git a/tools/hotplug/NetBSD/Makefile b/tools/hotplug/NetBSD/Makefile
index 18be7df8d8..06eee0556c 100644
--- a/tools/hotplug/NetBSD/Makefile
+++ b/tools/hotplug/NetBSD/Makefile
@@ -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 --git a/tools/hotplug/NetBSD/block-nbsd b/tools/hotplug/NetBSD/block
index d853e11584..d853e11584 100644
--- a/tools/hotplug/NetBSD/block-nbsd
+++ b/tools/hotplug/NetBSD/block
diff --git a/tools/hotplug/NetBSD/vif-bridge-nbsd b/tools/hotplug/NetBSD/vif-bridge
index ecfef15012..ecfef15012 100644
--- a/tools/hotplug/NetBSD/vif-bridge-nbsd
+++ b/tools/hotplug/NetBSD/vif-bridge
diff --git a/tools/hotplug/NetBSD/vif-ip-nbsd b/tools/hotplug/NetBSD/vif-ip
index ca4fd60580..ca4fd60580 100644
--- a/tools/hotplug/NetBSD/vif-ip-nbsd
+++ b/tools/hotplug/NetBSD/vif-ip
diff --git a/tools/misc/xend b/tools/misc/xend
index 4dd550bbed..f33e35bf24 100644
--- a/tools/misc/xend
+++ b/tools/misc/xend
@@ -107,6 +107,14 @@ def start_consoled():
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 --git a/tools/xenbackendd/Makefile b/tools/xenbackendd/Makefile
new file mode 100644
index 0000000000..4421f7d27e
--- /dev/null
+++ b/tools/xenbackendd/Makefile
@@ -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 --git a/tools/xenbackendd/xenbackendd.c b/tools/xenbackendd/xenbackendd.c
new file mode 100644
index 0000000000..852a11536f
--- /dev/null
+++ b/tools/xenbackendd/xenbackendd.c
@@ -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@netbsd.org>
+ * Copyright (C) 2009 Christoph Egger <Christoph.Egger@amd.com>
+ *
+ * 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;
+}