diff mbox

[6/8] libxl: Allow local access for block devices with hotplug scripts

Message ID 1458144557-29070-7-git-send-email-george.dunlap@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

George Dunlap March 16, 2016, 4:09 p.m. UTC
From: George Dunlap <george.dunlap@eu.citrix.com>

pygrub and qemuu need to be able to access a VM's disks locally in
order to be able to pull out the kernel and provide emulated disk
access, respectively.  This can be done either by accessing the local
disk directly, or by plugging the target disk into dom0 to allow
access.

Unfortunately, while the plugging machinery works for pygrub, it does
not yet work for qemuu; meaning that disk hotplug scripts cannot be
used with HVM domains.

Fortunately, disks using hotplug scripts created in dom0 do create a
block device as part of set-up, which can be accessed locally; and if
they use block-common.sh:write_dev, this path will bre written to
physical-device-path.

Modify libxl__device_disk_setdefault() to be able to fish this path
out of xenstore and pass it back.

We need the target domid to find the appropriate xenstore node, so add
that to libxl__disk_local_state.

Unfortunately, at the time pygrub runs, the devices have not yet been
set up.  Rather than try to stash the domid somewhere to pass, we just
pass -1.

This allows qemuu to boot with block devices created with hotplug
scripts.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
---
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monne <roger.pau@citrix.com>
---
 tools/libxl/libxl.c          | 38 +++++++++++++++++++++++++++++++++++---
 tools/libxl/libxl_dm.c       |  3 +--
 tools/libxl/libxl_internal.h |  3 ++-
 3 files changed, 38 insertions(+), 6 deletions(-)

Comments

Ian Jackson March 17, 2016, 6:36 p.m. UTC | #1
George Dunlap writes ("[PATCH 6/8] libxl: Allow local access for block devices with hotplug scripts"):
> pygrub and qemuu need to be able to access a VM's disks locally in
> order to be able to pull out the kernel and provide emulated disk
> access, respectively.  This can be done either by accessing the local
> disk directly, or by plugging the target disk into dom0 to allow
> access.

Some long lines, `if(', etc., in this patch, I'm afraid.

> Unfortunately, while the plugging machinery works for pygrub, it does
> not yet work for qemuu; meaning that disk hotplug scripts cannot be
> used with HVM domains.
> 
> Fortunately, disks using hotplug scripts created in dom0 do create a
> block device as part of set-up, which can be accessed locally; and if
> they use block-common.sh:write_dev, this path will bre written to
> physical-device-path.
> 
> Modify libxl__device_disk_setdefault() to be able to fish this path
> out of xenstore and pass it back.
> 
> We need the target domid to find the appropriate xenstore node, so add
> that to libxl__disk_local_state.

I couldn't find that change in this patch.

> +    /* 
> +     * If the format isn't raw and / or we're using a script, then see
> +     * if the script has written a path to the "cooked" node
> +     */
> +    if(disk->script && domid != INVALID_DOMID) {
> +        libxl__device device;
> +        char *be_path, *pdpath;
> +        int rc;

I don't see where you check that the disk is not being provided by a
driver domain - in which case the hotplug script ran in the driver
domain and the device path is also only in the driver domain.

(By `driver domain' I mean, really, a domain other than this one.)

>  _hidden char * libxl__device_disk_find_local_path(libxl__gc *gc, 
> +                                                  libxl_domid domid,

This new parameter would maybe be a little less confusing if it were
explicitly `guest_domid'; after all it might be the driver domain
domid.

Thanks,
Ian.
George Dunlap March 18, 2016, 5:17 p.m. UTC | #2
On Thu, Mar 17, 2016 at 6:36 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote:
> George Dunlap writes ("[PATCH 6/8] libxl: Allow local access for block devices with hotplug scripts"):
>> pygrub and qemuu need to be able to access a VM's disks locally in
>> order to be able to pull out the kernel and provide emulated disk
>> access, respectively.  This can be done either by accessing the local
>> disk directly, or by plugging the target disk into dom0 to allow
>> access.
>
> Some long lines, `if(', etc., in this patch, I'm afraid.
>
>> Unfortunately, while the plugging machinery works for pygrub, it does
>> not yet work for qemuu; meaning that disk hotplug scripts cannot be
>> used with HVM domains.
>>
>> Fortunately, disks using hotplug scripts created in dom0 do create a
>> block device as part of set-up, which can be accessed locally; and if
>> they use block-common.sh:write_dev, this path will bre written to
>> physical-device-path.
>>
>> Modify libxl__device_disk_setdefault() to be able to fish this path
>> out of xenstore and pass it back.
>>
>> We need the target domid to find the appropriate xenstore node, so add
>> that to libxl__disk_local_state.
>
> I couldn't find that change in this patch.

Oops -- forgot to take this paragraph out after porting it on top of
patch 2 (which changes libxl not to duplicate the work of 'block'
anymore).  I'll remove this.

>
>> +    /*
>> +     * If the format isn't raw and / or we're using a script, then see
>> +     * if the script has written a path to the "cooked" node
>> +     */
>> +    if(disk->script && domid != INVALID_DOMID) {
>> +        libxl__device device;
>> +        char *be_path, *pdpath;
>> +        int rc;
>
> I don't see where you check that the disk is not being provided by a
> driver domain - in which case the hotplug script ran in the driver
> domain and the device path is also only in the driver domain.
>
> (By `driver domain' I mean, really, a domain other than this one.)

It's in patch 4 (still at the top of this function):

+    /* No local paths for driver domains */
+    if (disk->backend_domname != NULL) {
+        LOG(DEBUG, "Non-local backend, can't access locally.\n");
+        goto out;
+    }

>
>>  _hidden char * libxl__device_disk_find_local_path(libxl__gc *gc,
>> +                                                  libxl_domid domid,
>
> This new parameter would maybe be a little less confusing if it were
> explicitly `guest_domid'; after all it might be the driver domain
> domid.

Ack.

 -George
diff mbox

Patch

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index d6302a9..490a7d2 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2296,7 +2296,7 @@  int libxl__device_disk_setdefault(libxl__gc *gc, libxl_device_disk *disk)
 }
 
 int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
-                                   libxl_device_disk *disk,
+                                   const libxl_device_disk *disk,
                                    libxl__device *device)
 {
     int devid;
@@ -3002,6 +3002,7 @@  static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user,
 /* Callbacks */
 
 char * libxl__device_disk_find_local_path(libxl__gc *gc, 
+                                          libxl_domid domid,
                                           const libxl_device_disk *disk,
                                           bool qdisk_direct) {
     char *path = NULL;
@@ -3032,6 +3033,37 @@  char * libxl__device_disk_find_local_path(libxl__gc *gc,
         path = libxl__strdup(gc, disk->pdev_path);
         LOG(DEBUG, "Directly accessing local QDISK target %s", path);
         goto out;
+    } 
+
+    /* 
+     * If the format isn't raw and / or we're using a script, then see
+     * if the script has written a path to the "cooked" node
+     */
+    if(disk->script && domid != INVALID_DOMID) {
+        libxl__device device;
+        char *be_path, *pdpath;
+        int rc;
+
+        LOG(DEBUG, "Run from a script; checking for physical-device-path (vdev %s)",
+            disk->vdev);
+
+        rc = libxl__device_from_disk(gc, domid, disk, &device);
+        if (rc < 0)
+            goto out;
+
+        be_path = libxl__device_backend_path(gc, &device);
+
+        pdpath = libxl__sprintf(gc, "%s/physical-device-path", be_path);
+
+        LOG(DEBUG, "Attempting to read node %s", pdpath);
+        path = libxl__xs_read(gc, XBT_NULL, pdpath);
+
+        if (path)
+            LOG(DEBUG, "Accessing cooked block device %s", path);
+        else
+            LOG(DEBUG, "No physical-device-path, can't access locally.");
+
+        goto out;
     }
 
  out:
@@ -3058,7 +3090,8 @@  void libxl__device_disk_local_initiate_attach(libxl__egc *egc,
 
     LOG(DEBUG, "Trying to find local path");
 
-    if ((dls->diskpath = libxl__device_disk_find_local_path(gc, in_disk, false))) {
+    if ((dls->diskpath = libxl__device_disk_find_local_path(gc, INVALID_DOMID,
+                                                            in_disk, false))) {
         LOG(DEBUG, "Local path found, executing callback.");
         dls->callback(egc, dls, 0);
     } else {
@@ -3073,7 +3106,6 @@  void libxl__device_disk_local_initiate_attach(libxl__egc *egc,
         rc = libxl__device_disk_setdefault(gc, disk);
         if (rc) goto out;
 
-        /* If we can't find a local path, attach it */
         libxl__prepare_ao_device(ao, &dls->aodev);
         dls->aodev.callback = local_device_attach_cb;
         device_disk_add(egc, LIBXL_TOOLSTACK_DOMID, disk, &dls->aodev,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 917ebbf..646a49c 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1206,8 +1206,7 @@  static int libxl__build_device_model_args_new(libxl__gc *gc,
                     target_path = libxl__blktap_devpath(gc, disks[i].pdev_path,
                                                       disks[i].format);
                 else
-                    target_path = libxl__device_disk_find_local_path(gc, 
-                                                               &disks[i], true);
+                    target_path = libxl__device_disk_find_local_path(gc, guest_domid, &disks[i], true);
 
                 if (!target_path) {
                     LOG(WARN, "No way to get local access disk to image: %s", disks[i].vdev);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a511c6d..6291b9c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1709,7 +1709,7 @@  _hidden char *libxl__blktap_devpath(libxl__gc *gc,
 _hidden int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *params);
 
 _hidden int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
-                                   libxl_device_disk *disk,
+                                   const libxl_device_disk *disk,
                                    libxl__device *device);
 
 /* Calls poll() again - useful to check whether a signaled condition
@@ -2674,6 +2674,7 @@  static inline void libxl__device_disk_local_init(libxl__disk_local_state *dls)
  * See if we can find a way to access a disk locally
  */
 _hidden char * libxl__device_disk_find_local_path(libxl__gc *gc, 
+                                                  libxl_domid domid,
                                                   const libxl_device_disk *disk,
                                                   bool qdisk_direct);