Index: src/xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.106 diff -u -p -r1.106 xend_internal.c --- src/xend_internal.c 4 Apr 2007 14:19:49 -0000 1.106 +++ src/xend_internal.c 6 Apr 2007 01:26:22 -0000 @@ -1441,6 +1441,7 @@ xend_parse_sexp_desc(virConnectPtr conn, char *offset; int isBlock = 0; int cdrom = 0; + int isNoSrcCdrom = 0; char *drvName = NULL; char *drvType = NULL; const char *src = NULL; @@ -1458,64 +1459,75 @@ xend_parse_sexp_desc(virConnectPtr conn, mode = sexpr_node(node, "device/tap/mode"); } - if (src == NULL) { - virXendError(conn, VIR_ERR_INTERNAL_ERROR, - _("domain information incomplete, vbd has no src")); - goto bad_parse; - } - if (dst == NULL) { virXendError(conn, VIR_ERR_INTERNAL_ERROR, _("domain information incomplete, vbd has no dev")); goto bad_parse; } - - offset = strchr(src, ':'); - if (!offset) { - virXendError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse vbd filename, missing driver name")); - goto bad_parse; - } - - drvName = malloc((offset-src)+1); - if (!drvName) { - virXendError(conn, VIR_ERR_NO_MEMORY, - _("allocate new buffer")); - goto bad_parse; + if (src == NULL) { + /* There is a case without the uname to the CD-ROM device */ + offset = strchr(dst, ':'); + if (offset) { + if (hvm && !strcmp( offset , ":cdrom")) { + isNoSrcCdrom = 1; + } + offset[0] = '\0'; + } + if (!isNoSrcCdrom) { + virXendError(conn, VIR_ERR_INTERNAL_ERROR, + _("domain information incomplete, vbd has no src")); + goto bad_parse; + } } - strncpy(drvName, src, (offset-src)); - drvName[offset-src] = '\0'; - src = offset + 1; - - if (!strcmp(drvName, "tap")) { + if (!isNoSrcCdrom) { offset = strchr(src, ':'); if (!offset) { virXendError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse vbd filename, missing driver type")); + _("cannot parse vbd filename, missing driver name")); goto bad_parse; } - drvType = malloc((offset-src)+1); - if (!drvType) { + drvName = malloc((offset-src)+1); + if (!drvName) { virXendError(conn, VIR_ERR_NO_MEMORY, _("allocate new buffer")); goto bad_parse; } - strncpy(drvType, src, (offset-src)); - drvType[offset-src] = '\0'; + strncpy(drvName, src, (offset-src)); + drvName[offset-src] = '\0'; + src = offset + 1; - /* Its possible to use blktap driver for block devs - too, but kinda pointless because blkback is better, - so we assume common case here. If blktap becomes - omnipotent, we can revisit this, perhaps stat()'ing - the src file in question */ - isBlock = 0; - } else if (!strcmp(drvName, "phy")) { - isBlock = 1; - } else if (!strcmp(drvName, "file")) { - isBlock = 0; + + if (!strcmp(drvName, "tap")) { + offset = strchr(src, ':'); + if (!offset) { + virXendError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot parse vbd filename, missing driver type")); + goto bad_parse; + } + + drvType = malloc((offset-src)+1); + if (!drvType) { + virXendError(conn, VIR_ERR_NO_MEMORY, + _("allocate new buffer")); + goto bad_parse; + } + strncpy(drvType, src, (offset-src)); + drvType[offset-src] = '\0'; + src = offset + 1; + /* Its possible to use blktap driver for block devs + too, but kinda pointless because blkback is better, + so we assume common case here. If blktap becomes + omnipotent, we can revisit this, perhaps stat()'ing + the src file in question */ + isBlock = 0; + } else if (!strcmp(drvName, "phy")) { + isBlock = 1; + } else if (!strcmp(drvName, "file")) { + isBlock = 0; + } } if (!strncmp(dst, "ioemu:", 6)) @@ -1536,18 +1548,23 @@ xend_parse_sexp_desc(virConnectPtr conn, } } - virBufferVSprintf(&buf, " \n", - isBlock ? "block" : "file", - cdrom ? "cdrom" : "disk"); - if (drvType) { - virBufferVSprintf(&buf, " \n", drvName, drvType); - } else { - virBufferVSprintf(&buf, " \n", drvName); - } - if (isBlock) { - virBufferVSprintf(&buf, " \n", src); + if (!isNoSrcCdrom) { + virBufferVSprintf(&buf, " \n", + isBlock ? "block" : "file", + cdrom ? "cdrom" : "disk"); + if (drvType) { + virBufferVSprintf(&buf, " \n", drvName, drvType); + } else { + virBufferVSprintf(&buf, " \n", drvName); + } + if (isBlock) { + virBufferVSprintf(&buf, " \n", src); + } else { + virBufferVSprintf(&buf, " \n", src); + } } else { - virBufferVSprintf(&buf, " \n", src); + /* This case is the cdrom device only */ + virBufferVSprintf(&buf, " \n"); } virBufferVSprintf(&buf, " \n", dst); Index: src/xml.c =================================================================== RCS file: /data/cvs/libvirt/src/xml.c,v retrieving revision 1.68 diff -u -p -r1.68 xml.c --- src/xml.c 21 Mar 2007 15:24:56 -0000 1.68 +++ src/xml.c 6 Apr 2007 01:27:19 -0000 @@ -691,6 +691,7 @@ virDomainParseXMLDiskDesc(virConnectPtr int shareable = 0; int typ = 0; int cdrom = 0; + int isNoSrcCdrom = 0; type = xmlGetProp(node, BAD_CAST "type"); if (type != NULL) { @@ -730,13 +731,23 @@ virDomainParseXMLDiskDesc(virConnectPtr } if (source == NULL) { - virXMLError(conn, VIR_ERR_NO_SOURCE, (const char *) target, 0); - - if (target != NULL) - xmlFree(target); - if (device != NULL) - xmlFree(device); - return (-1); + /* There is a case without the source + * to the CD-ROM device + */ + if (hvm && + device && + !strcmp((const char *)device, "cdrom")) { + isNoSrcCdrom = 1; + } + if (!isNoSrcCdrom) { + virXMLError(conn, VIR_ERR_NO_SOURCE, (const char *) target, 0); + + if (target != NULL) + xmlFree(target); + if (device != NULL) + xmlFree(device); + return (-1); + } } if (target == NULL) { virXMLError(conn, VIR_ERR_NO_TARGET, (const char *) source, 0); @@ -791,7 +802,7 @@ virDomainParseXMLDiskDesc(virConnectPtr } else virBufferVSprintf(buf, "(dev '%s')", (const char *)target); - if (drvName) { + if (drvName && !isNoSrcCdrom) { if (!strcmp((const char *)drvName, "tap")) { virBufferVSprintf(buf, "(uname '%s:%s:%s')", (const char *)drvName, @@ -802,7 +813,7 @@ virDomainParseXMLDiskDesc(virConnectPtr (const char *)drvName, (const char *)source); } - } else { + } else if (!isNoSrcCdrom) { if (typ == 0) virBufferVSprintf(buf, "(uname 'file:%s')", source); else if (typ == 1) {