Port-xen archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Patch files for xen-4.1's xl



Hi,

Since there's renewed interest in Xen 4 on netbsd, I thought it's timely to get these patches out. The only reason I looked into this is because xm and xend have been giving me grief lately requiring killing the xend child process every so often (this is with Xen 4.1 and netbsd current, Xen 3.3 is fine). Additionally the xen folks claims that they're going to deprecate xm and xend, so it's time to move on.

Okay, attached are two patch files for xentools41 that would correct problems in xl when dealing with PV domUs using file (vnd) based disks. To use them: 1. Save the attachments into the sysutils/xentools41/patches directory of your pkgsrc tree and make sure you retain the original file names to maintain sorting order during the 'make patch' phase.
2. cd sysutils/xentools41/ and do 'make makepatchsum'
3. make patch just to make sure that the patches get applied properly, or otherwise you can just to make build. I made my changes against the version 1 day before pkgsrc-2012Q1, but I think it will apply cleanly against pkgsrc HEAD, although I haven't checked it.

There were two problems that I encountered:
1. Using xl, if you have a file based disk, it would decide that it needs to start a qemu-dm process. With xm and xend on netbsd, it would just setup vnd properly. I compared the xenstore entries between xm and xl and noticed that with xl the 'type' entry under /local/domain/0/backend/vbd/<domid>/<frontend_diskid>/ was always 'phy', as opposed to 'file' when a file based disk is specified. So, the changes were merely to convince xl to set 'type' to 'file' for file-based disks. I also added support for extended physical-like disk types so that you can define 'phy:<custom_block_device_type>:<custom_block_device_spec>,hda,w'. This is done again by setting the 'type' to whatever you set for <custom_block_device_type>. The /usr/pkg/etc/xen/scripts/block script needs to be adjusted to accommodate your <custom_block_device_type>, but now there is more flexibility, e.g. to provide iscsi, or pud/rump-based disks through dom0, or whatever, which is what blktap in linux-xen is trying to do but which we don't have. Note, that defining phy:file:... would execute the same code path in the block script as defining 'file:...' virtual disks. FYI, the block script is called by xenbackendd who watches changes in xenstore under /local/domain/0/backend/vbd, but not for anything related to tap or qdisk.
These changes are in the attached file patch-libxl_vnd_phylike_support.

2. Another problem with xl, which I suspect is netbsd dom0 specific, is that the block script doesn't get called after domU shutdown, and so if you have vnd based disks, vnconfig -u won't get called. This problem didn't appear with xl block-attach and xl block-detach however. These changes are in patch-libxl_vbd_destroy_fixup. This patch might be readily submitted upstream to the Xen folks, but I don't know whether the intrusive file: support for netbsd and the unsanctioned phy:<subtype>: scheme in the previous patch file would be well received upstream.

I've also tested my HVM domU file-based XP image against these patches and it also worked. I didn't have to change anything in my HVM domU config file. I don't expect to encounter any problem with a physical block device based HVM domU.

I'm thinking of refactoring and modifying the block script such that a script called block-<custom_block_device_type> will get called if available, so that users can extend the block script easily. But, feel free to beat me to it.

Anyway, give it a whirl and let me know if there is any problem/suggestions.

Cheers,
Toby





--- libxl/libxl_device.c.orig   2011-10-20 13:05:42.000000000 -0400
+++ libxl/libxl_device.c        2012-05-27 15:46:14.000000000 -0400
@@ -249,9 +249,15 @@
 
     if (!state)
         goto out;
-    if (atoi(state) != 4) {
-        xs_rm(ctx->xsh, XBT_NULL, be_path);
-        goto out;
+
+    switch (atoi(state)) {
+        case 4:
+            break;
+        case 5:
+            goto wait;
+        default:
+            xs_rm(ctx->xsh, XBT_NULL, be_path);
+            goto out;
     }
 
 retry_transaction:
@@ -266,12 +272,14 @@
             goto out;
         }
     }
+
+wait:
     if (!force) {
         xs_watch(ctx->xsh, state_path, be_path);
         rc = 1;
     } else {
-               xs_rm(ctx->xsh, XBT_NULL, be_path);
-       }
+       xs_rm(ctx->xsh, XBT_NULL, be_path);
+    }
 out:
     libxl__free_all(&gc);
     return rc;
--- libxl/libxl.h.orig  2011-10-20 13:05:42.000000000 -0400
+++ libxl/libxl.h       2012-05-08 02:17:57.000000000 -0400
@@ -185,6 +185,9 @@
     DISK_BACKEND_PHY,
     DISK_BACKEND_TAP,
     DISK_BACKEND_QDISK,
+#if defined(__NetBSD__)
+    DISK_BACKEND_VND,
+#endif
 } libxl_disk_backend;
 
 typedef enum {
--- libxl/libxl.c.orig  2011-10-20 13:05:42.000000000 -0400
+++ libxl/libxl.c       2012-05-28 00:33:14.000000000 -0400
@@ -896,6 +896,16 @@
         }
     }
 
+#if defined(__NetBSD__)
+    if (disk->backend == DISK_BACKEND_PHY) {
+        delimiter = strchr(file_name, ':');
+        if (delimiter) {
+            /* Bypass validation and defer to xenbackendd block script */
+            return 0;
+        }
+    }
+#endif
+
     if ( stat(file_name, &stat_buf) != 0 ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to stat %s", 
file_name);
         return ERROR_INVAL;
@@ -955,8 +965,64 @@
     device.kind = DEVICE_VBD;
 
     switch (disk->backend) {
-        case DISK_BACKEND_PHY: 
+#if defined(__NetBSD__)
+        case DISK_BACKEND_VND:
+            /* Use bogus device; block script must redefine */
+            major = 2; minor = 12; /* /dev/zero char device */
+
+            flexarray_append(back, "physical-device");
+            flexarray_append(back, libxl__sprintf(&gc, "%x:%x", major, minor));
+
+            flexarray_append(back, "params");
+            flexarray_append(back, disk->pdev_path);
+
+            device.backend_kind = DEVICE_VBD;
+            break;
+        case DISK_BACKEND_PHY:
+            /*
+             * If disk.pdev_path has a colon, the part left to the colon
+             * is considered to be the type for the phy: device.
+             * This allows defining disks as e.g.:
+             * - 'phy:vnd:<path_to_disk_image>,hda,w'
+             * - 'phy:iscsi:<iscsi_specification>,hda,w'
+             * - 'phy:<type>:<custom_specification>,hda,w'
+             *
+             * The caveat is that the /usr/pkg/etc/xen/scripts/block script
+             * needs to handle <type>. The xenstore will be set up such that
+             * the block script will receive type to be <type> and param to
+             * be whatever is left to '<type>:' and before a ','.
+             */
+            {
+                char *bi, *ei, *b, *e, c, *colon;
+
+                bi = disk->pdev_path;
+                ei = (ei = strchr(bi, '\0')) ? ei-1 : NULL;
+  
+                colon = strchr(bi, ':');
+                if (colon) {
+                    *colon = '\0';
+                    for (b=bi, e=ei; b < e; b++, e--) {
+                        c = *b; *b = *e; *e = c;
+                    }
+                    colon = ei - (colon - bi);
+                    backend_type = colon + 1;
+                    for (b=backend_type, e=ei; b < e; b++, e--) {
+                        c = *b; *b = *e; *e = c;  
+                    }
+                    for (b=bi, e=colon-1; b < e; b++, e--) {
+                        c = *b; *b = *e; *e = c;
+                    } 
+                    /* Use bogus device; block script must redefine */
+                    major = 2; minor = 12; /* /dev/zero char device */
+                } else {
+                    libxl__device_physdisk_major_minor(disk->pdev_path,
+                        &major, &minor);
+                } 
+            }
+#else
+        case DISK_BACKEND_PHY:
             libxl__device_physdisk_major_minor(disk->pdev_path, &major, 
&minor);
+#endif
             flexarray_append(back, "physical-device");
             flexarray_append(back, libxl__sprintf(&gc, "%x:%x", major, minor));
 
@@ -1059,8 +1125,19 @@
     devid = libxl__device_disk_dev_number(disk->vdev);
     device.backend_domid    = disk->backend_domid;
     device.backend_devid    = devid;
+#if defined(__NetBSD__)
+    switch (disk->backend) {
+    case DISK_BACKEND_PHY:
+    case DISK_BACKEND_VND:
+        device.backend_kind = DEVICE_VBD;
+        break;
+    default:
+        device.backend_kind = DEVICE_TAP;
+    }
+#else
     device.backend_kind     = 
         (disk->backend == DISK_BACKEND_PHY) ? DEVICE_VBD : DEVICE_TAP;
+#endif
     device.domid            = disk->domid;
     device.devid            = devid;
     device.kind             = DEVICE_VBD;
@@ -1078,6 +1155,9 @@
     char *ret = NULL;
 
     switch (disk->backend) {
+#if defined(__NetBSD__)
+       case DISK_BACKEND_VND:
+#endif
         case DISK_BACKEND_PHY: 
             if (disk->format != DISK_FORMAT_RAW) {
                 LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "physical block device must"
--- libxl/libxl_device.c.orig   2012-05-28 00:55:38.000000000 -0400
+++ libxl/libxl_device.c        2012-05-27 23:55:47.000000000 -0400
@@ -139,6 +139,9 @@
         case DISK_BACKEND_QDISK: return "qdisk";
         case DISK_BACKEND_TAP: return "tap";
         case DISK_BACKEND_PHY: return "phy";
+#if defined(__NetBSD__)
+        case DISK_BACKEND_VND: return "file";
+#endif
         default: return NULL;
     }
 }
--- libxl/libxl_dm.c.orig       2011-10-20 13:05:42.000000000 -0400
+++ libxl/libxl_dm.c    2012-05-08 02:17:01.000000000 -0400
@@ -845,6 +845,9 @@
                 ret = 1;
                 goto out;
 
+#if defined(__NetBSD__)
+            case DISK_BACKEND_VND:
+#endif
             case DISK_BACKEND_PHY:
             case DISK_BACKEND_UNKNOWN:
                 break;
--- libxl/xl_cmdimpl.c.orig     2011-10-20 13:05:43.000000000 -0400
+++ libxl/xl_cmdimpl.c  2012-05-27 14:39:08.000000000 -0400
@@ -484,7 +484,11 @@
                 }else if ( !strcmp(tok, "file") ) {
                     state = DSTATE_PHYSPATH;
                     disk->format = DISK_FORMAT_RAW;
+#if defined(__NetBSD__)
+                    disk->backend = DISK_BACKEND_VND;
+#else
                     disk->backend = DISK_BACKEND_TAP;
+#endif
                 }else if ((!strcmp(tok, "tap")) ||
                           (!strcmp(tok, "tap2"))) {
                     state = DSTATE_TAP;
@@ -4432,7 +4436,11 @@
     if (!strcmp(tok, "phy")) {
         disk.backend = DISK_BACKEND_PHY;
     } else if (!strcmp(tok, "file")) {
+#if defined(__NetBSD__)
+        disk.backend = DISK_BACKEND_VND;
+#else
         disk.backend = DISK_BACKEND_TAP;
+#endif
     } else if (!strcmp(tok, "tap")) {
         tok = strtok(NULL, ":");
         if (!strcmp(tok, "aio")) {


Home | Main Index | Thread Index | Old Index