libxl: add option to choose who executes hotplug scripts
authorRoger Pau Monne <roger.pau@citrix.com>
Thu, 26 Jul 2012 15:47:32 +0000 (16:47 +0100)
committerRoger Pau Monne <roger.pau@citrix.com>
Thu, 26 Jul 2012 15:47:32 +0000 (16:47 +0100)
Add and option to xl.conf file to decide if hotplug scripts are
executed from the toolstack (xl) or from udev as it used to be in the
past.

This option is only introduced in this patch, but it has no effect
since the code to call hotplug scripts from libxl is introduced in a
latter patch.

This choice will be saved in "libxl/disable_udev", as specified in the
DISABLE_UDEV_PATH constant.

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>
docs/man/xl.conf.pod.5
tools/examples/xl.conf
tools/libxl/libxl_create.c
tools/libxl/libxl_dm.c
tools/libxl/libxl_internal.c
tools/libxl/libxl_internal.h
tools/libxl/libxl_types.idl
tools/libxl/xl.c
tools/libxl/xl.h
tools/libxl/xl_cmdimpl.c

index 149430c61ed76ad46db4a68896a4e1e617d3bd57..23932bea63ad0fc74714640b6d405f8ee008ac42 100644 (file)
@@ -55,6 +55,14 @@ default.
 
 Default: C<1>
 
+=item B<run_hotplug_scripts=BOOLEAN>
+
+If disabled hotplug scripts will be called from udev, as it used to
+be in the previous releases. With the default option, hotplug scripts
+will be launched by xl directly.
+
+Default: C<1>
+
 =item B<lockfile="PATH">
 
 Sets the path to the lock file used by xl to serialise certain
index ebf057c37a71fdf9570096c0c3c2abb3ade06c7a..28ab796ea3dcf559ae5d67a985db47b1ebaa4722 100644 (file)
@@ -15,3 +15,8 @@
 
 # first block device to be used for temporary VM disk mounts
 #blkdev_start="xvda"
+
+# default option to run hotplug scripts from xl
+# if disabled the old behaviour will be used, and hotplug scripts will be
+# launched by udev.
+#run_hotplug_scripts=1
index 707e7dd7283a09df56bdfe85d3f33647f5780d70..b9dd547c6a09751bebb6c985275c718f525b01de 100644 (file)
@@ -70,6 +70,8 @@ int libxl__domain_create_info_setdefault(libxl__gc *gc,
         libxl_defbool_setdefault(&c_info->oos, true);
     }
 
+    libxl_defbool_setdefault(&c_info->run_hotplug_scripts, true);
+
     return 0;
 }
 
@@ -384,7 +386,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
                        uint32_t *domid)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    int flags, ret, rc;
+    int flags, ret, rc, nb_vm;
     char *uuid_string;
     char *dom_path, *vm_path, *libxl_path;
     struct xs_permissions roperm[2];
@@ -392,6 +394,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
     struct xs_permissions noperm[1];
     xs_transaction_t t = 0;
     xen_domain_handle_t handle;
+    libxl_vminfo *vm_list;
 
 
     assert(!libxl_domid_valid_guest(*domid));
@@ -505,6 +508,41 @@ retry_transaction:
             libxl__sprintf(gc, "%s/hvmloader/generation-id-address", dom_path),
                         rwperm, ARRAY_SIZE(rwperm));
 
+                    vm_list = libxl_list_vm(ctx, &nb_vm);
+    if (!vm_list) {
+        LOG(ERROR, "cannot get number of running guests");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    libxl_vminfo_list_free(vm_list, nb_vm);
+    int hotplug_setting = libxl__hotplug_settings(gc, t);
+    if (hotplug_setting < 0) {
+        LOG(ERROR, "unable to get current hotplug scripts execution setting");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    if (libxl_defbool_val(info->run_hotplug_scripts) != hotplug_setting &&
+        (nb_vm - 1)) {
+        LOG(ERROR, "cannot change hotplug execution option once set, "
+                    "please shutdown all guests before changing it");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    if (libxl_defbool_val(info->run_hotplug_scripts)) {
+        rc = libxl__xs_write_checked(gc, t, DISABLE_UDEV_PATH, "1");
+        if (rc) {
+            LOGE(ERROR, "unable to write %s = 1", DISABLE_UDEV_PATH);
+            goto out;
+        }
+    } else {
+        rc = libxl__xs_rm_checked(gc, t, DISABLE_UDEV_PATH);
+        if (rc) {
+            LOGE(ERROR, "unable to delete %s", DISABLE_UDEV_PATH);
+            goto out;
+        }
+    }
+
     xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
     xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name));
 
index 1b17ef516fc04aa545197e1ea8718a2946fd8896..dec7c1966113e730a9c0b375a6b07c157f86c72e 100644 (file)
@@ -785,6 +785,9 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
 
     libxl__dm_vifs_from_hvm_guest_config(gc, guest_config, dm_config);
 
+    dm_config->c_info.run_hotplug_scripts =
+        guest_config->c_info.run_hotplug_scripts;
+
     ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info);
     if (ret) goto out;
     ret = libxl__domain_build_info_setdefault(gc, &dm_config->b_info);
index 24099f59f6f0f2a15308a3ef5c74f3a1f3dbf77f..211c8f5e2f26d0eaab2a2f5e6aee90fbd8a2415a 100644 (file)
@@ -352,6 +352,25 @@ int libxl__device_model_version_running(libxl__gc *gc, uint32_t domid)
     return value;
 }
 
+int libxl__hotplug_settings(libxl__gc *gc, xs_transaction_t t)
+{
+    int rc = 0;
+    char *val;
+
+    val = libxl__xs_read(gc, t, DISABLE_UDEV_PATH);
+    if (!val && errno != ENOENT) {
+        LOGE(ERROR, "cannot read %s from xenstore", DISABLE_UDEV_PATH);
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    if (!val) val = "0";
+
+    rc = !!atoi(val);
+
+out:
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
index e89f37c29676691f2201618fa6949a46d0a57efc..1ac681db55507a6f563b11bc62c8ea5bfb22f666 100644 (file)
@@ -91,6 +91,7 @@
 #define STUBDOM_CONSOLE_SERIAL 3
 #define STUBDOM_SPECIAL_CONSOLES 3
 #define TAP_DEVICE_SUFFIX "-emu"
+#define DISABLE_UDEV_PATH "libxl/disable_udev"
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
@@ -1510,6 +1511,8 @@ _hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s);
    * default is qemu xen traditional */
 _hidden int libxl__device_model_version_running(libxl__gc *gc, uint32_t domid);
 
+/* Check how executes hotplug script currently */
+int libxl__hotplug_settings(libxl__gc *gc, xs_transaction_t t);
 
 /*
  * Calling context and GC for event-generating functions:
index c1815c6c002245781e54e222f6a308679ae2784d..daa8c790ed527d61cdd6aa2fc6e5d104f4307650 100644 (file)
@@ -231,6 +231,7 @@ libxl_domain_create_info = Struct("domain_create_info",[
     ("xsdata",       libxl_key_value_list),
     ("platformdata", libxl_key_value_list),
     ("poolid",       uint32),
+    ("run_hotplug_scripts",libxl_defbool),
     ], dir=DIR_IN)
 
 MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT")
index d6f2b3ead2590d3f5f2fa8995a565a67c34a56b3..f31e836e870822bf34caf0bfe7778302734e7baf 100644 (file)
@@ -39,6 +39,7 @@ int dryrun_only;
 int force_execution;
 int autoballoon = 1;
 char *blkdev_start;
+int run_hotplug_scripts = 1;
 char *lockfile;
 char *default_vifscript = NULL;
 char *default_bridge = NULL;
@@ -70,6 +71,9 @@ static void parse_global_config(const char *configfile,
     if (!xlu_cfg_get_long (config, "autoballoon", &l, 0))
         autoballoon = l;
 
+    if (!xlu_cfg_get_long (config, "run_hotplug_scripts", &l, 0))
+        run_hotplug_scripts = l;
+
     if (!xlu_cfg_get_string (config, "lockfile", &buf, 0))
         lockfile = strdup(buf);
     else {
index b0ba357d3ca417ccc49564fbfae3bdeb42b2657a..0b2f848f90ba1da95d44509600010d01f17781fc 100644 (file)
@@ -140,6 +140,7 @@ int xl_child_pid(xlchildnum); /* returns 0 if child struct is not in use */
 
 /* global options */
 extern int autoballoon;
+extern int run_hotplug_scripts;
 extern int dryrun_only;
 extern char *lockfile;
 extern char *default_vifscript;
index 72892f3dfdccf20c7ba51339486a0a6b8eb9439a..a7dc3403d1931c5209be3c0291c742de026e28ec 100644 (file)
@@ -595,6 +595,7 @@ static void parse_config_data(const char *config_source,
         }
     }
 
+    libxl_defbool_set(&c_info->run_hotplug_scripts, run_hotplug_scripts);
     c_info->type = LIBXL_DOMAIN_TYPE_PV;
     if (!xlu_cfg_get_string (config, "builder", &buf, 0) &&
         !strncmp(buf, "hvm", strlen(buf)))