From: Roger Pau Monne <roger.pau@citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>,
Roger Pau Monne <roger.pau@citrix.com>
Subject: [PATCH v11 13/17] libxl: call hotplug scripts for nic devices from libxl
Date: Mon, 23 Jul 2012 18:27:41 +0100 [thread overview]
Message-ID: <1343064465-17864-14-git-send-email-roger.pau@citrix.com> (raw)
In-Reply-To: <1343064465-17864-1-git-send-email-roger.pau@citrix.com>
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.
Changes since v10:
* Removed strdups.
* Added comment on VIF_IOEMU fall through for get_hotplug_env.
* Don't execute tap hotplug scripts if domain has a studbom.
Changes since v8:
* Correctly detect errors from hotplug execution and cancel domain
creation if an error is found.
Changes since v6:
* Added an rc = 0 before exitting libxl__nic_type if successful.
Changes since v4:
* Add num_exec to NetBSD dummy function.
* Better comment in the prototype of libxl__get_hotplug_script_info.
* Remove nasty use of goto.
* Keep calling device_hotplug until libxl__get_hotplug_script_info
returns <= 0. This is used by TAP nics which also have a VIF
interface (PV_IOEMU).
Changes since v2:
* Change libxl__nic_type to return the value in a parameter passed by
the caller.
* Rename vif_execute to num_exec, to represent the number of times
hotplug scripts have been called for that device.
Changes since v1:
* Move event code to libxl_device.c (as in previous patch).
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Jackson<ian.jackson@eu.citrix.com>
Signed-off-by: Roger Pau Monne <roger.pau@citrix.com>
---
tools/hotplug/Linux/xen-backend.rules | 6 +-
tools/libxl/libxl_device.c | 60 +++++++++++++++++-
tools/libxl/libxl_internal.h | 14 ++++-
tools/libxl/libxl_linux.c | 108 +++++++++++++++++++++++++++++++-
tools/libxl/libxl_netbsd.c | 3 +-
5 files changed, 178 insertions(+), 13 deletions(-)
diff --git a/tools/hotplug/Linux/xen-backend.rules b/tools/hotplug/Linux/xen-backend.rules
index d55ff11..c591a3f 100644
--- a/tools/hotplug/Linux/xen-backend.rules
+++ b/tools/hotplug/Linux/xen-backend.rules
@@ -2,8 +2,8 @@ SUBSYSTEM=="xen-backend", KERNEL=="tap*", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scr
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ENV{UDEV_CALL}="1", 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-*", ENV{UDEV_CALL}="1", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ENV{UDEV_CALL}="1", 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", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
KERNEL=="evtchn", NAME="xen/%k"
@@ -13,4 +13,4 @@ KERNEL=="blktap-control", NAME="xen/blktap-2/control", MODE="0600"
KERNEL=="gntdev", NAME="xen/%k", MODE="0600"
KERNEL=="pci_iomul", NAME="xen/%k", MODE="0600"
KERNEL=="tapdev[a-z]*", NAME="xen/blktap-2/tapdev%m", MODE="0600"
-SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
+SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 2b0186e..cd51677 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -100,6 +100,31 @@ out:
return numdevs;
}
+int libxl__nic_type(libxl__gc *gc, libxl__device *dev, libxl_nic_type *nictype)
+{
+ char *snictype, *be_path;
+ int rc = 0;
+
+ be_path = libxl__device_backend_path(gc, dev);
+ snictype = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/%s", be_path, "type"));
+ if (!snictype) {
+ LOGE(ERROR, "unable to read nictype from %s", be_path);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ rc = libxl_nic_type_from_string(snictype, nictype);
+ if (rc) {
+ LOGE(ERROR, "unable to parse nictype from %s", be_path);
+ goto out;
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,
libxl__device *device, char **bents, char **fents)
{
@@ -628,6 +653,8 @@ static void device_hotplug_child_death_cb(libxl__egc *egc,
static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev);
+static void device_hotplug_clean(libxl__gc *gc, libxl__ao_device *aodev);
+
void libxl__wait_device_connection(libxl__egc *egc, libxl__ao_device *aodev)
{
STATE_AO_GC(aodev->ao);
@@ -842,7 +869,8 @@ 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);
+ aodev->action,
+ aodev->num_exec);
switch (hotplug) {
case 0:
/* no hotplug script to execute */
@@ -922,6 +950,8 @@ static void device_hotplug_child_death_cb(libxl__egc *egc,
char *be_path = libxl__device_backend_path(gc, aodev->dev);
char *hotplug_error;
+ device_hotplug_clean(gc, aodev);
+
if (status) {
libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR,
aodev->what, pid, status);
@@ -930,8 +960,25 @@ static void device_hotplug_child_death_cb(libxl__egc *egc,
if (hotplug_error)
LOG(ERROR, "script: %s", hotplug_error);
aodev->rc = ERROR_FAIL;
+ if (aodev->action == DEVICE_CONNECT)
+ /*
+ * Only fail on device connection, on disconnection
+ * ignore error, and continue with the remove process
+ */
+ goto error;
}
+ /* Increase num_exec and call hotplug scripts again if necessary
+ * If no more executions are needed, device_hotplug will call
+ * device_hotplug_done breaking the loop.
+ */
+ aodev->num_exec++;
+ device_hotplug(egc, aodev);
+
+ return;
+
+error:
+ assert(aodev->rc);
device_hotplug_done(egc, aodev);
}
@@ -943,9 +990,7 @@ static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev)
xs_transaction_t t = 0;
int rc;
- /* Clean events and check reentrancy */
- libxl__ev_time_deregister(gc, &aodev->timeout);
- assert(!libxl__ev_child_inuse(&aodev->child));
+ device_hotplug_clean(gc, aodev);
/* Clean xenstore if it's a disconnection */
if (aodev->action == DEVICE_DISCONNECT) {
@@ -967,6 +1012,13 @@ out:
return;
}
+static void device_hotplug_clean(libxl__gc *gc, libxl__ao_device *aodev)
+{
+ /* Clean events and check reentrancy */
+ libxl__ev_time_deregister(gc, &aodev->timeout);
+ assert(!libxl__ev_child_inuse(&aodev->child));
+}
+
static void devices_remove_callback(libxl__egc *egc, libxl__ao_devices *aodevs,
int rc)
{
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 8d701ef..be6ca49 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -879,6 +879,8 @@ _hidden int libxl__parse_backend_path(libxl__gc *gc, const char *path,
libxl__device *dev);
_hidden int libxl__device_destroy(libxl__gc *gc, libxl__device *dev);
_hidden int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state);
+_hidden int libxl__nic_type(libxl__gc *gc, libxl__device *dev,
+ libxl_nic_type *nictype);
/*
* For each aggregate type which can be used as an input we provide:
@@ -1800,6 +1802,7 @@ struct libxl__ao_device {
libxl__ao_devices *aodevs;
/* device hotplug execution */
const char *what;
+ int num_exec;
libxl__ev_child child;
};
@@ -1939,10 +1942,19 @@ _hidden void libxl__initiate_device_remove(libxl__egc *egc,
* < 0: Error
* 0: No need to execute hotplug script
* 1: Execute hotplug script
+ *
+ * The last parameter, "num_exec" refeers to the number of times hotplug
+ * scripts have been called for this device.
+ *
+ * The main body of libxl will, for each device, keep calling
+ * libxl__get_hotplug_script_info, with incrementing values of
+ * num_exec, and executing the resulting script accordingly,
+ * until libxl__get_hotplug_script_info returns<=0.
*/
_hidden 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);
/*----- local disk attach: attach a disk locally to run the bootloader -----*/
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index 97b3fd4..9ae0b4b 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;
diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c
index a2f8d3f..28cdf21 100644
--- a/tools/libxl/libxl_netbsd.c
+++ b/tools/libxl/libxl_netbsd.c
@@ -34,7 +34,8 @@ char *libxl__devid_to_localdev(libxl__gc *gc, int devid)
/* Hotplug scripts caller functions */
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)
{
return 0;
}
--
1.7.7.5 (Apple Git-26)
next prev parent reply other threads:[~2012-07-23 17:27 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-23 17:27 [PATCH v11 0/17] execute hotplug scripts from libxl Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 01/17] libxl: fix stubdom console destruction Roger Pau Monne
2012-07-24 7:50 ` Ian Campbell
2012-07-24 8:39 ` Roger Pau Monne
2012-07-24 10:16 ` Stefano Stabellini
2012-07-24 10:54 ` Roger Pau Monne
2012-07-24 10:57 ` Ian Campbell
2012-07-24 11:01 ` Roger Pau Monne
2012-07-24 11:58 ` Stefano Stabellini
2012-07-24 12:14 ` Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 02/17] libxl: refactor disk addition to take a helper Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 03/17] libxl: convert libxl__device_disk_local_attach to an async op Roger Pau Monne
2012-07-24 15:19 ` Ian Jackson
2012-07-24 16:09 ` Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 04/17] libxl: rename vifs to nics Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 05/17] libxl: convert libxl_device_disk_add to an async op Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 06/17] libxl: convert libxl_device_nic_add to an async operation Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 07/17] libxl: add option to choose who executes hotplug scripts Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 08/17] libxl: rename _IOEMU nic type to VIF_IOEMU Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 09/17] libxl: set nic type of stub to PV instead of copying from the parent Roger Pau Monne
2012-07-24 15:27 ` Ian Jackson
2012-07-24 15:32 ` Ian Campbell
2012-07-24 16:05 ` Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 10/17] libxl: set correct nic type depending on the guest Roger Pau Monne
2012-07-24 15:28 ` Ian Jackson
2012-07-24 16:02 ` Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 11/17] libxl: use libxl__xs_path_cleanup on device_destroy Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 12/17] libxl: call hotplug scripts for disk devices from libxl Roger Pau Monne
2012-07-23 17:27 ` Roger Pau Monne [this message]
2012-07-23 17:27 ` [PATCH v11 14/17] libxl: convert libxl_device_vkb_add to an async operation Roger Pau Monne
2012-07-23 17:27 ` [PATCH v11 15/17] libxl: convert libxl_device_vfb_add " Roger Pau Monne
2012-07-24 15:20 ` Ian Jackson
2012-07-25 11:00 ` Roger Pau Monne
2012-07-26 14:26 ` Ian Jackson
2012-07-23 17:27 ` [PATCH v11 16/17] xl: main_blockdetach don't call destroy if remove succeeds Roger Pau Monne
2012-07-24 15:29 ` Ian Jackson
2012-07-23 17:27 ` [PATCH v11 17/17] libxl: libxl__xs_path_cleanup don't print error if ENOENT Roger Pau Monne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343064465-17864-14-git-send-email-roger.pau@citrix.com \
--to=roger.pau@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).