Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 00 of 13 RFC] libxl: add hotplug script calling
This series is a WIP, and I''m posting it now that it has reached a state where hotplug scripts are called directly from libxl from both Linux and NetBSD. The series has been tested with Debian stable and NetBSD current. This is not intented to be commited to the repository, mainly because it breaks xend by disabling udev rules on Linux. Also, this should be applied on top of my previous patches: libxl: fix parse_backend_path and device_backend_path to be mutual libxl: Atomicaly check backend state and set it to 5 at device_remove qemu: react to XenbusStateClosing Having that said, I have in mind to move this into a separate daemon, just like xenbackendd, but instead of listening to /local/domain/<domid>/backend/ for changes the daemon should listen to /hotplug/<domid>/. Then when the Dom0 request the addition of a device (by writting the necessary entries to /hotplug/<domid>/), the daemon should call libxl_device_*_add(...) and the same when the device is removed (I think you can get the idea). It would be nice if someone could take a look at this while I work on the rest of the series, since I think that this *could* be a separate series if it didn''t break xend compatibility. In fact it will be nice to split driver domains into two separate series, one that adds hotplug script calling to libxl (the former), and the other one that moves the device hotplug into a separate daemon, this will probably be less painful than reviewing all at once.
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 01 of 13 RFC] hotplug/block: get the type of block device from file path (NetBSD)
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1317386335 -7200 # Node ID 25752ced44427caec863c3e64185429c39b28c3a # Parent 9482810bc60588c7d340009d85a20891253be27d hotplug/block: get the type of block device from file path (NetBSD) Guess the type of block device to attach based on the file name present in xenstore, since new Xen versions don''t make a difference between a block device or an image. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 9482810bc605 -r 25752ced4442 tools/hotplug/NetBSD/block --- a/tools/hotplug/NetBSD/block Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/hotplug/NetBSD/block Fri Sep 30 14:38:55 2011 +0200 @@ -19,9 +19,14 @@ error() { xpath=$1 xstatus=$2 -xtype=$(xenstore-read "$xpath/type") xparams=$(xenstore-read "$xpath/params") +if [ -f $xparams ]; then + xtype="file" +else + xtype="phy" +fi + case $xstatus in 6) # device removed
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 02 of 13 RFC] libxl: allow libxl__exec to take a parameter containing the env variables
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1324934702 -3600 # Node ID b9a79fd1b93d44cf7b9ccf288c9f5df169adeb4d # Parent 25752ced44427caec863c3e64185429c39b28c3a libxl: allow libxl__exec to take a parameter containing the env variables Add another parameter to libxl__exec call that contains the environment variables to use when performing the execvp call. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 25752ced4442 -r b9a79fd1b93d tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Sep 30 14:38:55 2011 +0200 +++ b/tools/libxl/libxl.c Mon Dec 26 22:25:02 2011 +0100 @@ -951,7 +951,7 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, args[2] = "-autopass"; } - libxl__exec(autopass_fd, -1, -1, args[0], args); + libxl__exec(autopass_fd, -1, -1, args[0], args, NULL); abort(); x_fail: diff -r 25752ced4442 -r b9a79fd1b93d tools/libxl/libxl_bootloader.c --- a/tools/libxl/libxl_bootloader.c Fri Sep 30 14:38:55 2011 +0200 +++ b/tools/libxl/libxl_bootloader.c Mon Dec 26 22:25:02 2011 +0100 @@ -116,12 +116,12 @@ static int open_xenconsoled_pty(int *mas static pid_t fork_exec_bootloader(int *master, const char *arg0, char **args) { struct termios termattr; + char *env[] = {"TERM", "vt100", NULL}; pid_t pid = forkpty(master, NULL, NULL, NULL); if (pid == -1) return -1; else if (pid == 0) { - setenv("TERM", "vt100", 1); - libxl__exec(-1, -1, -1, arg0, args); + libxl__exec(-1, -1, -1, arg0, args, env); return -1; } diff -r 25752ced4442 -r b9a79fd1b93d tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Fri Sep 30 14:38:55 2011 +0200 +++ b/tools/libxl/libxl_dm.c Mon Dec 26 22:25:02 2011 +0100 @@ -884,7 +884,7 @@ retry_transaction: goto out_close; if (!rc) { /* inner child */ setsid(); - libxl__exec(null, logfile_w, logfile_w, dm, args); + libxl__exec(null, logfile_w, logfile_w, dm, args, NULL); } rc = 0; diff -r 25752ced4442 -r b9a79fd1b93d tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c Fri Sep 30 14:38:55 2011 +0200 +++ b/tools/libxl/libxl_exec.c Mon Dec 26 22:25:02 2011 +0100 @@ -83,7 +83,7 @@ static void check_open_fds(const char *w } void libxl__exec(int stdinfd, int stdoutfd, int stderrfd, const char *arg0, - char **args) + char **args, char **env) /* call this in the child */ { if (stdinfd != -1) @@ -106,6 +106,11 @@ void libxl__exec(int stdinfd, int stdout /* in case our caller set it to IGN. subprocesses are entitled * to assume they got DFL. */ + if (env != NULL) { + for (int i = 0; env[i] != NULL && env[i+1] != NULL; i += 2) { + setenv(env[i], env[i+1], 1); + } + } execvp(arg0, args); fprintf(stderr, "libxl: cannot execute %s: %s\n", arg0, strerror(errno)); diff -r 25752ced4442 -r b9a79fd1b93d 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 Mon Dec 26 22:25:02 2011 +0100 @@ -451,7 +451,7 @@ _hidden int libxl__spawn_check(libxl__gc /* low-level stuff, for synchronous subprocesses etc. */ _hidden void libxl__exec(int stdinfd, int stdoutfd, int stderrfd, - const char *arg0, char **args); // logs errors, never returns + const char *arg0, char **args, char **env); // logs errors, never returns /* from xl_create */ _hidden int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info, uint32_t *domid);
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 03 of 13 RFC] libxl: add libxl__forkexec function to libxl_exec
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326564288 -3600 # Node ID 74c7175a9bcfb48e4db3ad9e92bdb5eaf4f05c31 # Parent b9a79fd1b93d44cf7b9ccf288c9f5df169adeb4d libxl: add libxl__forkexec function to libxl_exec Add a new function to libxl_exec that performs a fork and executes the passed arguments using libxl__exec. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r b9a79fd1b93d -r 74c7175a9bcf tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c Mon Dec 26 22:25:02 2011 +0100 +++ b/tools/libxl/libxl_exec.c Sat Jan 14 19:04:48 2012 +0100 @@ -454,6 +454,42 @@ int libxl__spawn_check(libxl__gc *gc, li return ERROR_FAIL; } +int libxl__forkexec(libxl__gc *gc, int stdinfd, int stdoutfd, + int stderrfd, const char *arg0, char **args, + char **env, const char *what) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + int status; + int rc = 0; + pid_t pid = fork(); + + switch (pid) { + case -1: + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "fork failed\n"); + rc = -1; + break; + case 0: + libxl__exec(stdinfd, stdoutfd, stderrfd, arg0, args, env); + /* libxl__exec never returns */ + default: + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "waitpid failed for %s\n", + what); + rc = -1; + break; + } + } + if (status) + libxl_report_child_exitstatus(ctx, LIBXL__LOG_ERROR, + what, pid, status); + rc = status; + break; + } + return rc; +} + /* * Local variables: * mode: C diff -r b9a79fd1b93d -r 74c7175a9bcf tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Mon Dec 26 22:25:02 2011 +0100 +++ b/tools/libxl/libxl_internal.h Sat Jan 14 19:04:48 2012 +0100 @@ -453,6 +453,21 @@ _hidden int libxl__spawn_check(libxl__gc _hidden void libxl__exec(int stdinfd, int stdoutfd, int stderrfd, const char *arg0, char **args, char **env); // logs errors, never returns +/* + * libxl__forkexec - Executes a file synchronously + * argv0: file name associated with the file being executed. + * args: list of arguments. See execvp(3) man page for more info. + * env: environment variables. See execvp(3) man page for more info. + * + * Returns -1 if the execution fails or the exit status, as reported + * by waitpid, on success. + * + * Logs errors. + */ +_hidden int libxl__forkexec(libxl__gc *gc, int stdinfd, int stdoutfd, + int stderrfd, const char *arg0, char **args, + char **env, const char *what); + /* from xl_create */ _hidden int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info, uint32_t *domid); _hidden int libxl__domain_build(libxl__gc *gc,
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 04 of 13 RFC] libxl: wait for devices to initialize upon addition to the domain
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326564288 -3600 # Node ID 4ae3d8e89ed8b491d342ebb8877386f9b72e1c06 # Parent 74c7175a9bcfb48e4db3ad9e92bdb5eaf4f05c31 libxl: wait for devices to initialize upon addition to the domain. Block waiting for devices (with backend PHY or TAP) to initialize (switch to state 2). This is necessary because we need to call the hotplug scripts when state is 2, otherwise the execution fails. Make use of the newly introduced function libxl__wait_for_device_state. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 74c7175a9bcf -r 4ae3d8e89ed8 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/libxl/libxl.c Sat Jan 14 19:04:48 2012 +0100 @@ -1013,6 +1013,8 @@ int libxl_device_disk_add(libxl_ctx *ctx flexarray_t *front; flexarray_t *back; char *dev; + char *be_path, *state_path, *state; + struct timeval tv; libxl__device device; int major, minor, rc; @@ -1117,6 +1119,27 @@ 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)); + if (disk->backend == LIBXL_DISK_BACKEND_PHY || + disk->backend == LIBXL_DISK_BACKEND_TAP) { + be_path = libxl__device_backend_path(gc, &device); + state_path = libxl__sprintf(gc, "%s/state", be_path); + state = libxl__xs_read(gc, XBT_NULL, state_path); + + if (atoi(state) != XenbusStateInitWait) { + xs_watch(ctx->xsh, state_path, be_path); + tv.tv_sec = LIBXL_DESTROY_TIMEOUT; + tv.tv_usec = 0; + rc = libxl__wait_for_device_state(gc, &tv, XenbusStateInitWait, + NULL); + xs_unwatch(ctx->xsh, state_path, be_path); + if (rc < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to initialize disk device: %s", + disk->pdev_path); + goto out_free; + } + } + } rc = 0; out_free: @@ -1492,6 +1515,8 @@ int libxl_device_nic_add(libxl_ctx *ctx, flexarray_t *back; libxl__device device; char *dompath, **l; + char *be_path, *state_path, *state; + struct timeval tv; unsigned int nb, rc; front = flexarray_make(16, 1); @@ -1566,8 +1591,25 @@ int libxl_device_nic_add(libxl_ctx *ctx, libxl__xs_kvs_of_flexarray(gc, back, back->count), libxl__xs_kvs_of_flexarray(gc, front, front->count)); - /* FIXME: wait for plug */ + be_path = libxl__device_backend_path(gc, &device); + state_path = libxl__sprintf(gc, "%s/state", be_path); + state = libxl__xs_read(gc, XBT_NULL, state_path); + + if (atoi(state) != XenbusStateInitWait) { + xs_watch(ctx->xsh, state_path, be_path); + tv.tv_sec = LIBXL_DESTROY_TIMEOUT; + tv.tv_usec = 0; + rc = libxl__wait_for_device_state(gc, &tv, XenbusStateInitWait, NULL); + xs_unwatch(ctx->xsh, state_path, be_path); + if (rc < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to initialize nic device: %s", + nic->ifname); + goto out_free; + } + } rc = 0; + out_free: flexarray_free(back); flexarray_free(front);
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 05 of 13 RFC] hotplug NetBSD: pass an action instead of a state to hotplug scripts
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326564288 -3600 # Node ID 0b45289e57b9fbeee3780f24a6398f7911a3320c # Parent 4ae3d8e89ed8b491d342ebb8877386f9b72e1c06 hotplug NetBSD: pass an action instead of a state to hotplug scripts change second parameter of NetBSD hotplug scripts to take an action (CONNECT/DISCONNECT) instead of a xenbus state. This patch also changes the behaviour of xenbackend to pass an action instead of a state. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 4ae3d8e89ed8 -r 0b45289e57b9 tools/hotplug/NetBSD/block --- a/tools/hotplug/NetBSD/block Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/hotplug/NetBSD/block Sat Jan 14 19:04:48 2012 +0100 @@ -18,7 +18,7 @@ error() { xpath=$1 -xstatus=$2 +xaction=$2 xparams=$(xenstore-read "$xpath/params") if [ -f $xparams ]; then @@ -27,8 +27,8 @@ else xtype="phy" fi -case $xstatus in -6) +case $xaction in +2) # device removed case $xtype in file) @@ -46,7 +46,7 @@ 6) xenstore-rm $xpath exit 0 ;; -2) +1) case $xtype in file) # Store the list of available vnd(4) devices in diff -r 4ae3d8e89ed8 -r 0b45289e57b9 tools/hotplug/NetBSD/vif-bridge --- a/tools/hotplug/NetBSD/vif-bridge Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/hotplug/NetBSD/vif-bridge Sat Jan 14 19:04:48 2012 +0100 @@ -11,15 +11,15 @@ PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${P export PATH xpath=$1 -xstatus=$2 +xaction=$2 -case $xstatus in -6) +case $xaction in +2) # device removed xenstore-rm $xpath exit 0 ;; -2) +1) xbridge=$(xenstore-read "$xpath/bridge") xfid=$(xenstore-read "$xpath/frontend-id") xhandle=$(xenstore-read "$xpath/handle") diff -r 4ae3d8e89ed8 -r 0b45289e57b9 tools/hotplug/NetBSD/vif-ip --- a/tools/hotplug/NetBSD/vif-ip Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/hotplug/NetBSD/vif-ip Sat Jan 14 19:04:48 2012 +0100 @@ -11,15 +11,15 @@ PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${P export PATH xpath=$1 -xstatus=$2 +xaction=$2 -case $xstatus in -6) +case $xaction in +2) # device removed xenstore-rm $xpath exit 0 ;; -2) +1) xip=$(xenstore-read "$xpath/ip") xfid=$(xenstore-read "$xpath/frontend-id") xhandle=$(xenstore-read "$xpath/handle") diff -r 4ae3d8e89ed8 -r 0b45289e57b9 tools/xenbackendd/xenbackendd.c --- a/tools/xenbackendd/xenbackendd.c Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/xenbackendd/xenbackendd.c Sat Jan 14 19:04:48 2012 +0100 @@ -34,6 +34,9 @@ #define DEVTYPE_VIF 1 #define DEVTYPE_VBD 2 +#define CONNECT "1" +#define DISCONNECT "2" + #define DOMAIN_PATH "/local/domain/0" #ifndef XEN_SCRIPT_DIR @@ -149,6 +152,7 @@ main(int argc, char * const argv[]) unsigned int num; char *s; int state; + char *action; char *sstate; char *p; char buf[80]; @@ -297,11 +301,13 @@ main(int argc, char * const argv[]) strerror(errno)); goto next2; } - doexec(s, vec[XS_WATCH_PATH], sstate); + action = (state == 6 ? DISCONNECT : CONNECT); + doexec(s, vec[XS_WATCH_PATH], action); break; case DEVTYPE_VBD: - doexec(vbd_script, vec[XS_WATCH_PATH], sstate); + action = (state == 6 ? DISCONNECT : CONNECT); + doexec(vbd_script, vec[XS_WATCH_PATH], action); break; default:
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 06 of 13 RFC] libxl: perform xenstore device cleanup from libxl
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326728389 -3600 # Node ID f7b6d7cd98202be1ca642949c4722c5e6da75540 # Parent 0b45289e57b9fbeee3780f24a6398f7911a3320c libxl: perform xenstore device cleanup from libxl Perform cleanup of xenstore device entries in libxl, instead of relying on xen-hotplug-cleanup script. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 0b45289e57b9 -r f7b6d7cd9820 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/libxl/libxl_device.c Mon Jan 16 16:39:49 2012 +0100 @@ -414,6 +414,28 @@ start: return rc; } +int libxl__device_cleanup(libxl__gc *gc, libxl__device *dev) { + libxl_ctx *ctx = libxl__gc_owner(gc); + char *path = libxl__device_backend_path(gc, dev); + unsigned int nb = 0; + char *last; + + if (!path) + return 0; + + xs_rm(ctx->xsh, XBT_NULL, path); + + for (last = strrchr(path, ''/''); last != NULL; last = strrchr(path, ''/'')) { + *last = ''\0''; + if (!libxl__xs_directory(gc, XBT_NULL, path, &nb)) + continue; + if (nb == 0) { + xs_rm(ctx->xsh, XBT_NULL, path); + } + } + return 0; +} + /* * Handler function for device destruction to be passed to * libxl__wait_for_device_state @@ -421,14 +443,26 @@ start: static int destroy_device(libxl__gc *gc, char **l1, char *state) { libxl_ctx *ctx = libxl__gc_owner(gc); + libxl__device dev; + int rc = -1; xs_unwatch(ctx->xsh, l1[0], l1[1]); - xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]); + + rc = libxl__parse_backend_path(gc, l1[0], &dev); + if (rc < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "failed to generate device from backend path %s", + l1[0]); + goto out; + } + + libxl__device_cleanup(gc, &dev); LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Destroyed device backend at %s", l1[XS_WATCH_TOKEN]); - - return 0; + rc = 0; +out: + return rc; } /* @@ -454,7 +488,7 @@ retry_transaction: if (atoi(state) != 4) { xs_transaction_end(ctx->xsh, t, 0); libxl__device_destroy_tapdisk(gc, be_path); - xs_rm(ctx->xsh, XBT_NULL, be_path); + libxl__device_cleanup(gc, dev); goto out; } @@ -495,7 +529,7 @@ int libxl__device_destroy(libxl__gc *gc, char *be_path = libxl__device_backend_path(gc, dev); char *fe_path = libxl__device_frontend_path(gc, dev); - xs_rm(ctx->xsh, XBT_NULL, be_path); + libxl__device_cleanup(gc, dev); xs_rm(ctx->xsh, XBT_NULL, fe_path); libxl__device_destroy_tapdisk(gc, be_path); diff -r 0b45289e57b9 -r f7b6d7cd9820 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Sat Jan 14 19:04:48 2012 +0100 +++ b/tools/libxl/libxl_internal.h Mon Jan 16 16:39:49 2012 +0100 @@ -306,6 +306,11 @@ _hidden int libxl__wait_for_device_state libxl__device_state_handler handler); /* + * libxl__device_cleanup - clean xenstore entries recursively for a given device + */ +_hidden int libxl__device_cleanup(libxl__gc *gc, libxl__device *dev); + +/* * libxl__try_phy_backend - Check if there''s support for the passed * type of file using the PHY backend * st_mode: mode_t of the file, as returned by stat function
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 07 of 13 RFC] libxl: remove force parameter from libxl__device_remove
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326728426 -3600 # Node ID 2a28a1126ab2fd6ab6b5c959daabdc6b3afd1fc6 # Parent f7b6d7cd98202be1ca642949c4722c5e6da75540 libxl: remove force parameter from libxl__device_remove All callers where using the wait parameter from libxl__device_remove, so it''s safe to simplify the logic of the function and assume that the callers always want libxl__device_remove to wait for the unplug of the device. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r f7b6d7cd9820 -r 2a28a1126ab2 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jan 16 16:39:49 2012 +0100 +++ b/tools/libxl/libxl.c Mon Jan 16 16:40:26 2012 +0100 @@ -1160,7 +1160,7 @@ int libxl_device_disk_remove(libxl_ctx * rc = libxl__device_from_disk(gc, domid, disk, &device); if (rc != 0) goto out; - rc = libxl__device_remove(gc, &device, 1); + rc = libxl__device_remove(gc, &device); out: GC_FREE; return rc; @@ -1628,7 +1628,7 @@ int libxl_device_nic_remove(libxl_ctx *c rc = libxl__device_from_nic(gc, domid, nic, &device); if (rc != 0) goto out; - rc = libxl__device_remove(gc, &device, 1); + rc = libxl__device_remove(gc, &device); out: GC_FREE; return rc; @@ -1968,7 +1968,7 @@ int libxl_device_vkb_remove(libxl_ctx *c rc = libxl__device_from_vkb(gc, domid, vkb, &device); if (rc != 0) goto out; - rc = libxl__device_remove(gc, &device, 1); + rc = libxl__device_remove(gc, &device); out: GC_FREE; return rc; @@ -2085,7 +2085,7 @@ int libxl_device_vfb_remove(libxl_ctx *c rc = libxl__device_from_vfb(gc, domid, vfb, &device); if (rc != 0) goto out; - rc = libxl__device_remove(gc, &device, 1); + rc = libxl__device_remove(gc, &device); out: GC_FREE; return rc; diff -r f7b6d7cd9820 -r 2a28a1126ab2 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Mon Jan 16 16:39:49 2012 +0100 +++ b/tools/libxl/libxl_device.c Mon Jan 16 16:40:26 2012 +0100 @@ -469,13 +469,14 @@ out: * Returns 0 (device already destroyed) or 1 (caller must * wait_for_dev_destroy) on success, ERROR_* on fail. */ -int libxl__device_remove(libxl__gc *gc, libxl__device *dev, int wait) +int libxl__device_remove(libxl__gc *gc, libxl__device *dev) { libxl_ctx *ctx = libxl__gc_owner(gc); xs_transaction_t t; char *be_path = libxl__device_backend_path(gc, dev); char *state_path = libxl__sprintf(gc, "%s/state", be_path); char *state; + struct timeval tv; int rc = 0; retry_transaction: @@ -506,18 +507,13 @@ retry_transaction: xs_watch(ctx->xsh, state_path, be_path); libxl__device_destroy_tapdisk(gc, be_path); - if (wait) { - struct timeval tv; - tv.tv_sec = LIBXL_DESTROY_TIMEOUT; - tv.tv_usec = 0; - rc = libxl__wait_for_device_state(gc, &tv, XenbusStateClosed, - destroy_device); - if (rc < 0) /* an error or timeout occurred, clear watches */ - xs_unwatch(ctx->xsh, state_path, be_path); - xs_rm(ctx->xsh, XBT_NULL, libxl__device_frontend_path(gc, dev)); - } else { - rc = 1; /* Caller must wait_for_dev_destroy */ - } + tv.tv_sec = LIBXL_DESTROY_TIMEOUT; + tv.tv_usec = 0; + rc = libxl__wait_for_device_state(gc, &tv, XenbusStateClosed, + destroy_device); + if (rc < 0) /* an error or timeout occurred, clear watches */ + xs_unwatch(ctx->xsh, state_path, be_path); + xs_rm(ctx->xsh, XBT_NULL, libxl__device_frontend_path(gc, dev)); out: return rc; diff -r f7b6d7cd9820 -r 2a28a1126ab2 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Mon Jan 16 16:39:49 2012 +0100 +++ b/tools/libxl/libxl_internal.h Mon Jan 16 16:40:26 2012 +0100 @@ -275,7 +275,7 @@ _hidden char *libxl__device_backend_path _hidden char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device); _hidden int libxl__parse_backend_path(libxl__gc *gc, const char *path, libxl__device *dev); -_hidden int libxl__device_remove(libxl__gc *gc, libxl__device *dev, int wait); +_hidden int libxl__device_remove(libxl__gc *gc, libxl__device *dev); _hidden int libxl__device_destroy(libxl__gc *gc, libxl__device *dev); _hidden int libxl__devices_destroy(libxl__gc *gc, uint32_t domid); _hidden int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state);
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 08 of 13 RFC] libxl: add better error checking on libxl__device_remove
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326728440 -3600 # Node ID 5849bf7c4507edbe900de00332f1218de2d9f45f # Parent 2a28a1126ab2fd6ab6b5c959daabdc6b3afd1fc6 libxl: add better error checking on libxl__device_remove Check return value of libxl__wait_for_device_state on libxl__device_remove and print an error message accordingly. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 2a28a1126ab2 -r 5849bf7c4507 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Mon Jan 16 16:40:26 2012 +0100 +++ b/tools/libxl/libxl_device.c Mon Jan 16 16:40:40 2012 +0100 @@ -511,8 +511,17 @@ retry_transaction: tv.tv_usec = 0; rc = libxl__wait_for_device_state(gc, &tv, XenbusStateClosed, destroy_device); - if (rc < 0) /* an error or timeout occurred, clear watches */ + if (rc == ERROR_TIMEDOUT) { + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Timeout while waiting for unplug of " + "device with backend path %s", be_path); xs_unwatch(ctx->xsh, state_path, be_path); + } else if (rc == ERROR_FAIL) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "failed to destroy device with " + "backend path %s", be_path); + xs_unwatch(ctx->xsh, state_path, be_path); + } xs_rm(ctx->xsh, XBT_NULL, libxl__device_frontend_path(gc, dev)); out:
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 09 of 13 RFC] libxl: destroy devices before device model
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326728472 -3600 # Node ID b5d63cf90d4ef8d222ae282e279b90b7f73f18c3 # Parent 5849bf7c4507edbe900de00332f1218de2d9f45f libxl: destroy devices before device model Destroying the device model before unplugging the devices prevented from doing a clean unplug, since libxl was waiting for dm devices to shutdown when the userspace process was already killed. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 5849bf7c4507 -r b5d63cf90d4e tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jan 16 16:40:40 2012 +0100 +++ b/tools/libxl/libxl.c Mon Jan 16 16:41:12 2012 +0100 @@ -802,15 +802,15 @@ int libxl_domain_destroy(libxl_ctx *ctx, if (rc < 0) { LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); } + if (libxl__devices_destroy(gc, domid) < 0) + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "libxl__devices_destroy failed for %d", domid); if (dm_present) { if (libxl__destroy_device_model(gc, domid) < 0) LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid); libxl__qmp_cleanup(gc, domid); } - if (libxl__devices_destroy(gc, domid) < 0) - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, - "libxl__devices_destroy failed for %d", domid); vm_path = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/vm", dom_path)); if (vm_path)
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 10 of 13 RFC] libxl: execute hotplug scripts directly from libxl
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1317386335 -7200 # Node ID 70359826f535461fedbbd86c18c772117030bc91 # Parent b5d63cf90d4ef8d222ae282e279b90b7f73f18c3 libxl: execute hotplug scripts directly from libxl. Added the necessary handlers to execute hotplug scripts when necessary from libxl. Split NetBSD and Linux hotplug calls into two separate files, because parameters for hotplug scripts are different. This patch adds the necessary functions to call hotplug scripts, but the implementation of those functions is left empty and will be filled in future patches. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r b5d63cf90d4e -r 70359826f535 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jan 16 16:41:12 2012 +0100 +++ b/tools/libxl/libxl.c Fri Sep 30 14:38:55 2011 +0200 @@ -1060,6 +1060,11 @@ int libxl_device_disk_add(libxl_ctx *ctx flexarray_append(back, "params"); flexarray_append(back, dev); + flexarray_append(back, "script"); + flexarray_append(back, libxl__sprintf(gc, "%s/%s", + libxl_xen_script_dir_path(), + "block")); + assert(device.backend_kind == LIBXL__DEVICE_KIND_VBD); break; case LIBXL_DISK_BACKEND_TAP: @@ -1072,6 +1077,10 @@ int libxl_device_disk_add(libxl_ctx *ctx flexarray_append(back, libxl__sprintf(gc, "%s:%s", libxl__device_disk_string_of_format(disk->format), disk->pdev_path)); + flexarray_append(back, "script"); + flexarray_append(back, libxl__sprintf(gc, "%s/%s", + libxl_xen_script_dir_path(), + "blktap")); /* now create a phy device to export the device to the guest */ goto do_backend_phy; @@ -1140,6 +1149,16 @@ int libxl_device_disk_add(libxl_ctx *ctx } } } + + /* Call hotplug scripts to attach device */ + if (libxl__device_hotplug(gc, &device, CONNECT) < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to execute hotplug script for disk: %s", + disk->pdev_path); + rc = -1; + goto out_free; + } + rc = 0; out_free: @@ -1608,6 +1627,16 @@ int libxl_device_nic_add(libxl_ctx *ctx, goto out_free; } } + + /* Call hotplug scripts to attach device */ + if (libxl__device_hotplug(gc, &device, CONNECT) < 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: diff -r b5d63cf90d4e -r 70359826f535 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Mon Jan 16 16:41:12 2012 +0100 +++ b/tools/libxl/libxl_device.c Fri Sep 30 14:38:55 2011 +0200 @@ -456,10 +456,16 @@ static int destroy_device(libxl__gc *gc, goto out; } + rc = libxl__device_hotplug(gc, &dev, DISCONNECT); + if (rc < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "failed to execute hotplug script for " + "device with backend path %s", l1[0]); + goto out; + } + libxl__device_cleanup(gc, &dev); - LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, - "Destroyed device backend at %s", - l1[XS_WATCH_TOKEN]); + rc = 0; out: return rc; @@ -488,6 +494,12 @@ retry_transaction: } if (atoi(state) != 4) { xs_transaction_end(ctx->xsh, t, 0); + rc = libxl__device_hotplug(gc, dev, DISCONNECT); + if (rc < 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "failed to execute hotplug script for " + "device with backend path %s", be_path); + } libxl__device_destroy_tapdisk(gc, be_path); libxl__device_cleanup(gc, dev); goto out; @@ -533,13 +545,16 @@ int libxl__device_destroy(libxl__gc *gc, libxl_ctx *ctx = libxl__gc_owner(gc); char *be_path = libxl__device_backend_path(gc, dev); char *fe_path = libxl__device_frontend_path(gc, dev); + int rc; + xs_rm(ctx->xsh, XBT_NULL, fe_path); + /* Wait for backend status to disconnect */ + rc = libxl__device_remove(gc, dev); libxl__device_cleanup(gc, dev); - xs_rm(ctx->xsh, XBT_NULL, fe_path); libxl__device_destroy_tapdisk(gc, be_path); - return 0; + return rc; } int libxl__devices_destroy(libxl__gc *gc, uint32_t domid) diff -r b5d63cf90d4e -r 70359826f535 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Mon Jan 16 16:41:12 2012 +0100 +++ b/tools/libxl/libxl_internal.h Fri Sep 30 14:38:55 2011 +0200 @@ -319,6 +319,25 @@ _hidden int libxl__device_cleanup(libxl_ */ _hidden int libxl__try_phy_backend(mode_t st_mode); +/* hotplug functions */ + +/* Action to pass to hotplug caller functions */ +typedef enum { + CONNECT = 1, + DISCONNECT = 2 +} libxl__hotplug_action; + +/* + * libxl__device_hotplug - generic function to execute hotplug scripts + * gc: allocation pool + * dev: reference to the device that executes the hotplug scripts + * action: action to execute + * + * Returns 0 on success, and < 0 on error. + */ +_hidden int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_action action); + /* from libxl_pci */ _hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting); diff -r b5d63cf90d4e -r 70359826f535 tools/libxl/libxl_linux.c --- a/tools/libxl/libxl_linux.c Mon Jan 16 16:41:12 2012 +0100 +++ b/tools/libxl/libxl_linux.c Fri Sep 30 14:38:55 2011 +0200 @@ -25,3 +25,11 @@ int libxl__try_phy_backend(mode_t st_mod return 1; } + +/* Hotplug scripts caller functions */ + +int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_action action) +{ + return 0; +} diff -r b5d63cf90d4e -r 70359826f535 tools/libxl/libxl_netbsd.c --- a/tools/libxl/libxl_netbsd.c Mon Jan 16 16:41:12 2012 +0100 +++ b/tools/libxl/libxl_netbsd.c Fri Sep 30 14:38:55 2011 +0200 @@ -14,6 +14,7 @@ */ #include <sys/stat.h> +#include <sys/wait.h> #include "libxl_internal.h" @@ -24,3 +25,11 @@ int libxl__try_phy_backend(mode_t st_mod return 0; } + +/* Hotplug scripts call function */ + +int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_action action) +{ + return 0; +}
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 11 of 13 RFC] libxl: add hotplug script calling for NetBSD
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326728652 -3600 # Node ID d0eb0f3a305fbcdb5fca853e7c674b9b59719e4a # Parent 70359826f535461fedbbd86c18c772117030bc91 libxl: add hotplug script calling for NetBSD Hotplug scripts in NetBSD are in charge of adding the virtual DomU network interface to the desired bridge and also mount the vnd device to use virtual images as block devices. The following scripts are currently implemented: * block: executed when a vbd is used, is in charge mounting the virtual image to the vnd device and setting the state of xenstore to 4 (connected). When using a physical partition, the script only sets the state to 4. * vif-bridge: adds the virtual DomU interface to the desired bridge. * vif-ip: configures the physical network interface assigned to the DomU. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 70359826f535 -r d0eb0f3a305f tools/libxl/libxl_netbsd.c --- a/tools/libxl/libxl_netbsd.c Fri Sep 30 14:38:55 2011 +0200 +++ b/tools/libxl/libxl_netbsd.c Mon Jan 16 16:44:12 2012 +0100 @@ -31,5 +31,50 @@ int libxl__try_phy_backend(mode_t st_mod int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev, libxl__hotplug_action action) { - return 0; + libxl_ctx *ctx = libxl__gc_owner(gc); + char *be_path = libxl__device_backend_path(gc, dev); + char *script, *what; + char **args; + int status, nr = 0; + int rc = -1; + flexarray_t *f_args; + + if (dev->backend_kind != LIBXL__DEVICE_KIND_VIF && + dev->backend_kind != LIBXL__DEVICE_KIND_VBD) + return 0; + + 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; + } + + 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++, libxl__sprintf(gc, "%d", action)); + flexarray_set(f_args, nr++, NULL); + + args = (char **) flexarray_contents(f_args); + + what = libxl__sprintf(gc, "%s %s", args[0], + action == CONNECT ? "connect" : "disconnect"); + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Calling hotplug script: %s %s %s", + args[0], args[1], args[2]); + status = libxl__forkexec(gc, -1, -1, -1, args[0], args, NULL, what); + if (status) { + rc = -1; + goto out; + } + rc = 0; + +out: + free(args); + return rc; }
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 12 of 13 RFC] libxl: add hotplug script calls for Linux
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1326729329 -3600 # Node ID 6e076ded8be36a90c6c1e0fb3172bc22011a80b6 # Parent d0eb0f3a305fbcdb5fca853e7c674b9b59719e4a libxl: add hotplug script calls for Linux This patchs adds the necessary logic to call hotplug scripts directly from libxl. Linux hotplug scritps read most parameters from the caller environment (since udev set this parameters automatically). In this implementation we fake udev parameters, so no changes are needed to the scripts itself. Currently, the following scripts are called: * block: used when disk backend is PHY. * blktap: used when disk backend is TAP. * vif-*: used when adding a network interface and can be manually set by the user. This patchs disables some udev rules, to prevent udev from trying to execute hotplug scripts for the devices listed above. udev rules descrive more device types, currently the following scripts are NOT executed from libxl because I wasn''t able to find any support for this device types in libxl: * vtpm * vif2 * vscsi * vif-setup with devices of type tap* Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r d0eb0f3a305f -r 6e076ded8be3 tools/hotplug/Linux/xen-backend.rules --- a/tools/hotplug/Linux/xen-backend.rules Mon Jan 16 16:44:12 2012 +0100 +++ b/tools/hotplug/Linux/xen-backend.rules Mon Jan 16 16:55:29 2012 +0100 @@ -1,11 +1,11 @@ -SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}" -SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}" +# SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}" +# SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}" -SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif" -SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif" +# SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif" +# SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif" SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}" -SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup" +# SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup" KERNEL=="evtchn", NAME="xen/%k" SUBSYSTEM=="xen", KERNEL=="blktap[0-9]*", NAME="xen/%k", MODE="0600" SUBSYSTEM=="blktap2", KERNEL=="blktap[0-9]*", NAME="xen/blktap-2/%k", MODE="0600" diff -r d0eb0f3a305f -r 6e076ded8be3 tools/libxl/libxl_linux.c --- a/tools/libxl/libxl_linux.c Mon Jan 16 16:44:12 2012 +0100 +++ b/tools/libxl/libxl_linux.c Mon Jan 16 16:55:29 2012 +0100 @@ -26,10 +26,172 @@ int libxl__try_phy_backend(mode_t st_mod return 1; } +/* Hotplug scripts helpers */ + +static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + char *be_path = libxl__device_backend_path(gc, dev); + flexarray_t *f_env; + int nr = 0; + + f_env = flexarray_make(11, 1); + if (!f_env) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to create environment array"); + return NULL; + } + + flexarray_set(f_env, nr++, "script"); + flexarray_set(f_env, nr++, libxl__xs_read(gc, XBT_NULL, + libxl__sprintf(gc, "%s/%s", + be_path, + "script"))); + flexarray_set(f_env, nr++, "XENBUS_TYPE"); + flexarray_set(f_env, nr++, (char *) + libxl__device_kind_to_string(dev->backend_kind)); + flexarray_set(f_env, nr++, "XENBUS_PATH"); + flexarray_set(f_env, nr++, + libxl__sprintf(gc, "backend/%s/%u/%d", + libxl__device_kind_to_string(dev->backend_kind), + dev->domid, dev->devid)); + flexarray_set(f_env, nr++, "XENBUS_BASE_PATH"); + flexarray_set(f_env, nr++, "backend"); + if (dev->backend_kind == LIBXL__DEVICE_KIND_VIF) { + flexarray_set(f_env, nr++, "vif"); + flexarray_set(f_env, nr++, + libxl__sprintf(gc, "%s%u.%d", + libxl__device_kind_to_string(dev->backend_kind), + dev->domid, dev->devid)); + } + flexarray_set(f_env, nr++, NULL); + + return (char **) flexarray_contents(f_env); +} + /* Hotplug scripts caller functions */ +static int libxl__hotplug_nic(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_action action) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + char *be_path = libxl__device_backend_path(gc, dev); + char *script, *what; + char **args, **env; + int status, nr = 0; + int rc = -1; + 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; + } + + env = get_hotplug_env(gc, dev); + if (!env) + return -1; + + f_args = flexarray_make(4, 1); + if (!f_args) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to create arguments array"); + return -1; + } + + flexarray_set(f_args, nr++, script); + flexarray_set(f_args, nr++, action == CONNECT ? "online" : "offline"); + flexarray_set(f_args, nr++, "type_if=vif"); + flexarray_set(f_args, nr++, NULL); + + args = (char **) flexarray_contents(f_args); + what = libxl__sprintf(gc, "%s %s", args[0], + action == CONNECT ? "connect" : "disconnect"); + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Calling hotplug script: %s %s %s", + args[0], args[1], args[2]); + status = libxl__forkexec(gc, -1, -1, -1, args[0], args, env, what); + if (status) { + rc = -1; + goto out; + } + rc = 0; + +out: + free(env); + free(args); + return rc; +} + +static int libxl__hotplug_disk(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_action action) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + char *be_path = libxl__device_backend_path(gc, dev); + char *script, *what; + char **args, **env; + int status, nr = 0; + int rc = -1; + 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; + } + + env = get_hotplug_env(gc, dev); + if (!env) + return -1; + + f_args = flexarray_make(3, 1); + if (!f_args) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to create arguments array"); + return -1; + } + + flexarray_set(f_args, nr++, script); + flexarray_set(f_args, nr++, action == CONNECT ? "add" : "remove"); + flexarray_set(f_args, nr++, NULL); + + args = (char **) flexarray_contents(f_args); + what = libxl__sprintf(gc, "%s %s", args[0], + action == CONNECT ? "connect" : "disconnect"); + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Calling hotplug script: %s %s", + args[0], args[1]); + status = libxl__forkexec(gc, -1, -1, -1, args[0], args, env, what); + if (status) { + rc = -1; + goto out; + } + rc = 0; + +out: + free(env); + free(args); + return rc; +} + int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev, - libxl__hotplug_action action) + libxl__hotplug_action action) { - return 0; + int rc = 0; + + switch (dev->backend_kind) { + case LIBXL__DEVICE_KIND_VIF: + rc = libxl__hotplug_nic(gc, dev, action); + break; + case LIBXL__DEVICE_KIND_VBD: + rc = libxl__hotplug_disk(gc, dev, action); + break; + default: + rc = 0; + break; + } + + return rc; }
Roger Pau Monne
2012-Jan-18 09:58 UTC
[PATCH 13 of 13 RFC] rc.d NetBSD: don''t start xenbackendd by default, only when xend needs it
# HG changeset patch # User Roger Pau Monne <roger.pau@entel.upc.edu> # Date 1317386335 -7200 # Node ID 4416c2b24b9568f860311cbdef44eb5c7f919855 # Parent 6e076ded8be36a90c6c1e0fb3172bc22011a80b6 rc.d NetBSD: don''t start xenbackendd by default, only when xend needs it. With the move of hotplug scripts from xenbackendd to libxl xenbackendd is no longer needed by libxl, only start it when xend is started. Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> diff -r 6e076ded8be3 -r 4416c2b24b95 tools/hotplug/NetBSD/rc.d/xenbackendd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/hotplug/NetBSD/rc.d/xenbackendd Fri Sep 30 14:38:55 2011 +0200 @@ -0,0 +1,27 @@ +#!/bin/sh +# +# PROVIDE: xenbackendd +# REQUIRE: xencommons + +. /etc/rc.subr + +DIR=$(dirname "$0") +. "${DIR}/xen-hotplugpath.sh" + +LD_LIBRARY_PATH="${LIBDIR}" +export LD_LIBRARY_PATH PYTHONPATH +PATH="${PATH}:${SBINDIR}" +export PATH + +name="xenbackendd" +rcvar=$name +command="${SBINDIR}/xenbackendd" +if [ -n "${XENBACKENDD_DEBUG}" ]; then + command_args="${XENBACKENDD_ARGS} -d" +else + command_args="${XENBACKENDD_ARGS}" +fi + +load_rc_config $name +run_rc_command "$1" + diff -r 6e076ded8be3 -r 4416c2b24b95 tools/hotplug/NetBSD/rc.d/xencommons --- a/tools/hotplug/NetBSD/rc.d/xencommons Mon Jan 16 16:55:29 2012 +0100 +++ b/tools/hotplug/NetBSD/rc.d/xencommons Fri Sep 30 14:38:55 2011 +0200 @@ -22,8 +22,6 @@ required_files="/kern/xen/privcmd" XENSTORED_PIDFILE="/var/run/xenstored.pid" XENCONSOLED_PIDFILE="/var/run/xenconsoled.pid" -XENBACKENDD_PIDFILE="/var/run/xenbackendd.pid" -#XENBACKENDD_DEBUG=1 #XENCONSOLED_TRACE="/var/log/xen/xenconsole-trace.log" #XENSTORED_TRACE="/var/log/xen/xenstore-trace.log" @@ -46,7 +44,7 @@ xen_startcmd() XENSTORED_ROOTDIR="/var/lib/xenstored" fi rm -f ${XENSTORED_ROOTDIR}/tdb* >/dev/null 2>&1 - printf "Starting xenservices: xenstored, xenconsoled, xenbackendd." + printf "Starting xenservices: xenstored, xenconsoled." XENSTORED_ARGS=" --pid-file ${XENSTORED_PIDFILE}" if [ -n "${XENSTORED_TRACE}" ]; then XENSTORED_ARGS="${XENSTORED_ARGS} -T /var/log/xen/xenstored-trace.log" @@ -58,7 +56,7 @@ xen_startcmd() sleep 1 done else - printf "Starting xenservices: xenconsoled, xenbackendd." + printf "Starting xenservices: xenconsoled." fi XENCONSOLED_ARGS="" @@ -68,13 +66,6 @@ xen_startcmd() ${SBINDIR}/xenconsoled ${XENCONSOLED_ARGS} - XENBACKENDD_ARGS="" - if [ -n "${XENBACKENDD_DEBUG}" ]; then - XENBACKENDD_ARGS="${XENBACKENDD_ARGS} -d" - fi - - ${SBINDIR}/xenbackendd ${XENBACKENDD_ARGS} - printf "\n" printf "Setting domain 0 name.\n" @@ -87,8 +78,6 @@ xen_stop() printf "Stopping xencommons.\n" printf "WARNING: Not stopping xenstored, as it cannot be restarted.\n" - rc_pid=$(check_pidfile ${XENBACKENDD_PIDFILE} ${SBINDIR}/xenbackendd) - pids="$pids $rc_pid" rc_pid=$(check_pidfile ${XENCONSOLED_PIDFILE} ${SBINDIR}/xenconsoled) pids="$pids $rc_pid" @@ -108,17 +97,12 @@ xen_status() pids="$pids $xenconsoled_pid" fi - xenbackend_pid=$(check_pidfile ${XENBACKENDD_PIDFILE} ${SBINDIR}/xenbackendd) - if test -n ${xenbackend_pid}; then - pids="$pids $xenbackend_pid" - fi - - if test -n "$xenbackend_pid" -a -n "$xenconsoled_pid" -a -n "$xenstored_pid"; + if test -n "$xenconsoled_pid" -a -n "$xenstored_pid"; then echo "xencommons are running as pids $pids." return 0 fi - if test -z "$xenbackend_pid" -a -z "$xenconsoled_pid" -a -z "$xenstored_pid"; + if test -z "$xenconsoled_pid" -a -z "$xenstored_pid"; then echo "xencommons are not running." return 0 @@ -134,11 +118,6 @@ xen_status() else echo "xenconsoled is not running." fi - if test -n $xenbackend_pid; then - echo "xenbackendd is running as pid $xenbackend_pid." - else - echo "xenbackendd is not running." - fi } load_rc_config $name diff -r 6e076ded8be3 -r 4416c2b24b95 tools/hotplug/NetBSD/rc.d/xend --- a/tools/hotplug/NetBSD/rc.d/xend Mon Jan 16 16:55:29 2012 +0100 +++ b/tools/hotplug/NetBSD/rc.d/xend Fri Sep 30 14:38:55 2011 +0200 @@ -1,7 +1,7 @@ #!/bin/sh # # PROVIDE: xend -# REQUIRE: xencommons +# REQUIRE: xencommons xenbackendd . /etc/rc.subr
Stefano Stabellini
2012-Jan-26 17:23 UTC
Re: [PATCH 09 of 13 RFC] libxl: destroy devices before device model
On Wed, 18 Jan 2012, Roger Pau Monne wrote:> # HG changeset patch > # User Roger Pau Monne <roger.pau@entel.upc.edu> > # Date 1326728472 -3600 > # Node ID b5d63cf90d4ef8d222ae282e279b90b7f73f18c3 > # Parent 5849bf7c4507edbe900de00332f1218de2d9f45f > libxl: destroy devices before device model > > Destroying the device model before unplugging the devices prevented > from doing a clean unplug, since libxl was waiting for dm devices > to shutdown when the userspace process was already killed.I think that this change is correct but have you tested it with any backends running in qemu?> Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> > > diff -r 5849bf7c4507 -r b5d63cf90d4e tools/libxl/libxl.c > --- a/tools/libxl/libxl.c Mon Jan 16 16:40:40 2012 +0100 > +++ b/tools/libxl/libxl.c Mon Jan 16 16:41:12 2012 +0100 > @@ -802,15 +802,15 @@ int libxl_domain_destroy(libxl_ctx *ctx, > if (rc < 0) { > LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); > } > + if (libxl__devices_destroy(gc, domid) < 0) > + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, > + "libxl__devices_destroy failed for %d", domid); > if (dm_present) { > if (libxl__destroy_device_model(gc, domid) < 0) > LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid); > > libxl__qmp_cleanup(gc, domid); > } > - if (libxl__devices_destroy(gc, domid) < 0) > - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, > - "libxl__devices_destroy failed for %d", domid); > > vm_path = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/vm", dom_path)); > if (vm_path) > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel >
Roger Pau Monné
2012-Jan-26 18:46 UTC
Re: [PATCH 09 of 13 RFC] libxl: destroy devices before device model
2012/1/26 Stefano Stabellini <stefano.stabellini@eu.citrix.com>:> On Wed, 18 Jan 2012, Roger Pau Monne wrote: >> # HG changeset patch >> # User Roger Pau Monne <roger.pau@entel.upc.edu> >> # Date 1326728472 -3600 >> # Node ID b5d63cf90d4ef8d222ae282e279b90b7f73f18c3 >> # Parent 5849bf7c4507edbe900de00332f1218de2d9f45f >> libxl: destroy devices before device model >> >> Destroying the device model before unplugging the devices prevented >> from doing a clean unplug, since libxl was waiting for dm devices >> to shutdown when the userspace process was already killed. > > I think that this change is correct but have you tested it with any > backends running in qemu?I've tried with qdisk and console backends with a PV DomU (I will try with a HVM guest too, tomorrow morning), anyway, this patch it's quite useless on it's own, it's the combination of this one and: qemu: react to XenbusStateClosing that makes qemu device model destruction successful (devices are disconnected before backend removal). BTW Xen Qemu code in qemu-xen is an indentation mess, I've tried to keep it as similar as possible.> >> Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> >> >> diff -r 5849bf7c4507 -r b5d63cf90d4e tools/libxl/libxl.c >> --- a/tools/libxl/libxl.c Mon Jan 16 16:40:40 2012 +0100 >> +++ b/tools/libxl/libxl.c Mon Jan 16 16:41:12 2012 +0100 >> @@ -802,15 +802,15 @@ int libxl_domain_destroy(libxl_ctx *ctx, >> if (rc < 0) { >> LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); >> } >> + if (libxl__devices_destroy(gc, domid) < 0) >> + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, >> + "libxl__devices_destroy failed for %d", domid); >> if (dm_present) { >> if (libxl__destroy_device_model(gc, domid) < 0) >> LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid); >> >> libxl__qmp_cleanup(gc, domid); >> } >> - if (libxl__devices_destroy(gc, domid) < 0) >> - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, >> - "libxl__devices_destroy failed for %d", domid); >> >> vm_path = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/vm", dom_path)); >> if (vm_path) >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel >> > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Roger Pau Monné
2012-Jan-27 10:21 UTC
Re: [PATCH 09 of 13 RFC] libxl: destroy devices before device model
2012/1/26 Stefano Stabellini <stefano.stabellini@eu.citrix.com>:> On Wed, 18 Jan 2012, Roger Pau Monne wrote: >> # HG changeset patch >> # User Roger Pau Monne <roger.pau@entel.upc.edu> >> # Date 1326728472 -3600 >> # Node ID b5d63cf90d4ef8d222ae282e279b90b7f73f18c3 >> # Parent 5849bf7c4507edbe900de00332f1218de2d9f45f >> libxl: destroy devices before device model >> >> Destroying the device model before unplugging the devices prevented >> from doing a clean unplug, since libxl was waiting for dm devices >> to shutdown when the userspace process was already killed. > > I think that this change is correct but have you tested it with any > backends running in qemu?Tested under NetBSD Dom0 with HVM DomU and with Debian Dom0 and PV DomU with qdisk and console backends. Sorry, but I'm unable to test on Debian with HVM, I don't have any Debian servers with virtualization extensions.>> Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu> >> >> diff -r 5849bf7c4507 -r b5d63cf90d4e tools/libxl/libxl.c >> --- a/tools/libxl/libxl.c Mon Jan 16 16:40:40 2012 +0100 >> +++ b/tools/libxl/libxl.c Mon Jan 16 16:41:12 2012 +0100 >> @@ -802,15 +802,15 @@ int libxl_domain_destroy(libxl_ctx *ctx, >> if (rc < 0) { >> LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); >> } >> + if (libxl__devices_destroy(gc, domid) < 0) >> + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, >> + "libxl__devices_destroy failed for %d", domid); >> if (dm_present) { >> if (libxl__destroy_device_model(gc, domid) < 0) >> LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid); >> >> libxl__qmp_cleanup(gc, domid); >> } >> - if (libxl__devices_destroy(gc, domid) < 0) >> - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, >> - "libxl__devices_destroy failed for %d", domid); >> >> vm_path = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/vm", dom_path)); >> if (vm_path) >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel >> > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel