mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Basic domain XML conversions for Xen/QEMU drivers
This commit is contained in:
parent
60d4777190
commit
d8dbd61107
@ -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>
|
||||
|
||||
Remote protocol support for domain XML conversion APIs
|
||||
|
@ -1251,21 +1251,18 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
|
||||
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
||||
{
|
||||
char arg[PATH_MAX];
|
||||
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;
|
||||
}
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -106,6 +106,9 @@ struct _qemudDomainStatus {
|
||||
#define QEMUD_MIGRATION_FIRST_PORT 49152
|
||||
#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...) \
|
||||
virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__, \
|
||||
__FUNCTION__, __LINE__, fmt)
|
||||
|
@ -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,
|
||||
char **const names, int nnames) {
|
||||
struct qemud_driver *driver = conn->privateData;
|
||||
@ -5225,7 +5352,7 @@ static virDriver qemuDriver = {
|
||||
qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
|
||||
qemudDomainDumpXML, /* domainDumpXML */
|
||||
NULL, /* domainXmlFromNative */
|
||||
NULL, /* domainXmlToNative */
|
||||
qemuDomainXMLToNative, /* domainXMLToNative */
|
||||
qemudListDefinedDomains, /* listDefinedDomains */
|
||||
qemudNumDefinedDomains, /* numOfDefinedDomains */
|
||||
qemudDomainStart, /* domainCreate */
|
||||
|
@ -1043,6 +1043,97 @@ xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
|
||||
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
|
||||
xenUnifiedDomainMigratePrepare (virConnectPtr dconn,
|
||||
char **cookie,
|
||||
@ -1580,8 +1671,8 @@ static virDriver xenUnifiedDriver = {
|
||||
NULL, /* domainGetSecurityLabel */
|
||||
NULL, /* nodeGetSecurityModel */
|
||||
xenUnifiedDomainDumpXML, /* domainDumpXML */
|
||||
NULL, /* domainXmlFromNative */
|
||||
NULL, /* domainXmlToNative */
|
||||
xenUnifiedDomainXMLFromNative, /* domainXmlFromNative */
|
||||
xenUnifiedDomainXMLToNative, /* domainXmlToNative */
|
||||
xenUnifiedListDefinedDomains, /* listDefinedDomains */
|
||||
xenUnifiedNumOfDefinedDomains, /* numOfDefinedDomains */
|
||||
xenUnifiedDomainCreate, /* domainCreate */
|
||||
|
@ -46,6 +46,9 @@ extern int xenRegister (void);
|
||||
|
||||
#define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */
|
||||
|
||||
#define XEN_CONFIG_FORMAT_XM "xen-xm"
|
||||
#define XEN_CONFIG_FORMAT_SEXPR "xen-sxpr"
|
||||
|
||||
/* _xenUnifiedDriver:
|
||||
*
|
||||
* Entry points into the underlying Xen drivers. This structure
|
||||
|
Loading…
Reference in New Issue
Block a user