From: Marek Marczykowski <marmarek@invisiblethingslab.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>,
Jim Fehlig <jfehlig@suse.com>,
Dave Scott <Dave.Scott@eu.citrix.com>,
Ian Campbell <Ian.Campbell@citrix.com>,
xen-devel <xen-devel@lists.xen.org>
Subject: Re: libvirt, libxl and QDISKs
Date: Fri, 26 Apr 2013 13:31:31 +0200 [thread overview]
Message-ID: <517A6593.70906@invisiblethingslab.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1304261108000.4180@kaball.uk.xensource.com>
[-- Attachment #1.1.1: Type: text/plain, Size: 3371 bytes --]
On 26.04.2013 12:10, Stefano Stabellini wrote:
> On Fri, 26 Apr 2013, Jim Fehlig wrote:
>> if (l_disk->driverName) {
>> if (STREQ(l_disk->driverName, "tap") ||
>> STREQ(l_disk->driverName, "tap2")) {
>> switch (l_disk->format) {
>> case VIR_STORAGE_FILE_QCOW:
>> x_disk->format = LIBXL_DISK_FORMAT_QCOW;
>> x_disk->backend = LIBXL_DISK_BACKEND_QDISK;
>> break;
>> case VIR_STORAGE_FILE_QCOW2:
>> x_disk->format = LIBXL_DISK_FORMAT_QCOW2;
>> x_disk->backend = LIBXL_DISK_BACKEND_QDISK;
>> break;
>> case VIR_STORAGE_FILE_VHD:
>> x_disk->format = LIBXL_DISK_FORMAT_VHD;
>> x_disk->backend = LIBXL_DISK_BACKEND_TAP;
>> break;
>> case VIR_STORAGE_FILE_NONE:
>> /* No subtype specified, default to raw/tap */
>> case VIR_STORAGE_FILE_RAW:
>> x_disk->format = LIBXL_DISK_FORMAT_RAW;
>> x_disk->backend = LIBXL_DISK_BACKEND_TAP;
>> break;
>> default:
>> virReportError(VIR_ERR_INTERNAL_ERROR,
>> _("libxenlight does not support disk
>> driver %s"),
>>
>> virStorageFileFormatTypeToString(l_disk->format));
>> return -1;
>> }
>> } else if (STREQ(l_disk->driverName, "file")) {
>> x_disk->format = LIBXL_DISK_FORMAT_RAW;
>> x_disk->backend = LIBXL_DISK_BACKEND_TAP;
>> } else if (STREQ(l_disk->driverName, "phy")) {
>> x_disk->format = LIBXL_DISK_FORMAT_RAW;
>> x_disk->backend = LIBXL_DISK_BACKEND_PHY;
>> } else {
>> virReportError(VIR_ERR_INTERNAL_ERROR,
>> _("libxenlight does not support disk driver %s"),
>> l_disk->driverName);
>> return -1;
>> }
>> } else {
>> /*
>> * If driverName is not specified, default to raw as per
>> * xl-disk-configuration.txt in the xen documentation and let
>> * libxl pick a suitable backend.
>> */
>> x_disk->format = LIBXL_DISK_FORMAT_RAW;
>> x_disk->backend = LIBXL_DISK_BACKEND_UNKNOWN;
>> }
>
> It looks like the defaults are the same of libxl.
>
> However the mapping of RAW to TAP (libxl does the same) has always been
> a bit dubious to me: now that upstream QEMU is used with HVM guests too
> by libxl, there is no reason to use blktap over QEMU for raw files any
> more.
What about old good loop+phy based backend for file disk images? I don't want
whole qemu in dom0 for PV domains, only for handling simple disk backend.
Additionally sparse images + loop + phy + mount -o discard in domU makes the
images "auto shrinking". Don't know if qemu is able to do this.
Attached patch, which I currently use for that. If it is close to something
that would be accepted, I will send it in new thread.
BTW I don't want qemu in dom0 for HVM also, but this is another story
(modified stubdom etc) and probably not acceptable in vanilla xen.
--
Best Regards / Pozdrawiam,
Marek Marczykowski
Invisible Things Lab
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.1.2: 0001-libxl-allow-PHY-backend-for-files-allocate-loop-devi.patch --]
[-- Type: text/x-patch; name="0001-libxl-allow-PHY-backend-for-files-allocate-loop-devi.patch", Size: 8660 bytes --]
From cbd5831fd5a6a00429957acb6b1d58d7c645f219 Mon Sep 17 00:00:00 2001
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
Date: Tue, 16 Apr 2013 22:20:25 +0200
Subject: [PATCH] libxl: allow PHY backend for files - allocate loop device
Organization: Invisible Things Lab
Cc: Marek Marczykowski <marmarek@invisiblethingslab.com>
This is implementation of /etc/xen/scripts/block behaviour, but without
calling the script, which should be much faster.
Signed-off-by: Marek Marczykowski <marmarek@invisiblethingslab.com>
---
tools/libxl/libxl.c | 13 ++++-
tools/libxl/libxl_device.c | 8 +++
tools/libxl/libxl_internal.h | 9 +++
tools/libxl/libxl_linux.c | 129 ++++++++++++++++++++++++++++++++++++++++++-
tools/libxl/libxl_netbsd.c | 11 ++++
5 files changed, 168 insertions(+), 2 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index a813a88..4af5591 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2086,7 +2086,18 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,
*/
if (!disk->script) {
int major, minor;
- libxl__device_physdisk_major_minor(dev, &major, &minor);
+ char *node;
+
+ node = libxl__loopdev_setup(gc, dev);
+ if (!node) {
+ /* error already reported by libxl__setup_loopdev */
+ goto out;
+ }
+ if (node != dev) {
+ flexarray_append_pair(back, "node", node);
+ }
+
+ libxl__device_physdisk_major_minor(node, &major, &minor);
flexarray_append_pair(back, "physical-device",
libxl__sprintf(gc, "%x:%x", major, minor));
}
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index d622826..936961e 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -883,6 +883,7 @@ static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev)
{
STATE_AO_GC(aodev->ao);
char *be_path = libxl__device_backend_path(gc, aodev->dev);
+ char *node;
char **args = NULL, **env = NULL;
int rc = 0;
int hotplug;
@@ -906,6 +907,13 @@ static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev)
switch (hotplug) {
case 0:
/* no hotplug script to execute */
+ /* check if we have loop device allocated - if so, try to release it */
+ node = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/node", be_path));
+ if (node) {
+ /* ignore errors: if device is already released - no problem, if
+ * EBUSY - can be shared */
+ libxl__loopdev_cleanup(gc, node);
+ }
goto out;
case 1:
/* execute hotplug script */
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 3ba3a21..573e3d1 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1050,6 +1050,15 @@ static inline void libxl__domaindeathcheck_stop(libxl__gc *gc,
*/
_hidden int libxl__try_phy_backend(mode_t st_mode);
+/*
+ * libxl__setup_loopdev - Setup loop device if needed.
+ *
+ * Return its path on success or NULL in case of failure. If no loop device is
+ * needed, return original filename.
+ */
+_hidden char *libxl__loopdev_setup(libxl__gc *gc, char *filename);
+
+_hidden void libxl__loopdev_cleanup(libxl__gc *gc, char *devname);
_hidden char *libxl__devid_to_localdev(libxl__gc *gc, int devid);
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index 37815eb..115332a 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -16,16 +16,143 @@
#include "libxl_osdeps.h" /* must come before any other headers */
#include "libxl_internal.h"
+#include <linux/loop.h>
int libxl__try_phy_backend(mode_t st_mode)
{
- if (!S_ISBLK(st_mode)) {
+ if (!S_ISBLK(st_mode) && !S_ISREG(st_mode)) {
return 0;
}
return 1;
}
+char *libxl__loopdev_setup(libxl__gc *gc, char *filename) {
+ struct stat st;
+ DIR *sysblock;
+ int dir_fd;
+ int control_fd = -1;
+ int loop_fd = -1;
+ int file_fd = -1;
+ int devnr;
+ struct dirent *d;
+ struct loop_info64 info;
+ char *loop_name = NULL;
+ char *ret = NULL;
+
+ if (stat(filename, &st) < 0) {
+ LOG(ERROR, "unable to stat %s", filename);
+ return NULL;
+ }
+
+ /* do not do anything if filename already is block device */
+ if (S_ISBLK(st.st_mode))
+ return filename;
+
+ /* first check if file has already loop device assigned according to
+ *
+ * losetup implementation readdir on /sys/block + stat on
+ * loop/backing_file is faster than open each loop dev
+ */
+ sysblock = opendir("/sys/block");
+ if (!sysblock) {
+ LOG(ERROR, "unable to open /sys/block");
+ return NULL;
+ }
+
+ dir_fd = dirfd(sysblock);
+
+ while ((d = readdir(sysblock))) {
+ char name[256];
+ struct stat buf;
+
+ if (strcmp(d->d_name, ".") == 0
+ || strcmp(d->d_name, "..") == 0
+ || strncmp(d->d_name, "loop", 4) != 0)
+ continue;
+ snprintf(name, sizeof(name), "%s/loop/backing_file", d->d_name);
+ if (fstatat(dir_fd, name, &buf, 0) == 0) {
+ snprintf(name, sizeof(name), "/dev/%s", d->d_name);
+ loop_fd = open(name, O_RDWR);
+ if (loop_fd < 0) {
+ LOG(ERROR, "unable to open %s", name);
+ goto out;
+ }
+ if (ioctl(loop_fd, LOOP_GET_STATUS64, &info) < 0) {
+ LOG(ERROR, "unable to get %s info: %s", name, strerror(errno));
+ goto out;
+ }
+ if (info.lo_inode == st.st_ino && info.lo_device == st.st_dev) {
+ /* found */
+ ret = libxl__strdup(gc, name);
+ goto out;
+ }
+ }
+ }
+
+ /* not found, so allocate new one */
+ file_fd = open(filename, O_RDWR);
+ if (file_fd < 0) {
+ LOG(ERROR, "unable to open %s: %s", filename, strerror(errno));
+ goto out;
+ }
+
+ control_fd = open("/dev/loop-control", O_RDWR);
+ if (control_fd < 0) {
+ LOG(ERROR, "unable to open /dev/loop-control: %s", strerror(errno));
+ goto out;
+ }
+ devnr = ioctl(control_fd, LOOP_CTL_GET_FREE);
+ if (devnr < 0) {
+ LOG(ERROR, "unable to get free loop device: %s", strerror(errno));
+ goto out;
+ }
+ loop_name = libxl__sprintf(gc, "/dev/loop%d", devnr);
+ loop_fd = open(loop_name, O_RDWR);
+ if (loop_fd < 0) {
+ LOG(ERROR, "unable to open %s: %s", loop_name, strerror(errno));
+ goto out;
+ }
+ if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0) {
+ LOG(ERROR, "unable to set loop backing store: %s", strerror(errno));
+ goto out;
+ }
+ ret = loop_name;
+
+out:
+ if (file_fd >= 0)
+ close(file_fd);
+ if (control_fd >= 0)
+ close(control_fd);
+ if (loop_fd >= 0)
+ close(loop_fd);
+ if (sysblock)
+ closedir(sysblock);
+
+ return ret;
+}
+
+void libxl__loopdev_cleanup(libxl__gc *gc, char *devname)
+{
+ int loop_fd;
+
+ loop_fd = open(devname, O_RDWR);
+ if (loop_fd < 0) {
+ LOG(ERROR, "unable to open device %s: %s", devname, strerror(errno));
+ goto out;
+ }
+
+ if (ioctl(loop_fd, LOOP_CLR_FD) < 0) {
+ LOG(ERROR, "unable to release device %s: %s", devname, strerror(errno));
+ goto out;
+ }
+
+out:
+ if (loop_fd >= 0)
+ close(loop_fd);
+}
+
+
#define EXT_SHIFT 28
#define EXTENDED (1<<EXT_SHIFT)
#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c
index 898e160..1e71572 100644
--- a/tools/libxl/libxl_netbsd.c
+++ b/tools/libxl/libxl_netbsd.c
@@ -25,6 +25,17 @@ int libxl__try_phy_backend(mode_t st_mode)
return 0;
}
+char *libxl__loopdev_setup(libxl__gc *gc, char *filename)
+{
+ /* files supported natively */
+ return filename;
+}
+
+void libxl__loopdev_cleanup(libxl__gc *gc, char *devname)
+{
+ /* nothing to do */
+}
+
char *libxl__devid_to_localdev(libxl__gc *gc, int devid)
{
/* TODO */
--
1.8.1.4
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 553 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2013-04-26 11:31 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-24 14:22 libvirt, libxl and QDISKs David Scott
2013-04-24 15:55 ` Stefano Stabellini
2013-04-25 8:55 ` Ian Campbell
2013-04-25 10:36 ` George Dunlap
2013-04-25 11:33 ` Ian Campbell
2013-04-25 11:55 ` Stefano Stabellini
2013-04-25 11:57 ` Ian Campbell
2013-04-25 12:12 ` David Scott
2013-04-25 12:43 ` Ian Campbell
2013-04-25 13:22 ` David Scott
2013-04-25 13:56 ` Ian Campbell
2013-04-26 1:27 ` Jim Fehlig
2013-04-26 4:50 ` Jim Fehlig
2013-04-26 10:37 ` David Scott
2013-04-26 23:44 ` Jim Fehlig
[not found] ` <517B1170.4020300@suse.com>
2013-04-29 9:41 ` David Scott
2013-04-26 8:49 ` Ian Campbell
2013-04-26 10:10 ` Stefano Stabellini
2013-04-26 10:13 ` Ian Campbell
2013-04-26 10:28 ` Stefano Stabellini
2013-04-26 11:31 ` Marek Marczykowski [this message]
2013-04-26 11:40 ` Ian Campbell
2013-04-26 11:48 ` Stefano Stabellini
2013-04-26 13:27 ` Ian Campbell
2013-04-26 17:10 ` Stefano Stabellini
2013-04-29 8:23 ` Ian Campbell
2013-04-29 10:07 ` Stefano Stabellini
2013-04-26 11:50 ` Marek Marczykowski
2013-04-29 21:00 ` Jim Fehlig
2013-04-26 11:45 ` Stefano Stabellini
2013-04-26 14:36 ` Roger Pau Monné
2013-04-25 18:26 ` Sylvain Munaut
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=517A6593.70906@invisiblethingslab.com \
--to=marmarek@invisiblethingslab.com \
--cc=Dave.Scott@eu.citrix.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=jfehlig@suse.com \
--cc=stefano.stabellini@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.