aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_linux.c
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@citrix.com>2012-07-26 16:47:34 +0100
committerRoger Pau Monne <roger.pau@citrix.com>2012-07-26 16:47:34 +0100
commitb24dc64ef34437c958b40a71f510f404e0c4bbe4 (patch)
tree45d6b1f9269c422f0618918c64f4ba41752ddb7b /tools/libxl/libxl_linux.c
parent24bc7a06aea0dd3cb3c9e0ba6c0367d54fdd503e (diff)
downloadxen-b24dc64ef34437c958b40a71f510f404e0c4bbe4.tar.gz
xen-b24dc64ef34437c958b40a71f510f404e0c4bbe4.tar.bz2
xen-b24dc64ef34437c958b40a71f510f404e0c4bbe4.zip
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. We will chain the launch of the disk hotplug scripts after the device_backend_callback callback, or directly from libxl__initiate_device_{add,remove} if the device is already in the desired state. 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.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index 0169b2ff0b..97b3fd4a64 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -77,3 +77,100 @@ char *libxl__devid_to_localdev(libxl__gc *gc, int devid)
"%d", minor & (nr_parts - 1));
return ret;
}
+
+/* Hotplug scripts helpers */
+
+static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev)
+{
+ char *be_path = libxl__device_backend_path(gc, dev);
+ char *script;
+ const char *type = libxl__device_kind_to_string(dev->backend_kind);
+ char **env;
+ int nr = 0;
+
+ 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;
+ }
+
+ 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);
+
+ return env;
+}
+
+/* Hotplug scripts caller functions */
+
+static int libxl__hotplug_disk(libxl__gc *gc, libxl__device *dev,
+ char ***args, char ***env,
+ libxl__device_action action)
+{
+ char *be_path = libxl__device_backend_path(gc, dev);
+ char *script;
+ int nr = 0, rc = 0;
+
+ 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);
+ rc = ERROR_FAIL;
+ goto error;
+ }
+
+ *env = get_hotplug_env(gc, dev);
+ if (!*env) {
+ rc = ERROR_FAIL;
+ goto error;
+ }
+
+ const int arraysize = 3;
+ GCNEW_ARRAY(*args, arraysize);
+ (*args)[nr++] = script;
+ (*args)[nr++] = action == DEVICE_CONNECT ? "add" : "remove";
+ (*args)[nr++] = NULL;
+ assert(nr == arraysize);
+
+ rc = 1;
+
+error:
+ return rc;
+}
+
+int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,
+ char ***args, char ***env,
+ libxl__device_action action)
+{
+ char *disable_udev = libxl__xs_read(gc, XBT_NULL, DISABLE_UDEV_PATH);
+ int rc;
+
+ /* Check if we have to run hotplug scripts */
+ if (!disable_udev) {
+ rc = 0;
+ goto out;
+ }
+
+ switch (dev->backend_kind) {
+ case LIBXL__DEVICE_KIND_VBD:
+ rc = libxl__hotplug_disk(gc, dev, args, env, action);
+ break;
+ default:
+ /* No need to execute any hotplug scripts */
+ rc = 0;
+ break;
+ }
+
+out:
+ return rc;
+}