Basic domain XML conversions for Xen/QEMU drivers

This commit is contained in:
Daniel P. Berrange 2009-05-21 14:14:01 +00:00
parent 60d4777190
commit d8dbd61107
6 changed files with 246 additions and 17 deletions

View File

@ -1,3 +1,11 @@
Thu May 21 14:59:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Basic domain XML conversions
* src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c: Wire up
API for conversion from XML to native argv
* src/xen_unified.c, src/xen_unified.h: Wire up API for domain
XML conversions to & from native
Thu May 21 14:48:22 BST 2009 Daniel P. Berrange <berrange@redhat.com> Thu May 21 14:48:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Remote protocol support for domain XML conversion APIs Remote protocol support for domain XML conversion APIs

View File

@ -1251,21 +1251,18 @@ int qemudBuildCommandLine(virConnectPtr conn,
case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_ETHERNET:
{ {
char arg[PATH_MAX]; virBuffer buf = VIR_BUFFER_INITIALIZER;
if (net->ifname) {
if (snprintf(arg, PATH_MAX-1, "tap,ifname=%s,script=%s,vlan=%d",
net->ifname,
net->data.ethernet.script,
vlan) >= (PATH_MAX-1))
goto error;
} else {
if (snprintf(arg, PATH_MAX-1, "tap,script=%s,vlan=%d",
net->data.ethernet.script,
vlan) >= (PATH_MAX-1))
goto error;
}
ADD_ARG_LIT(arg); virBufferAddLit(&buf, "tap");
if (net->ifname)
virBufferVSprintf(&buf, ",ifname=%s", net->ifname);
if (net->data.ethernet.script)
virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
virBufferVSprintf(&buf, ",vlan=%d", vlan);
if (virBufferError(&buf))
goto error;
ADD_ARG(virBufferContentAndReset(&buf));
} }
break; break;

View File

@ -106,6 +106,9 @@ struct _qemudDomainStatus {
#define QEMUD_MIGRATION_FIRST_PORT 49152 #define QEMUD_MIGRATION_FIRST_PORT 49152
#define QEMUD_MIGRATION_NUM_PORTS 64 #define QEMUD_MIGRATION_NUM_PORTS 64
/* Config type for XML import/export conversions */
#define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
#define qemudReportError(conn, dom, net, code, fmt...) \ #define qemudReportError(conn, dom, net, code, fmt...) \
virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__, \ virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__, \
__FUNCTION__, __LINE__, fmt) __FUNCTION__, __LINE__, fmt)

View File

@ -3422,6 +3422,133 @@ cleanup:
} }
static char *qemuDomainXMLToNative(virConnectPtr conn,
const char *format,
const char *xmlData,
unsigned int flags ATTRIBUTE_UNUSED) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def = NULL;
const char *emulator;
unsigned int qemuCmdFlags;
struct stat sb;
const char **retargv = NULL;
const char **retenv = NULL;
const char **tmp;
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *ret = NULL;
int i;
if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_ARG,
_("unsupported config type %s"), format);
goto cleanup;
}
def = virDomainDefParseString(conn, driver->caps, xmlData, 0);
if (!def)
goto cleanup;
/* Since we're just exporting args, we can't do bridge/network
* setups, since libvirt will normally create TAP devices
* directly. We convert those configs into generic 'ethernet'
* config and assume the user has suitable 'ifup-qemu' scripts
*/
for (i = 0 ; i < def->nnets ; i++) {
virDomainNetDefPtr net = def->nets[i];
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
VIR_FREE(net->data.network.name);
memset(net, 0, sizeof *net);
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
net->data.ethernet.dev = NULL;
net->data.ethernet.script = NULL;
net->data.ethernet.ipaddr = NULL;
} else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
char *brname = net->data.bridge.brname;
char *script = net->data.bridge.script;
char *ipaddr = net->data.bridge.ipaddr;
memset(net, 0, sizeof *net);
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
net->data.ethernet.dev = brname;
net->data.ethernet.script = script;
net->data.ethernet.ipaddr = ipaddr;
}
}
for (i = 0 ; i < def->ngraphics ; i++) {
if (def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
def->graphics[i]->data.vnc.autoport)
def->graphics[i]->data.vnc.port = 5900;
}
emulator = def->emulator;
if (!emulator)
emulator = virDomainDefDefaultEmulator(conn, def, driver->caps);
if (!emulator)
goto cleanup;
/* Make sure the binary we are about to try exec'ing exists.
* Technically we could catch the exec() failure, but that's
* in a sub-process so its hard to feed back a useful error
*/
if (stat(emulator, &sb) < 0) {
virReportSystemError(conn, errno,
_("Cannot find QEMU binary %s"),
emulator);
goto cleanup;
}
if (qemudExtractVersionInfo(emulator,
NULL,
&qemuCmdFlags) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("Cannot determine QEMU argv syntax %s"),
emulator);
goto cleanup;
}
if (qemudBuildCommandLine(conn, driver, def,
qemuCmdFlags,
&retargv, &retenv,
NULL, NULL, /* Don't want it to create TAP devices */
NULL) < 0) {
goto cleanup;
}
tmp = retenv;
while (*tmp) {
virBufferAdd(&buf, *tmp, strlen(*tmp));
virBufferAddLit(&buf, " ");
tmp++;
}
tmp = retargv;
while (*tmp) {
virBufferAdd(&buf, *tmp, strlen(*tmp));
virBufferAddLit(&buf, " ");
tmp++;
}
if (virBufferError(&buf))
goto cleanup;
ret = virBufferContentAndReset(&buf);
cleanup:
for (tmp = retargv ; tmp && *tmp ; tmp++)
VIR_FREE(*tmp);
VIR_FREE(retargv);
for (tmp = retenv ; tmp && *tmp ; tmp++)
VIR_FREE(*tmp);
VIR_FREE(retenv);
virDomainDefFree(def);
return ret;
}
static int qemudListDefinedDomains(virConnectPtr conn, static int qemudListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
@ -5225,7 +5352,7 @@ static virDriver qemuDriver = {
qemudNodeGetSecurityModel, /* nodeGetSecurityModel */ qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
qemudDomainDumpXML, /* domainDumpXML */ qemudDomainDumpXML, /* domainDumpXML */
NULL, /* domainXmlFromNative */ NULL, /* domainXmlFromNative */
NULL, /* domainXmlToNative */ qemuDomainXMLToNative, /* domainXMLToNative */
qemudListDefinedDomains, /* listDefinedDomains */ qemudListDefinedDomains, /* listDefinedDomains */
qemudNumDefinedDomains, /* numOfDefinedDomains */ qemudNumDefinedDomains, /* numOfDefinedDomains */
qemudDomainStart, /* domainCreate */ qemudDomainStart, /* domainCreate */

View File

@ -1043,6 +1043,97 @@ xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
return NULL; return NULL;
} }
static char *
xenUnifiedDomainXMLFromNative(virConnectPtr conn,
const char *format,
const char *config,
unsigned int flags ATTRIBUTE_UNUSED)
{
virDomainDefPtr def = NULL;
char *ret = NULL;
virConfPtr conf = NULL;
GET_PRIVATE(conn);
if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
_("unsupported config type %s"), format);
return NULL;
}
if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
conf = virConfReadMem(config, strlen(config));
if (!conf)
goto cleanup;
def = xenXMDomainConfigParse(conn, conf);
} else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
def = xenDaemonParseSxprString(conn, config, priv->xendConfigVersion);
}
if (!def)
goto cleanup;
ret = virDomainDefFormat(conn, def, 0);
cleanup:
virDomainDefFree(def);
return ret;
}
#define MAX_CONFIG_SIZE (1024 * 65)
static char *
xenUnifiedDomainXMLToNative(virConnectPtr conn,
const char *format,
const char *xmlData,
unsigned int flags ATTRIBUTE_UNUSED)
{
virDomainDefPtr def = NULL;
char *ret = NULL;
virConfPtr conf = NULL;
GET_PRIVATE(conn);
if (STRNEQ(format, XEN_CONFIG_FORMAT_XM) &&
STRNEQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
xenUnifiedError(conn, VIR_ERR_INVALID_ARG,
_("unsupported config type %s"), format);
goto cleanup;
}
if (!(def = virDomainDefParseString(conn,
priv->caps,
xmlData,
0)))
goto cleanup;
if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
int len = MAX_CONFIG_SIZE;
conf = xenXMDomainConfigFormat(conn, def);
if (!conf)
goto cleanup;
if (VIR_ALLOC_N(ret, len) < 0) {
virReportOOMError(conn);
goto cleanup;
}
if (virConfWriteMem(ret, &len, conf) < 0) {
VIR_FREE(ret);
goto cleanup;
}
} else if (STREQ(format, XEN_CONFIG_FORMAT_SEXPR)) {
ret = xenDaemonFormatSxpr(conn, def, priv->xendConfigVersion);
}
cleanup:
virDomainDefFree(def);
if (conf)
virConfFree(conf);
return ret;
}
static int static int
xenUnifiedDomainMigratePrepare (virConnectPtr dconn, xenUnifiedDomainMigratePrepare (virConnectPtr dconn,
char **cookie, char **cookie,
@ -1580,8 +1671,8 @@ static virDriver xenUnifiedDriver = {
NULL, /* domainGetSecurityLabel */ NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */ NULL, /* nodeGetSecurityModel */
xenUnifiedDomainDumpXML, /* domainDumpXML */ xenUnifiedDomainDumpXML, /* domainDumpXML */
NULL, /* domainXmlFromNative */ xenUnifiedDomainXMLFromNative, /* domainXmlFromNative */
NULL, /* domainXmlToNative */ xenUnifiedDomainXMLToNative, /* domainXmlToNative */
xenUnifiedListDefinedDomains, /* listDefinedDomains */ xenUnifiedListDefinedDomains, /* listDefinedDomains */
xenUnifiedNumOfDefinedDomains, /* numOfDefinedDomains */ xenUnifiedNumOfDefinedDomains, /* numOfDefinedDomains */
xenUnifiedDomainCreate, /* domainCreate */ xenUnifiedDomainCreate, /* domainCreate */

View File

@ -46,6 +46,9 @@ extern int xenRegister (void);
#define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */ #define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */
#define XEN_CONFIG_FORMAT_XM "xen-xm"
#define XEN_CONFIG_FORMAT_SEXPR "xen-sxpr"
/* _xenUnifiedDriver: /* _xenUnifiedDriver:
* *
* Entry points into the underlying Xen drivers. This structure * Entry points into the underlying Xen drivers. This structure