# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1317386335 -7200
# Node ID a767b85f9c3410c4cbe5cca7b12bd0900415040e
# Parent ce4b969a938afa40edb6858629b6eb2905a29f04
libxl: execute hotplug scripts directly from libxl.
Added the necessary handlers to execute hotplug scripts when necessary from
libxl. Split NetBSD from Linux hotplug calls into two separate files, because
parameters for hotplug scripts are different. Linux has empty functions, since
the calling of hotplug scripts is still done using udev.
Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/Makefile
--- a/tools/libxl/Makefile Fri Sep 30 14:38:55 2011 +0200
+++ b/tools/libxl/Makefile Fri Sep 30 14:38:55 2011 +0200
@@ -33,10 +33,13 @@ LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.
LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
LIBXL_OBJS-$(CONFIG_NetBSD) += libxl_phybackend.o
LIBXL_OBJS-$(CONFIG_Linux) += libxl_nophybackend.o
+LIBXL_OBJS-$(CONFIG_NetBSD) += hotplug_netbsd.o
+LIBXL_OBJS-$(CONFIG_Linux) += hotplug_linux.o
LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
- libxl_internal.o libxl_utils.o libxl_uuid.o
$(LIBXL_OBJS-y)
+ libxl_internal.o libxl_utils.o libxl_uuid.o
libxl_hotplug.o \
+ $(LIBXL_OBJS-y)
LIBXL_OBJS += _libxl_types.o libxl_flask.o
$(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
$(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/hotplug_linux.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/hotplug_linux.c Fri Sep 30 14:38:55 2011 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011
+ * Author Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file 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 Lesser General Public License for more details.
+ */
+
+#include "libxl_internal.h"
+
+int libxl_disk_hotplug(libxl__gc *gc, char *be_path)
+{
+ return 0;
+}
+
+int libxl_nic_hotplug_connect(libxl__gc *gc, char *be_path)
+{
+ return 0;
+}
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/hotplug_netbsd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/hotplug_netbsd.c Fri Sep 30 14:38:55 2011 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011
+ * Author Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file 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 Lesser General Public License for more details.
+ */
+
+#include <sys/stat.h>
+
+#include "libxl_internal.h"
+
+int libxl_disk_hotplug(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ struct stat stab;
+ char *stype, *sstate, *script, *params;
+ char **args;
+ int nr = 0;
+ flexarray_t *f_args;
+
+ script = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s", be_path,
"script"));
+ if (!script) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to read script from %s",
+ be_path);
+ return -1;
+ }
+
+ params = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s", be_path,
"params"));
+ if (!params)
+ return -1;
+
+ sstate = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s", be_path,
"state"));
+ if (!sstate) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to read state from %s",
+ be_path);
+ return -1;
+ }
+
+ if (stat(params, &stab) < 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to get stat info\n");
+ return -1;
+ }
+ if (S_ISBLK(stab.st_mode))
+ stype = "phy";
+ if (S_ISREG(stab.st_mode))
+ stype = "file";
+ if (stype == NULL) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Not block or regular file");
+ return -1;
+ }
+
+ f_args = flexarray_make(5, 1);
+ if (!f_args)
+ return -1;
+
+ flexarray_set(f_args, nr++, script);
+ flexarray_set(f_args, nr++, be_path);
+ flexarray_set(f_args, nr++, sstate);
+ flexarray_set(f_args, nr++, stype);
+ flexarray_set(f_args, nr++, NULL);
+
+ args = (char **) flexarray_contents(f_args);
+
+ if (libxl_exec(gc, args) < 0) {
+ free(args);
+ return -1;
+ }
+
+ free(args);
+ return 0;
+}
+
+int libxl_nic_hotplug(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *sstate, *script;
+ char **args;
+ int nr = 0;
+ flexarray_t *f_args;
+
+ script = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s", be_path,
"script"));
+ if (!script) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to read script from %s",
+ be_path);
+ return -1;
+ }
+
+ sstate = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s", be_path,
"state"));
+ if (!sstate) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to read state from %s",
+ be_path);
+ return -1;
+ }
+
+ f_args = flexarray_make(4, 1);
+ if (!f_args)
+ return -1;
+
+ flexarray_set(f_args, nr++, script);
+ flexarray_set(f_args, nr++, be_path);
+ flexarray_set(f_args, nr++, sstate);
+ flexarray_set(f_args, nr++, NULL);
+
+ args = (char **) flexarray_contents(f_args);
+
+ if (libxl_exec(gc, args) < 0) {
+ free(args);
+ return -1;
+ }
+
+ free(args);
+ return 0;
+}
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Fri Sep 30 14:38:55 2011 +0200
+++ b/tools/libxl/libxl.c Fri Sep 30 14:38:55 2011 +0200
@@ -1009,6 +1009,11 @@ int libxl_device_disk_add(libxl_ctx *ctx
flexarray_append(back,
libxl__device_disk_string_of_backend(disk->backend));
flexarray_append(back, "mode");
flexarray_append(back, disk->readwrite ? "w" : "r");
+ /* TODO: add Linux scripts, NetBSD only has block */
+ flexarray_append(back, "script");
+ flexarray_append(back, libxl__sprintf(&gc, "%s/%s",
+ libxl_xen_script_dir_path(),
+ "block"));
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(&gc, "%d", disk->backend_domid));
@@ -1023,6 +1028,14 @@ int libxl_device_disk_add(libxl_ctx *ctx
libxl__xs_kvs_of_flexarray(&gc, back,
back->count),
libxl__xs_kvs_of_flexarray(&gc, front,
front->count));
+ /* Call hotplug scripts to attach device */
+ if (libxl_disk_hotplug(&gc, libxl__device_backend_path(&gc, &device)) < 0)
{
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to execute hotplug script
for disk: %s\n",
+ disk->pdev_path);
+ rc = -1;
+ goto out_free;
+ }
+
rc = 0;
out_free:
@@ -1252,6 +1265,15 @@ int libxl_device_nic_add(libxl_ctx *ctx,
libxl__xs_kvs_of_flexarray(&gc, front,
front->count));
/* FIXME: wait for plug */
+
+ /* Call hotplug scripts to attach device */
+ if (libxl_nic_hotplug(&gc, libxl__device_backend_path(&gc, &device)) < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to execute hotplug script
for nic: %s\n",
+ nic->ifname);
+ rc = -1;
+ goto out_free;
+ }
+
rc = 0;
out_free:
flexarray_free(back);
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c Fri Sep 30 14:38:55 2011 +0200
+++ b/tools/libxl/libxl_device.c Fri Sep 30 14:38:55 2011 +0200
@@ -59,6 +59,42 @@ char *libxl__device_backend_path(libxl__
device->domid, device->devid);
}
+static libxl__device_kinds libxl__device_identify(char *be_path)
+{
+ char strkind[16]; /* Longest is actually "console" */
+ int len = sizeof(string_of_kinds)/sizeof(char *);
+
+ /* /local/domain/<domid>/backend/<kind>/ */
+ if (sscanf(be_path, "/local/domain/%*d/backend/%16[^/]s", strkind) != 1)
+ return DEVICE_UNKNOWN;
+
+ for (int j = 1; j < len; j++) {
+ if (strncmp(strkind, string_of_kinds[j], 16) == 0)
+ return j;
+ }
+
+ return DEVICE_UNKNOWN;
+}
+
+static int libxl__device_hotplug(libxl__gc *gc, libxl__device_kinds device,
+ char *be_path)
+{
+ int rc = 0;
+
+ switch(device) {
+ case DEVICE_VIF:
+ rc = libxl_nic_hotplug(gc, be_path);
+ break;
+ case DEVICE_VBD:
+ rc = libxl_disk_hotplug(gc, be_path);
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
int libxl__device_generic_add(libxl__gc *gc, libxl__device *device,
char **bents, char **fents)
{
@@ -366,11 +402,13 @@ int libxl__device_destroy(libxl__gc *gc,
xs_transaction_t t;
char *state_path = libxl__sprintf(gc, "%s/state", be_path);
char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+ libxl__device_kinds device = libxl__device_identify(be_path);
int rc = 0;
if (!state)
goto out;
if (atoi(state) != 4) {
+ libxl__device_hotplug(gc, device, be_path);
xs_rm(ctx->xsh, XBT_NULL, be_path);
goto out;
}
@@ -391,6 +429,7 @@ retry_transaction:
xs_watch(ctx->xsh, state_path, be_path);
rc = 1;
} else {
+ libxl__device_hotplug(gc, device, be_path);
xs_rm(ctx->xsh, XBT_NULL, be_path);
}
out:
@@ -404,6 +443,7 @@ static int wait_for_dev_destroy(libxl__g
unsigned int n;
fd_set rfds;
char **l1 = NULL;
+ libxl__device_kinds device;
rc = 1;
nfds = xs_fileno(ctx->xsh) + 1;
@@ -415,6 +455,8 @@ static int wait_for_dev_destroy(libxl__g
char *state = libxl__xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]);
if (!state || atoi(state) == 6) {
xs_unwatch(ctx->xsh, l1[0], l1[1]);
+ device = libxl__device_identify(l1[XS_WATCH_PATH]);
+ libxl__device_hotplug(gc, device, l1[XS_WATCH_PATH]);
xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]);
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Destroyed device backend at
%s", l1[XS_WATCH_TOKEN]);
rc = 0;
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/libxl_hotplug.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_hotplug.c Fri Sep 30 14:38:55 2011 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011
+ * Author Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file 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 Lesser General Public License for more details.
+ */
+
+#include <unistd.h>
+
+#include "libxl_internal.h"
+
+int libxl_exec(libxl__gc *gc, char **cmd)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Executing: %s", cmd[0]);
+ switch(vfork()) {
+ case -1:
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to vfork\n");
+ return -1;
+ case 0:
+ execv(cmd[0], cmd);
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to execute %s\n",
+ cmd[0]);
+ exit(EXIT_FAILURE);
+ break;
+ default:
+ wait(NULL);
+ break;
+ }
+ return 0;
+}
diff -r ce4b969a938a -r a767b85f9c34 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Fri Sep 30 14:38:55 2011 +0200
+++ b/tools/libxl/libxl_internal.h Fri Sep 30 14:38:55 2011 +0200
@@ -95,7 +95,8 @@ struct libxl__ctx {
};
typedef enum {
- DEVICE_VIF = 1,
+ DEVICE_UNKNOWN = 0,
+ DEVICE_VIF,
DEVICE_VBD,
DEVICE_QDISK,
DEVICE_PCI,
@@ -230,6 +231,11 @@ _hidden int libxl__wait_for_backend(libx
/* OS dependant helper function */
_hidden int try_phy_backend(mode_t st_mode);
+/* hotplug functions */
+_hidden int libxl_exec(libxl__gc *gc, char **cmd);
+_hidden int libxl_disk_hotplug(libxl__gc *gc, char *be_path);
+_hidden int libxl_nic_hotplug(libxl__gc *gc, char *be_path);
+
/* from libxl_pci */
_hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid,
libxl_device_pci *pcidev, int starting);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|