[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 08/10] libxl: call hotplug scripts for disk devices from libxl
Roger Pau Monne writes ("[PATCH v4 08/10] libxl: call hotplug scripts for disk devices from libxl"): > Since most of the needed work is already done in previous patches, > this patch only contains the necessary code to call hotplug scripts > for disk devices, that should be called when the device is added or > removed from a guest. Thanks. > +static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev) > +{ ... > + /* Check if we have to execute hotplug scripts for this device > + * and return the necessary args/env vars for execution */ > + hotplug = libxl__get_hotplug_script_info(gc, aodev->dev, &args, &env, > + aodev->action); > + switch (hotplug) { ... > + default: > + /* everything else is an error */ > + LOG(ERROR, "unable to get args/env to execute hotplug script for " > + "device %s", libxl__device_backend_path(gc, aodev->dev)); > + rc = ERROR_FAIL; Again, `rc = hotplug' perhaps ? > + /* fork and execute hotplug script */ > + aodev->pid = libxl__ev_child_fork(gc, &aodev->child, > + device_hotplug_fork_cb); > + if (aodev->pid == -1) { > + LOG(ERROR, "unable to fork"); > + rc = ERROR_FAIL; > + goto out; > + } > + > + if (!aodev->pid) { > + /* child */ > + libxl__exec(gc, -1, -1, -1, args[0], args, env); > + /* notreached */ > + abort(); > + } > + > + if (!libxl__ev_child_inuse(&aodev->child)) { > + /* hotplug launch failed */ > + LOG(ERROR, "unable to launch hotplug script for device %s", be_path); > + rc = ERROR_FAIL; > + goto out; > + } This isn't right. After a successful libxl__ev_child_fork, the child structure is definitely in use. So an assert would be appropriate but really this last stanza can just be removed. > + return; > + > +out: > + libxl__ev_time_deregister(gc, &aodev->ev); > + aodev->rc = rc; > + aodev->callback(egc, aodev); > + return; > +} Shouldn't something set aodev->state to FINISHED in this error path ? It might be better to have a helper function to call when declaring the aodev finished. That helper function would also do the _ev_time_deregister, and assert !libxl__ev_child_inuse. > +static void device_hotplug_fork_cb(libxl__egc *egc, libxl__ev_child *child, > + pid_t pid, int status) This shouldn't be called `fork_cb'. It's a callback that happens when the child dies, not when it forks. I wouldn't call it `death_cb' or `child_cb' or something. > +static void device_hotplug_timeout_cb(libxl__egc *egc, libxl__ev_time *ev, > + const struct timeval *requested_abs) > +{ > + libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, ev); > + STATE_AO_GC(aodev->ao); > + > + if (libxl__ev_child_inuse(&aodev->child)) { > + if (kill(aodev->pid, SIGKILL)) { > + LOGEV(ERROR, errno, "unable to kill hotplug script %s [%ld]", > + aodev->what, (unsigned long)aodev->pid); > + goto out; > + } > + } > + > +out: > + libxl__ev_time_deregister(gc, &aodev->ev); > + return; You could profitably move that deregistration to the top of the function. That would save the goto. Also libxl__ev_child_inuse should always be true here, surely ? After all we shouldn't have a timeout running unless we also have the child. So yo should assert libxl__ev_child_inuse. > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index 45b776c..da5b02b 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h ... > + /* device hotplug execution */ > + pid_t pid; > + char *what; > + libxl__ev_time ev; > + libxl__ev_child child; Is the pid inside child not sufficient ? > diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c > index 925248b..98cd25f 100644 > --- a/tools/libxl/libxl_linux.c > +++ b/tools/libxl/libxl_linux.c > @@ -25,3 +25,101 @@ int libxl__try_phy_backend(mode_t st_mode) > > return 1; > } > + > +/* Hotplug scripts helpers */ > + > +static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev) > +{ ... > + int nr = 0, arraysize = 9; A nit, but here we see memetic leakage from the tyranny of -Wdeclaration-after-statement. Surely the definition of arraysize would be better placed: > + script = libxl__xs_read(gc, XBT_NULL, > + GCSPRINTF("%s/%s", be_path, "script")); > + if (!script) { > + LOGEV(ERROR, errno, "unable to read script from %s", be_path); > + return NULL; > + } > + Here: const int arraysize = 9; > + GCNEW_ARRAY(env, arraysize); > + env[nr++] = "script"; > + env[nr++] = script; > + env[nr++] = "XENBUS_TYPE"; > + env[nr++] = libxl__strdup(gc, type); > + env[nr++] = "XENBUS_PATH"; > + env[nr++] = GCSPRINTF("backend/%s/%u/%d", type, dev->domid, dev->devid); > + env[nr++] = "XENBUS_BASE_PATH"; > + env[nr++] = "backend"; > + env[nr++] = NULL; > + assert(nr == arraysize); > diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c > index 9e0ed6d..0f2cdaa 100644 > --- a/tools/libxl/libxl_netbsd.c > +++ b/tools/libxl/libxl_netbsd.c > @@ -24,3 +24,12 @@ int libxl__try_phy_backend(mode_t st_mode) > > return 0; > } > + > +/* Hotplug scripts caller functions */ > + > +int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev, > + char ***args, char ***env, > + libxl__device_action action) > +{ > + return 0; > +} > \ No newline at end of file That last complaint from diff should be fixed :-). Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |