diff options
author | Roger Pau Monne <roger.pau@citrix.com> | 2012-07-26 16:47:35 +0100 |
---|---|---|
committer | Roger Pau Monne <roger.pau@citrix.com> | 2012-07-26 16:47:35 +0100 |
commit | 57ad6afe2a08a03c40bcd336bfb27e008e1d3e53 (patch) | |
tree | 5458836e1fff4d42ab9cdc3bebb9d9225a6247f3 /tools/libxl/libxl_linux.c | |
parent | b24dc64ef34437c958b40a71f510f404e0c4bbe4 (diff) | |
download | xen-57ad6afe2a08a03c40bcd336bfb27e008e1d3e53.tar.gz xen-57ad6afe2a08a03c40bcd336bfb27e008e1d3e53.tar.bz2 xen-57ad6afe2a08a03c40bcd336bfb27e008e1d3e53.zip |
libxl: call hotplug scripts for nic 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 nic devices, that should be called when the device is added or
removed from a guest.
Added another parameter to libxl__get_hotplug_script_info, that is
used to know the number of times hotplug scripts have been called for
that device. This is currently used by IOEMU nics on Linux.
Signed-off-by: Roger Pau Monne <roger.pau@citrix.com>
Acked-by: Ian Jackson<ian.jackson@eu.citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxl/libxl_linux.c')
-rw-r--r-- | tools/libxl/libxl_linux.c | 108 |
1 files changed, 104 insertions, 4 deletions
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c index 97b3fd4a64..9ae0b4b88f 100644 --- a/tools/libxl/libxl_linux.c +++ b/tools/libxl/libxl_linux.c @@ -87,6 +87,7 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev) const char *type = libxl__device_kind_to_string(dev->backend_kind); char **env; int nr = 0; + libxl_nic_type nictype; script = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s", be_path, "script")); @@ -95,24 +96,106 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev) return NULL; } - const int arraysize = 9; + const int arraysize = 13; GCNEW_ARRAY(env, arraysize); env[nr++] = "script"; env[nr++] = script; env[nr++] = "XENBUS_TYPE"; - env[nr++] = libxl__strdup(gc, type); + env[nr++] = (char *) 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"; + if (dev->backend_kind == LIBXL__DEVICE_KIND_VIF) { + if (libxl__nic_type(gc, dev, &nictype)) { + LOG(ERROR, "unable to get nictype"); + return NULL; + } + switch (nictype) { + case LIBXL_NIC_TYPE_VIF_IOEMU: + env[nr++] = "INTERFACE"; + env[nr++] = (char *) libxl__device_nic_devname(gc, dev->domid, + dev->devid, + LIBXL_NIC_TYPE_VIF_IOEMU); + /* + * We need to fall through because for PV_IOEMU nic types we need + * to execute both the vif and the tap hotplug script, and we + * don't know which one we are executing in this call, so provide + * both env variables. + */ + case LIBXL_NIC_TYPE_VIF: + env[nr++] = "vif"; + env[nr++] = (char *) libxl__device_nic_devname(gc, dev->domid, + dev->devid, + LIBXL_NIC_TYPE_VIF); + break; + default: + return NULL; + } + } + env[nr++] = NULL; - assert(nr == arraysize); + assert(nr <= arraysize); return env; } /* Hotplug scripts caller functions */ +static int libxl__hotplug_nic(libxl__gc *gc, libxl__device *dev, + char ***args, char ***env, + libxl__device_action action, int num_exec) +{ + char *be_path = libxl__device_backend_path(gc, dev); + char *script; + int nr = 0, rc = 0; + libxl_nic_type nictype; + + script = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s", be_path, + "script")); + if (!script) { + LOGE(ERROR, "unable to read script from %s", be_path); + rc = ERROR_FAIL; + goto out; + } + + rc = libxl__nic_type(gc, dev, &nictype); + if (rc) { + LOG(ERROR, "error when fetching nic type"); + rc = ERROR_FAIL; + goto out; + } + if (nictype == LIBXL_NIC_TYPE_VIF && num_exec != 0) { + rc = 0; + goto out; + } + + *env = get_hotplug_env(gc, dev); + if (!env) { + rc = ERROR_FAIL; + goto out; + } + + const int arraysize = 4; + GCNEW_ARRAY(*args, arraysize); + (*args)[nr++] = script; + + if (nictype == LIBXL_NIC_TYPE_VIF_IOEMU && num_exec) { + (*args)[nr++] = action == DEVICE_CONNECT ? "add" : "remove"; + (*args)[nr++] = "type_if=tap"; + (*args)[nr++] = NULL; + } else { + (*args)[nr++] = action == DEVICE_CONNECT ? "online" : "offline"; + (*args)[nr++] = "type_if=vif"; + (*args)[nr++] = NULL; + } + assert(nr == arraysize); + rc = 1; + +out: + return rc; +} + static int libxl__hotplug_disk(libxl__gc *gc, libxl__device *dev, char ***args, char ***env, libxl__device_action action) @@ -150,7 +233,8 @@ error: int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev, char ***args, char ***env, - libxl__device_action action) + libxl__device_action action, + int num_exec) { char *disable_udev = libxl__xs_read(gc, XBT_NULL, DISABLE_UDEV_PATH); int rc; @@ -163,8 +247,24 @@ int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev, switch (dev->backend_kind) { case LIBXL__DEVICE_KIND_VBD: + if (num_exec != 0) { + rc = 0; + goto out; + } rc = libxl__hotplug_disk(gc, dev, args, env, action); break; + case LIBXL__DEVICE_KIND_VIF: + /* + * If domain has a stubdom we don't have to execute hotplug scripts + * for emulated interfaces + */ + if ((num_exec > 1) || + (libxl_get_stubdom_id(CTX, dev->domid) && num_exec)) { + rc = 0; + goto out; + } + rc = libxl__hotplug_nic(gc, dev, args, env, action, num_exec); + break; default: /* No need to execute any hotplug scripts */ rc = 0; |