mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 01:43:23 +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>
|
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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user