From patchwork Wed Mar 2 11:14:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: George Dunlap X-Patchwork-Id: 8480151 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0F03C9F38C for ; Wed, 2 Mar 2016 11:16:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E240A2022A for ; Wed, 2 Mar 2016 11:16:50 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9F6FD20225 for ; Wed, 2 Mar 2016 11:16:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1ab4jb-0006GO-RP; Wed, 02 Mar 2016 11:14:27 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1ab4ja-0006Ed-Ld for xen-devel@lists.xen.org; Wed, 02 Mar 2016 11:14:26 +0000 Received: from [85.158.137.68] by server-7.bemta-3.messagelabs.com id ED/F4-04060-21BC6D65; Wed, 02 Mar 2016 11:14:26 +0000 X-Env-Sender: prvs=862dda752=George.Dunlap@citrix.com X-Msg-Ref: server-15.tower-31.messagelabs.com!1456917262!25996748!3 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 30806 invoked from network); 2 Mar 2016 11:14:25 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-15.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 2 Mar 2016 11:14:25 -0000 X-IronPort-AV: E=Sophos;i="5.22,528,1449532800"; d="scan'208";a="342498617" From: George Dunlap To: Date: Wed, 2 Mar 2016 11:14:04 +0000 Message-ID: <1456917244-2908-5-git-send-email-george.dunlap@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1456917244-2908-1-git-send-email-george.dunlap@citrix.com> References: <1456917244-2908-1-git-send-email-george.dunlap@citrix.com> MIME-Version: 1.0 X-DLP: MIA1 Cc: George Dunlap , Ian Jackson , Wei Liu , Ian Campbell , Roger Pau Monne Subject: [Xen-devel] [PATCH RFC 4/4] libxl: Allow local access for block devices with hotplug scripts X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: George Dunlap 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. First, modify the write_dev function in block-common to add an extra parameter: "physical-device-path", the path to the physical device which is passed to blkback. All hotplug scripts that use write_dev will automatically gain the new functionality. Second, 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. This allows qemuu to boot with block devices created with hotplug scripts. Unfortunately it does not allow pygrub to access a device locally without having to plug it in, because when pygrub runs the guests' disks have not yet been set up. Signed-off-by: George Dunlap --- CC: Ian Campbell CC: Ian Jackson CC: Wei Liu CC: Roger Pau Monne --- tools/hotplug/Linux/block-common.sh | 5 ++++- tools/libxl/libxl.c | 42 ++++++++++++++++++++++++++++++++++--- tools/libxl/libxl_bootloader.c | 1 + tools/libxl/libxl_dm.c | 2 +- tools/libxl/libxl_internal.h | 4 +++- 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/tools/hotplug/Linux/block-common.sh b/tools/hotplug/Linux/block-common.sh index ee95009..1aecd7e 100644 --- a/tools/hotplug/Linux/block-common.sh +++ b/tools/hotplug/Linux/block-common.sh @@ -58,8 +58,9 @@ device_major_minor() # write_dev() { local mm + local dev="$1" - mm=$(device_major_minor "$1") + mm=$(device_major_minor "$dev") if [ -z $mm ] then @@ -68,6 +69,8 @@ write_dev() { xenstore_write "$XENBUS_PATH/physical-device" "$mm" + xenstore_write "$XENBUS_PATH/physical-device-path" "$dev" + success } diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 2f66c3a..cc97fa8 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; @@ -2454,6 +2454,7 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid, if (!libxl__device_physdisk_major_minor(dev, &major, &minor)) flexarray_append_pair(back, "physical-device", GCSPRINTF("%x:%x", major, minor)); + flexarray_append_pair(back, "physical-device-path", dev); } assert(device->backend_kind == LIBXL__DEVICE_KIND_VBD); @@ -3017,6 +3018,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; @@ -3047,6 +3049,40 @@ 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) { + 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; + + /* Needs: dompath, device type, domid */ + be_path = libxl__device_backend_path(gc, &device); + + /* FIXME: Do we need to wait for things to be set up here? */ + + 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: @@ -3073,7 +3109,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, dls->domid, + in_disk, false))) { LOG(DEBUG, "Local path found, executing callback."); dls->callback(egc, dls, 0); } else { @@ -3088,7 +3125,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_bootloader.c b/tools/libxl/libxl_bootloader.c index 0ae074a..5648ed7 100644 --- a/tools/libxl/libxl_bootloader.c +++ b/tools/libxl/libxl_bootloader.c @@ -382,6 +382,7 @@ void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl) /* This sets the state of the dls struct from Undefined to Idle */ libxl__device_disk_local_init(&bl->dls); bl->dls.ao = ao; + bl->dls.domid = bl->domid; bl->dls.in_disk = bl->disk; bl->dls.blkdev_start = info->blkdev_start; bl->dls.callback = bootloader_disk_attached_cb; diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index 917ebbf..5bd4dad 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -1207,7 +1207,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc, disks[i].format); else target_path = libxl__device_disk_find_local_path(gc, - &disks[i], true); + 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 265b8a2..b773e5a 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 @@ -2650,6 +2650,7 @@ typedef void libxl__disk_local_state_callback(libxl__egc*, struct libxl__disk_local_state { /* filled by the user */ libxl__ao *ao; + libxl_domid domid; const libxl_device_disk *in_disk; libxl_device_disk disk; const char *blkdev_start; @@ -2674,6 +2675,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);