From: Daniel P. Berrange Date: Fri, 19 Jan 2007 20:23:37 +0000 (+0000) Subject: Finished off XML parsing & XM config file generation for all supported guest configs X-Git-Tag: LIBVIRT_0_1_11~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b0f541704d0172fdbc4c0e075b37dc2e196d4cc;p=thirdparty%2Flibvirt.git Finished off XML parsing & XM config file generation for all supported guest configs --- diff --git a/ChangeLog b/ChangeLog index ce4ec79075..5a92b114a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jan 19 15:23:13 EST 2007 Daniel Berrange + + * src/xm_internal.c: Finished off the conversion from XML + to XM config files, and the reverse, to deal with all known + libvirt guest config options. + Fri Jan 19 15:07:13 EST 2007 Daniel Berrange * src/conf.c: Free stored config parameters, when free'ing diff --git a/src/xm_internal.c b/src/xm_internal.c index 4b37c702d3..e60fd1827e 100644 --- a/src/xm_internal.c +++ b/src/xm_internal.c @@ -1,13 +1,25 @@ /* * xm_internal.h: helper routines for dealing with inactive domains * - * Copyright (C) 2006 + * Copyright (C) 2006-2007 Red Hat + * Copyright (C) 2006 Daniel P. Berrange * - * Daniel Berrange + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Daniel P. Berrange * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file COPYING.LIB in the main directory of this - * archive for more details. */ #include @@ -493,7 +505,7 @@ int xenXMClose(virConnectPtr conn ATTRIBUTE_UNUSED) { return (0); } -/* +/* * Our backend type */ const char *xenXMGetType(virConnectPtr conn ATTRIBUTE_UNUSED) { @@ -502,7 +514,7 @@ const char *xenXMGetType(virConnectPtr conn ATTRIBUTE_UNUSED) { /* * Since these are all offline domains, we only return info about - * VCPUs and memory. + * VCPUs and memory. */ int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) { const char *filename; @@ -548,14 +560,13 @@ int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) { } +#define MAX_VFB 1024 /* * Turn a config record into a lump of XML describing the * domain, suitable for later feeding for virDomainCreateLinux */ -char *xenXMDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) { +char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf) { virBufferPtr buf; - const char *filename; - xenXMConfCachePtr entry; char *xml; const char *name; unsigned char uuid[16]; @@ -563,24 +574,16 @@ char *xenXMDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) { int hvm = 0; long val; virConfValuePtr list; - - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { - xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, - __FUNCTION__); - return(NULL); - } - if (domain->handle != -1) - return (NULL); - - if (!(filename = virHashLookup(nameConfigMap, domain->name))) - return (NULL); - - if (!(entry = virHashLookup(configCache, filename))) - return (NULL); - - if (xenXMConfigGetString(entry->conf, "name", &name) < 0) + int vnc = 0, sdl = 0; + char vfb[MAX_VFB]; + long vncdisplay; + long vncunused = 1; + const char *vnclisten = NULL; + const char *vncpasswd = NULL; + + if (xenXMConfigGetString(conf, "name", &name) < 0) return (NULL); - if (xenXMConfigGetUUID(entry->conf, "uuid", uuid) < 0) + if (xenXMConfigGetUUID(conf, "uuid", uuid) < 0) return (NULL); buf = virBufferNew(4096); @@ -594,64 +597,93 @@ char *xenXMDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) { uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); - if ((xenXMConfigGetString(entry->conf, "builder", &str) == 0) && + if ((xenXMConfigGetString(conf, "builder", &str) == 0) && !strcmp(str, "hvm")) hvm = 1; if (hvm) { + const char *boot; virBufferAdd(buf, " \n", -1); virBufferAdd(buf, " hvm\n", -1); - if (xenXMConfigGetString(entry->conf, "kernel", &str) == 0) + if (xenXMConfigGetString(conf, "kernel", &str) == 0) virBufferVSprintf(buf, " %s\n", str); + + if (xenXMConfigGetString(conf, "boot", &boot) < 0) + boot = "c"; + + while (*boot) { + const char *dev; + switch (*boot) { + case 'a': + dev = "fd"; + break; + case 'd': + dev = "cdrom"; + break; + case 'c': + default: + dev = "hd"; + break; + } + virBufferVSprintf(buf, " %s\n", dev); + boot++; + } + virBufferAdd(buf, " \n", -1); } else { - if (xenXMConfigGetString(entry->conf, "bootloader", &str) == 0) + if (xenXMConfigGetString(conf, "bootloader", &str) == 0) virBufferVSprintf(buf, " %s\n", str); - if (xenXMConfigGetString(entry->conf, "kernel", &str) == 0) { + if (xenXMConfigGetString(conf, "kernel", &str) == 0) { virBufferAdd(buf, " \n", -1); virBufferAdd(buf, " linux\n", -1); virBufferVSprintf(buf, " %s\n", str); - if (xenXMConfigGetString(entry->conf, "ramdisk", &str) == 0) + if (xenXMConfigGetString(conf, "ramdisk", &str) == 0) virBufferVSprintf(buf, " %s\n", str); - if (xenXMConfigGetString(entry->conf, "extra", &str) == 0) + if (xenXMConfigGetString(conf, "extra", &str) == 0) virBufferVSprintf(buf, " %s\n", str); virBufferAdd(buf, " \n", -1); } } - if (xenXMConfigGetInt(entry->conf, "memory", &val) < 0) + if (xenXMConfigGetInt(conf, "memory", &val) < 0) val = 64; + virBufferVSprintf(buf, " %ld\n", val * 1024); + + if (xenXMConfigGetInt(conf, "maxmem", &val) < 0) + if (xenXMConfigGetInt(conf, "memory", &val) < 0) + val = 64; virBufferVSprintf(buf, " %ld\n", val * 1024); - if (xenXMConfigGetInt(entry->conf, "vcpus", &val) < 0) + + if (xenXMConfigGetInt(conf, "vcpus", &val) < 0) val = 1; virBufferVSprintf(buf, " %ld\n", val); - if (xenXMConfigGetString(entry->conf, "on_poweroff", &str) < 0) + if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0) str = "destroy"; virBufferVSprintf(buf, " %s\n", str); - if (xenXMConfigGetString(entry->conf, "on_reboot", &str) < 0) + if (xenXMConfigGetString(conf, "on_reboot", &str) < 0) str = "restart"; virBufferVSprintf(buf, " %s\n", str); - if (xenXMConfigGetString(entry->conf, "on_crash", &str) < 0) + if (xenXMConfigGetString(conf, "on_crash", &str) < 0) str = "restart"; virBufferVSprintf(buf, " %s\n", str); if (hvm) { virBufferAdd(buf, " \n", -1); - if (xenXMConfigGetInt(entry->conf, "pae", &val) == 0 && + if (xenXMConfigGetInt(conf, "pae", &val) == 0 && val) virBufferAdd(buf, " \n", -1); - if (xenXMConfigGetInt(entry->conf, "acpi", &val) == 0 && + if (xenXMConfigGetInt(conf, "acpi", &val) == 0 && val) virBufferAdd(buf, " \n", -1); - if (xenXMConfigGetInt(entry->conf, "apic", &val) == 0 && + if (xenXMConfigGetInt(conf, "apic", &val) == 0 && val) virBufferAdd(buf, " \n", -1); virBufferAdd(buf, " \n", -1); @@ -660,167 +692,283 @@ char *xenXMDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) { virBufferAdd(buf, " \n", -1); if (hvm) { - if (xenXMConfigGetString(entry->conf, "device_model", &str) == 0) + if (xenXMConfigGetString(conf, "device_model", &str) == 0) virBufferVSprintf(buf, " %s\n", str); } - list = virConfGetValue(entry->conf, "disk"); - while (list && list->type == VIR_CONF_LIST) { - virConfValuePtr el = list->list; - int block = 0; - char dev[NAME_MAX]; - char src[PATH_MAX]; - char drvName[NAME_MAX] = ""; - char drvType[NAME_MAX] = ""; - char *device; - char *mode; - char *path; - - if ((el== NULL) || (el->type != VIR_CONF_STRING) || (el->str == NULL)) - goto skipdisk; - - if (!(device = index(el->str, ',')) || device[0] == '\0') - goto skipdisk; - device++; - if (!(mode = index(device, ',')) || mode[0] == '\0') - goto skipdisk; - mode++; - - if (!(path = index(el->str, ':')) || path[0] == '\0' || path > device) - goto skipdisk; - - strncpy(drvName, el->str, (path-el->str)); - if (!strcmp(drvName, "tap")) { - if (!(path = index(el->str+4, ':')) || path[0] == '\0' || path > device) + list = virConfGetValue(conf, "disk"); + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + int block = 0; + int cdrom = 0; + char src[PATH_MAX]; + char dev[NAME_MAX]; + char drvName[NAME_MAX] = ""; + char drvType[NAME_MAX] = ""; + char *head; + char *offset; + char *tmp, *tmp1; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipdisk; + head = list->str; + + /* + * Disks have 3 components, SOURCE,DEST-DEVICE,MODE + * eg, phy:/dev/HostVG/XenGuest1,xvda,w + * The SOURCE is usually prefixed with a driver type, + * and optionally driver sub-type + * The DEST-DEVICE is optionally post-fixed with disk type + */ + + /* Extract the source */ + if (!(offset = index(head, ',')) || offset[0] == '\0') goto skipdisk; + if ((offset - head) >= (PATH_MAX-1)) + goto skipdisk; + strncpy(src, head, (offset - head)); + src[(offset-head)] = '\0'; + head = offset + 1; - strncpy(drvType, el->str+4, (path-(el->str+4))); - } - if ((device-path) > PATH_MAX) - goto skipdisk; + /* Extract the dest */ + if (!(offset = index(head, ',')) || offset[0] == '\0') + goto skipdisk; + if ((offset - head) >= (PATH_MAX-1)) + goto skipdisk; + strncpy(dev, head, (offset - head)); + dev[(offset-head)] = '\0'; + head = offset + 1; - strncpy(src, path+1, (device-(path+1))-1); - src[(device-(path+1))-1] = '\0'; - if (!strcmp(drvName, "phy")) { - block = 1; - } + /* Extract source driver type */ + if (!(tmp = index(src, ':')) || !tmp[0]) + goto skipdisk; + strncpy(drvName, src, (tmp-src)); + drvName[tmp-src] = '\0'; + + /* And the source driver sub-type */ + if (!strncmp(drvName, "tap", 3)) { + if (!(tmp1 = index(tmp+1, ':')) || !tmp1[0]) + goto skipdisk; + strncpy(drvType, tmp+1, (tmp1-(tmp+1))); + memmove(src, src+(tmp1-src)+1, strlen(src)-(tmp1-src)); + } else { + drvType[0] = '\0'; + memmove(src, src+(tmp-src)+1, strlen(src)-(tmp-src)); + } - if ((mode-device-1) > (NAME_MAX-1)) { - goto skipdisk; - } - strncpy(dev, device, (mode-device-1)); - dev[(mode-device-1)] = '\0'; + /* phy: type indicates a block device */ + if (!strcmp(drvName, "phy")) { + block = 1; + } - virBufferVSprintf(buf, " \n", block ? "block" : "file"); - if (drvType[0]) - virBufferVSprintf(buf, " \n", drvName, drvType); - else - virBufferVSprintf(buf, " \n", drvName); - virBufferVSprintf(buf, " \n", block ? "dev" : "file", src); - virBufferVSprintf(buf, " \n", dev); - if (*mode == 'r') - virBufferAdd(buf, " \n", -1); - virBufferAdd(buf, " \n", -1); + /* Remove legacy ioemu: junk */ + if (!strncmp(dev, "ioemu:", 6)) { + memmove(dev, dev+6, strlen(dev)-5); + } + + /* Check for a :cdrom/:disk postfix */ + if ((tmp = index(dev, ':')) != NULL) { + if (!strcmp(tmp, ":cdrom")) + cdrom = 1; + tmp[0] = '\0'; + } - skipdisk: - list = list->next; + virBufferVSprintf(buf, " \n", + block ? "block" : "file", + cdrom ? "cdrom" : "disk"); + if (drvType[0]) + virBufferVSprintf(buf, " \n", drvName, drvType); + else + virBufferVSprintf(buf, " \n", drvName); + virBufferVSprintf(buf, " \n", block ? "dev" : "file", src); + virBufferVSprintf(buf, " \n", dev); + if (!strcmp(head, "r") || + !strcmp(head, "ro")) + virBufferAdd(buf, " \n", -1); + virBufferAdd(buf, " \n", -1); + + skipdisk: + list = list->next; + } } - list = virConfGetValue(entry->conf, "vif"); - while (list && list->type == VIR_CONF_LIST) { - virConfValuePtr el = list->list; - int type = -1; - char script[PATH_MAX]; - char ip[16]; - char mac[18]; - char *key; + if (hvm && conn->xendConfigVersion == 1) { + if (xenXMConfigGetString(conf, "cdrom", &str) == 0) { + virBufferAdd(buf, " \n", -1); + virBufferAdd(buf, " \n", -1); + virBufferVSprintf(buf, " \n", str); + virBufferAdd(buf, " \n", -1); + virBufferAdd(buf, " \n", -1); + virBufferAdd(buf, " \n", -1); + } + } - mac[0] = '\0'; - script[0] = '\0'; - ip[0] = '\0'; + list = virConfGetValue(conf, "vif"); + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + int type = -1; + char script[PATH_MAX]; + char ip[16]; + char mac[18]; + char *key; + + mac[0] = '\0'; + script[0] = '\0'; + ip[0] = '\0'; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipnic; - if ((el== NULL) || (el->type != VIR_CONF_STRING) || (el->str == NULL)) - goto skipnic; + key = list->str; + while (key) { + char *data; + char *nextkey = index(key, ','); + + if (!(data = index(key, '=')) || (data[0] == '\0')) + goto skipnic; + data++; + + if (!strncmp(key, "mac=", 4)) { + int len = nextkey ? (nextkey - data) : 17; + if (len > 17) + len = 17; + strncpy(mac, data, len); + mac[len] = '\0'; + } else if (!strncmp(key, "bridge=", 7)) { + type = 1; + } else if (!strncmp(key, "script=", 7)) { + int len = nextkey ? (nextkey - data) : PATH_MAX-1; + if (len > (PATH_MAX-1)) + len = PATH_MAX-1; + strncpy(script, data, len); + script[len] = '\0'; + } else if (!strncmp(key, "ip=", 3)) { + int len = nextkey ? (nextkey - data) : 15; + if (len > 15) + len = 15; + strncpy(ip, data, len); + ip[len] = '\0'; + } - key = el->str; - while (key) { - char *data; - char *nextkey = index(key, ','); + while (nextkey && (nextkey[0] == ',' || + nextkey[0] == ' ' || + nextkey[0] == '\t')) + nextkey++; + key = nextkey; + } - if (!(data = index(key, '=')) || (data[0] == '\0')) - goto skipnic; - data++; - - if (!strncmp(key, "mac=", 4)) { - int len = nextkey ? (nextkey - data) : 17; - if (len > 17) - len = 17; - strncpy(mac, data, len); - mac[len] = '\0'; - } else if (!strncmp(key, "bridge=", 7)) { + /* XXX Forcing to pretend its a bridge */ + if (type == -1) { type = 1; - } else if (!strncmp(key, "script=", 7)) { - int len = nextkey ? (nextkey - data) : PATH_MAX-1; - if (len > (PATH_MAX-1)) - len = PATH_MAX-1; - strncpy(script, data, len); - script[len] = '\0'; - } else if (!strncmp(key, "ip=", 3)) { - int len = nextkey ? (nextkey - data) : 15; - if (len > 15) - len = 15; - strncpy(ip, data, len); - ip[len] = '\0'; } - while (nextkey && (nextkey[0] == ',' || - nextkey[0] == ' ' || - nextkey[0] == '\t')) - nextkey++; - key = nextkey; + virBufferAdd(buf, " \n", -1); + if (mac[0]) + virBufferVSprintf(buf, " \n", mac); + if (script[0]) + virBufferVSprintf(buf, "