Thank you all. Have tested pv-grub and qemu-nbd trick. Both work.
Following is the test patch that starts qemu-nbd to mount a non-raw qdisk in domain0, so that it can work with qcow/qcow2 disk image and using pygrub. I don't know if we need such a patch, or prefer to ask user to use pv-grub instead. Just post here for any chance of use. Thanks.
Patch description: start qemu-nbd to mount non-raw qdisk in dom0 so that xl can create PV guest with qcow/qcow2 disk image and using pygrub.
Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx>
diff -r b4cf57bbc3fb tools/libxl/libxl.c
--- a/tools/libxl/libxl.cThu Oct 20 15:24:46 2011 +0800
+++ b/tools/libxl/libxl.cThu Oct 20 15:48:45 2011 +0800
@@ -1078,12 +1078,41 @@
return rc;
}
+static char * nbd_mount_disk(libxl_device_disk *disk)
+{
+ int i;
+ int nbds_max = 16;
+ char *nbd_dev, *cmd;
+ char *ret = NULL;
+
+ for (i = 0; i < nbds_max; i++) {
+ asprintf(&nbd_dev,"/dev/nbd%d", i);
+ asprintf(&cmd, "qemu-nbd -c %s %s", nbd_dev, disk->pdev_path);
+ if (system(cmd) == 0) {
+ ret = strdup(nbd_dev);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int nbd_unmount_disk(char *diskpath) {
+ char *cmd;
+ asprintf(&cmd, "qemu-nbd -d %s", diskpath);
+ if (system(cmd) == 0)
+ return 0;
+ else
+ return ERROR_FAIL;
+}
+
char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk)
{
libxl__gc gc = LIBXL_INIT_GC(ctx);
char *dev = NULL;
char *ret = NULL;
int rc;
+ char *mdev = NULL;
rc = libxl__device_disk_set_backend(&gc, disk);
if (rc) goto out;
@@ -1118,8 +1147,12 @@
break;
case LIBXL_DISK_BACKEND_QDISK:
if (disk->format != LIBXL_DISK_FORMAT_RAW) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot locally"
- " attach a qdisk image if the format is not raw");
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "attaching a non-raw qdisk image to domain 0\n");
+ mdev = nbd_mount_disk(disk);
+ if (mdev)
+ dev = mdev;
+ else
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "fail to mount image with qemu-nbd");
break;
}
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "locally attaching qdisk %s\n",
@@ -1135,11 +1168,13 @@
out:
if (dev != NULL)
ret = strdup(dev);
+ if (mdev)
+ free(mdev);
libxl__free_all(&gc);
return ret;
}
-int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk)
+int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath)
{
/* Nothing to do for PHYSTYPE_PHY. */
@@ -1147,6 +1182,19 @@
* For other device types assume that the blktap2 process is
* needed by the soon to be started domain and do nothing.
*/
+ int ret;
+
+ switch (disk->backend) {
+ case LIBXL_DISK_BACKEND_QDISK:
+ if (disk->format != LIBXL_DISK_FORMAT_RAW) {
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Locally detach a non-raw "
+ "qdisk image");
+ ret = nbd_unmount_disk(diskpath);
+ return ret;
+ }
+ default:
+ break;
+ }
return 0;
}
diff -r b4cf57bbc3fb tools/libxl/libxl.h
--- a/tools/libxl/libxl.hThu Oct 20 15:24:46 2011 +0800
+++ b/tools/libxl/libxl.hThu Oct 20 15:48:45 2011 +0800
@@ -390,7 +390,7 @@
* Make a disk available in this domain. Returns path to a device.
*/
char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk);
-int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk);
+int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath);
int libxl_device_nic_init(libxl_device_nic *nic, int dev_num);
int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic);
diff -r b4cf57bbc3fb tools/libxl/libxl_bootloader.c
--- a/tools/libxl/libxl_bootloader.cThu Oct 20 15:24:46 2011 +0800
+++ b/tools/libxl/libxl_bootloader.cThu Oct 20 15:48:45 2011 +0800
@@ -424,7 +424,7 @@
rc = 0;
out_close:
if (diskpath) {
- libxl_device_disk_local_detach(ctx, disk);
+ libxl_device_disk_local_detach(ctx, disk, diskpath);
free(diskpath);
}
if (fifo_fd > -1)
>>> Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> 10/19/2011 9:40 PM >>> On Wed, 19 Oct 2011, Fajar A. Nugraha wrote: > On Wed, Oct 19, 2011 at 5:55 PM, Stefano Stabellini > <stefano.stabellini@xxxxxxxxxxxxx> wrote: > >> This is a PV guest configured with pygrub, correct? > >> If so, qcow/qcow2 are not supported in this scenario. > >> > >> You could: > >> > >> - avoid using pygrub (specify the kernel manually) and keep using qcow/qcow2; > >> - switch to raw disks and keep using pygrub; > >> - install a Linux kernel that support blktap2 (like the XCP kernel, see > >> http://wiki.xen.org/xenwiki/XenDom0Kernels) and switch to VHD format. > >> > > > > The way to make it work would be to call qemu-nbd and nbd-client from xl > > so that a /dev/nbd0 comes up in dom0 and pygrub can use it to extract > > the kernel and initrd from the qcow2 image. > > would pv-grub work? If yes, it would give better performance compared > to nbd workaround.
Yes, it should. That would be the other alternative.
|