From: Kamala Narasimhan <kamala.narasimhan@gmail.com>
To: "xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: [PATCH 3/5] xl disk configuration parsing changes
Date: Mon, 07 Feb 2011 16:24:25 -0500 [thread overview]
Message-ID: <4D506309.7010803@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 208 bytes --]
Attached is a patch to refactor xl disk configuration option parsing. Please let me know if there are further comments/issues to fix.
Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Kamala
[-- Attachment #2: xl-disk-parsing-changes.diff --]
[-- Type: text/x-diff, Size: 11077 bytes --]
diff -u -r libxl-interface-changes/xl_cmdimpl.c libxl/xl_cmdimpl.c
--- libxl-interface-changes/xl_cmdimpl.c 2011-02-07 12:03:37.000000000 -0500
+++ libxl/xl_cmdimpl.c 2011-02-07 14:58:39.000000000 -0500
@@ -438,143 +438,184 @@
return 0;
}
-#define DSTATE_INITIAL 0
-#define DSTATE_TAP 1
-#define DSTATE_PHYSPATH 2
-#define DSTATE_VIRTPATH 3
-#define DSTATE_VIRTTYPE 4
-#define DSTATE_RW 5
-#define DSTATE_TERMINAL 6
+#define DSTATE_INITIAL 0
+#define DSTATE_ATTRIB_PARSED 1
+#define DSTATE_VDEV_PARSED 2
+static int parse_disk_attrib(libxl_device_disk *disk, char *attrib)
+{
+ if ( attrib[0] == 'w' )
+ disk->readwrite = 1;
+ else if ( attrib[0] != 'r' ) {
+ LOG("Required access rights attribute is missing or incorrect in "
+ "disk configuration option %s", attrib);
+ return ERROR_INVAL;
+ }
+
+ return 0;
+}
+
+static int parse_disk_vdev_info(libxl_device_disk *disk, char *vdev_info)
+{
+ char *vdev, *type;
+
+ type = strchr(vdev_info, ':');
+ if ( type ) {
+ *type = '\0';
+ type++;
+ if ( !strncmp(type, "cdrom", sizeof("cdrom")-1) ) {
+ disk->is_cdrom = 1;
+ disk->unpluggable = 1;
+ }
+ else {
+ LOG("Invalid vdev type %s specified in disk configuration option",
+ type);
+ return ERROR_INVAL;
+ }
+ }
+
+ vdev = vdev_info;
+ if ( vdev[0] == '\0' ) {
+ LOG("Mandatory attribute vdev not specified");
+ return ERROR_INVAL;
+ }
+
+ disk->vdev = strdup(vdev);
+ return 0;
+}
+
+static int parse_disk_pdev_info(libxl_device_disk *disk, char *pdev_info)
+{
+ char *pdev_type, *pdev_impl, *pdev_format, *pdev_path;
+
+ if ( pdev_info[0] == '\0' && !disk->is_cdrom ) {
+ /* pdev can be empty string only for cdrom drive with no media inserted */
+ LOG("Required vdev info missing in disk configuration option");
+ return ERROR_INVAL;
+ }
+
+ pdev_path = strrchr(pdev_info, ':');
+ if ( !pdev_path ) {
+ disk->pdev_path = strdup(pdev_info);
+ return 0;
+ }
+
+ *pdev_path = '\0';
+ disk->pdev_path = strdup(++pdev_path);
+
+ pdev_format = strrchr(pdev_info, ':');
+ if ( !pdev_format )
+ pdev_format = pdev_info;
+ else {
+ *pdev_format = '\0';
+ pdev_format++;
+ }
+
+ if ( !strncmp(pdev_format, "raw", sizeof("raw")-1) )
+ disk->format = DISK_FORMAT_RAW;
+ else if ( !strncmp(pdev_format, "qcow", sizeof("qcow")-1) )
+ disk->format = DISK_FORMAT_QCOW;
+ else if ( !strncmp(pdev_format, "qcow2", sizeof("qcow2")-1) )
+ disk->format = DISK_FORMAT_QCOW2;
+ else if ( !strncmp(pdev_format, "vhd", sizeof("vhd")-1) )
+ disk->format = DISK_FORMAT_VHD;
+
+ if ( disk->format == DISK_FORMAT_UNKNOWN )
+ pdev_impl = pdev_format;
+ else {
+ pdev_impl = strrchr(pdev_info, ':');
+ if ( !pdev_impl )
+ return 0;
+ *pdev_impl = '\0';
+ pdev_impl++;
+ }
+
+ if ( !strncmp(pdev_impl, "aio", sizeof("aio")-1) ||
+ !strncmp(pdev_impl, "tapdisk", sizeof("tapdisk")-1) )
+ disk->backend = DISK_BACKEND_TAPDISK2;
+ else if ( !strncmp(pdev_impl, "ioemu", sizeof("ioemu")-1) )
+ disk->backend = DISK_BACKEND_QEMU;
+
+ if ( disk->backend == DISK_BACKEND_UNKNOWN )
+ pdev_type = pdev_impl;
+ else {
+ pdev_type = pdev_info;
+ if ( pdev_type[0] == '\0' )
+ return 0;
+ }
+
+ if ( !strncmp(pdev_type, "phy", sizeof("phy")-1) )
+ disk->backend = DISK_BACKEND_BLKBACK;
+ else if ( !strncmp(pdev_type, "file", sizeof("file")-1) ||
+ !strncmp(pdev_type, "tap", sizeof("tap")-1) ||
+ !strncmp(pdev_type, "tap2", sizeof("tap2")-1) )
+ disk->backend = DISK_BACKEND_TAPDISK2;
+
+ return 0;
+}
+
+/*
+ * Note: Following code calls methods each of which will parse
+ * specific chunks of the disk configuration option, the specific
+ * chunks being attribute, vdev and pdev. As with any parsing code
+ * it makes assumption about the order in which specific chunks appear
+ * in the disk configuration option string. So, please use
+ * care while modifying the code below, esp. when it comes to
+ * the order of calls.
+ */
static int parse_disk_config(libxl_device_disk *disk, char *buf2)
{
- int state = DSTATE_INITIAL;
- char *p, *end, *tok;
+ int state = DSTATE_INITIAL, ret_val;
+ char *substr = buf2;
memset(disk, 0, sizeof(*disk));
- for(tok = p = buf2, end = buf2 + strlen(buf2) + 1; p < end; p++) {
- switch(state){
- case DSTATE_INITIAL:
- if ( *p == ':' ) {
- *p = '\0';
- if ( !strcmp(tok, "phy") ) {
- state = DSTATE_PHYSPATH;
- disk->format = DISK_FORMAT_RAW;
- disk->backend = DISK_BACKEND_BLKBACK;
- }else if ( !strcmp(tok, "file") ) {
- state = DSTATE_PHYSPATH;
- disk->format = DISK_FORMAT_RAW;
- disk->backend = DISK_BACKEND_TAPDISK2;
- }else if ( !strcmp(tok, "tap") ) {
- state = DSTATE_TAP;
- }else{
- fprintf(stderr, "Unknown disk type: %s\n", tok);
- return 0;
+ for ( substr = strrchr(buf2, ',');
+ substr || (!substr && state == DSTATE_VDEV_PARSED);
+ substr = strrchr(buf2, ',') ) {
+ switch ( state ) {
+ case DSTATE_INITIAL: {
+ if ( !substr ) {
+ LOG("Invalid disk configuration option %s. Refer to the xl disk "
+ "configuration document for further information", buf2);
+ return ERROR_INVAL;
}
- tok = p + 1;
- } else if (*p == ',') {
- state = DSTATE_VIRTPATH;
- disk->backend = DISK_FORMAT_EMPTY;
- disk->pdev_path = strdup("");
- tok = p + 1;
- }
- break;
- case DSTATE_TAP:
- if ( *p == ':' ) {
- *p = '\0';
- if ( !strcmp(tok, "aio") ) {
- disk->format = DISK_FORMAT_RAW;
- disk->backend = DISK_BACKEND_TAPDISK2;
- }else if ( !strcmp(tok, "vhd") ) {
- disk->format = DISK_FORMAT_VHD;
- disk->backend = DISK_BACKEND_TAPDISK2;
- }else if ( !strcmp(tok, "qcow") ) {
- disk->format = DISK_FORMAT_QCOW;
- disk->backend = DISK_BACKEND_QEMU;
- }else if ( !strcmp(tok, "qcow2") ) {
- disk->format = DISK_FORMAT_QCOW2;
- disk->backend = DISK_BACKEND_QEMU;
- }else {
- fprintf(stderr, "Unknown tapdisk type: %s\n", tok);
- return 0;
- }
-
- tok = p + 1;
- state = DSTATE_PHYSPATH;
- }
- break;
- case DSTATE_PHYSPATH:
- if ( *p == ',' ) {
- int ioemu_len;
-
- *p = '\0';
- disk->pdev_path = (*tok) ? strdup(tok) : NULL;
- tok = p + 1;
-
- /* hack for ioemu disk spec */
- ioemu_len = strlen("ioemu:");
- state = DSTATE_VIRTPATH;
- if ( tok + ioemu_len < end &&
- !strncmp(tok, "ioemu:", ioemu_len)) {
- tok += ioemu_len;
- p += ioemu_len;
- }
- }
- break;
- case DSTATE_VIRTPATH:
- if ( *p == ',' || *p == ':' || *p == '\0' ) {
- switch(*p) {
- case ':':
- state = DSTATE_VIRTTYPE;
- break;
- case ',':
- state = DSTATE_RW;
- break;
- case '\0':
- state = DSTATE_TERMINAL;
- break;
- }
- if ( tok == p )
- goto out;
- *p = '\0';
- disk->vdev = (*tok) ? strdup(tok) : NULL;
- tok = p + 1;
+ *substr = '\0';
+ substr++;
+ ret_val = parse_disk_attrib(disk, substr);
+ if ( ret_val )
+ return ret_val;
+ state = DSTATE_ATTRIB_PARSED;
+ break;
}
- break;
- case DSTATE_VIRTTYPE:
- if ( *p == ',' || *p == '\0' ) {
- *p = '\0';
- if ( !strcmp(tok, "cdrom") ) {
- disk->is_cdrom = 1;
- disk->unpluggable = 1;
- }else{
- fprintf(stderr, "Unknown virtual disk type: %s\n", tok);
- return 0;
+ case DSTATE_ATTRIB_PARSED: {
+ if ( !substr ) {
+ LOG("Required vdev info missing in disk configuration option");
+ return ERROR_INVAL;
}
- tok = p + 1;
- state = (*p == ',') ? DSTATE_RW : DSTATE_TERMINAL;
+ *substr = '\0';
+ substr++;
+ ret_val = parse_disk_vdev_info(disk, substr);
+ if ( ret_val )
+ return ret_val;
+ state = DSTATE_VDEV_PARSED;
+ break;
}
- break;
- case DSTATE_RW:
- if ( *p == '\0' ) {
- disk->readwrite = (tok[0] == 'w');
- tok = p + 1;
- state = DSTATE_TERMINAL;
+ case DSTATE_VDEV_PARSED: {
+ ret_val = parse_disk_pdev_info(disk, buf2);
+ if ( ret_val )
+ return ret_val;
+ if ( disk->format == DISK_FORMAT_UNKNOWN )
+ disk->format = DISK_FORMAT_RAW;
+ if ( disk->backend == DISK_BACKEND_UNKNOWN )
+ disk->backend = DISK_BACKEND_TAPDISK2;
+ return 0;
}
- break;
- case DSTATE_TERMINAL:
- goto out;
}
}
-out:
- if ( tok != p || state != DSTATE_TERMINAL ) {
- fprintf(stderr, "parse error in disk config near '%s'\n", tok);
- return 0;
- }
-
- return 1;
+ LOG("Disk configuration parsing failed");
+ return ERROR_INVAL;
}
static void parse_config_data(const char *configfile_filename_report,
@@ -768,7 +809,7 @@
d_config->disks = (libxl_device_disk *) realloc(d_config->disks, sizeof (libxl_device_disk) * (d_config->num_disks + 1));
disk = d_config->disks + d_config->num_disks;
- if ( !parse_disk_config(disk, buf2) ) {
+ if ( parse_disk_config(disk, buf2) ) {
exit(1);
}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2011-02-07 21:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-07 21:24 Kamala Narasimhan [this message]
2011-02-08 16:43 ` [PATCH 3/5] xl disk configuration parsing changes Stefano Stabellini
2011-02-08 19:08 ` Kamala Narasimhan
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=4D506309.7010803@gmail.com \
--to=kamala.narasimhan@gmail.com \
--cc=xen-devel@lists.xensource.com \
/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.