[libvirt] [PATCH 0/6] Add new command domiftune
by Hu Tao
This series adds a new command domiftune to get/set parameters of
domain's network interfaces. Supported parameters are bandwidth
settings.
Currently the network interface bandwidth can only be set:
- in domain's xml before the domain is up
- when attaching an interface by attach-interface
With this series, users can change network interface bandwidth
settings using virsh, whether the domain is running or not.
Hu Tao (6):
Add API virDomain{S,G}etInterfaceParameters
virDomain{S,G}etInterfaceParameters: the main entry points
Add virDomain{S,G}etInterfaceparameters support to the remote driver
Add virDomain{S,G}etInterfaceParameters support to qemu driver
Enable the virDomain{S,G}etInterfaceParameters in virsh
Add document for the new command domiftune
daemon/remote.c | 64 ++++++
include/libvirt/libvirt.h.in | 50 +++++
python/generator.py | 2 +
src/driver.h | 12 ++
src/libvirt.c | 118 ++++++++++++
src/libvirt_public.syms | 6 +
src/qemu/qemu_driver.c | 434 ++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 52 +++++
src/remote/remote_protocol.x | 28 +++-
src/remote_protocol-structs | 24 +++
tools/virsh.c | 227 ++++++++++++++++++++++
tools/virsh.pod | 21 ++
12 files changed, 1037 insertions(+), 1 deletions(-)
--
1.7.3.1
13 years
[libvirt] a compilation issue
by Alex Jia
Hi developers,
I met the following compilation issue when I 'git checkout v0.9.8-rc1' tag
then run './configure && make':
<snip>
Copying file ._bootmp/gnulib/lib/netinet_in.in.h
Copying file ._bootmp/gnulib/lib/nonblocking.c
Copying file ._bootmp/gnulib/lib/nonblocking.h
Copying file ._bootmp/gnulib/lib/open.c
.gnulib/gnulib-tool: line 1475: patch: command not found
.gnulib/gnulib-tool: *** patch file gnulib/local/lib/openpty.c.diff didn't apply cleanly
.gnulib/gnulib-tool: *** Stop.
Failed to bootstrap, please investigate.
make: *** [_autogen] Error 1
</snip>
Has any advice about this?
BTW, it's fine when I compiled latest GIT head.
Thanks,
Alex
--------------------------------------------
IRC: #virt, #libvirt-qe, #apac-qa
Phone: +86-10-6260-8185
--------------------------------------------
13 years
[libvirt] [PATCH] Prevent crash of libvirtd when attaching to existing qemu process
by Jim Fehlig
With security_driver set to "none" in /etc/libvirt/qemu.conf,
libvirtd would crash when attempted to attach to an existing
qemu process. Only copy the security model if it actually exists.
---
src/qemu/qemu_process.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9309761..45ed011 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3609,7 +3609,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
if (virSecurityManagerGetProcessLabel(driver->securityManager,
vm, seclabel) < 0)
goto cleanup;
- if (!(vm->def->seclabel.model = strdup(driver->caps->host.secModel.model)))
+ if (driver->caps->host.secModel.model &&
+ !(vm->def->seclabel.model = strdup(driver->caps->host.secModel.model)))
goto no_memory;
if (!(vm->def->seclabel.label = strdup(seclabel->label)))
goto no_memory;
--
1.7.7
13 years
[libvirt] [PATCH 1/2] Fix typo in virDomainResume API doc
by Christophe Fergeau
It's referring to virSuspendDomain instead of
virDomainSuspend.
---
src/libvirt.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 68074e7..9977915 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -2391,7 +2391,7 @@ error:
* @domain: a domain object
*
* Resume a suspended domain, the process is restarted from the state where
- * it was frozen by calling virSuspendDomain().
+ * it was frozen by calling virDomainSuspend().
* This function may require privileged access
*
* Returns 0 in case of success and -1 in case of failure.
--
1.7.7.3
13 years
[libvirt] [PATCH] API: Share code between virConnectOpen functions
by Eduardo Lima (Etrunko)
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
src/libvirt.c | 30 ++----------------------------
1 files changed, 2 insertions(+), 28 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 68074e7..ca7a9a2 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1341,20 +1341,7 @@ failed:
virConnectPtr
virConnectOpen (const char *name)
{
- virConnectPtr ret = NULL;
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
-
- VIR_DEBUG("name=%s", name);
- ret = do_open (name, NULL, 0);
- if (!ret)
- goto error;
- return ret;
-
-error:
- virDispatchError(NULL);
- return NULL;
+ return virConnectOpenAuth(name, NULL, 0);
}
/**
@@ -1375,20 +1362,7 @@ error:
virConnectPtr
virConnectOpenReadOnly(const char *name)
{
- virConnectPtr ret = NULL;
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
-
- VIR_DEBUG("name=%s", name);
- ret = do_open (name, NULL, VIR_CONNECT_RO);
- if (!ret)
- goto error;
- return ret;
-
-error:
- virDispatchError(NULL);
- return NULL;
+ return virConnectOpenAuth(name, NULL, VIR_CONNECT_RO);
}
/**
--
1.7.4.4
13 years
[libvirt] [PATCH] qemu: Ignore shutdown event from destroyed domain
by Jiri Denemark
During virDomainDestroy, QEMU may emit SHUTDOWN event as a response to
SIGTERM and since domain object is still locked, the event is processed
after the domain is destroyed. We need to ignore this event in such case
to avoid changing domain state from shutoff to shutdown.
---
src/qemu/qemu_process.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5e8a20a..9309761 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -471,6 +471,10 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s",
vm->def->name);
goto unlock;
+ } else if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s",
+ vm->def->name);
+ goto unlock;
}
priv->gotShutdown = true;
--
1.7.8
13 years
[libvirt] [libvirt-glib] Add "priority" argument to gvir_stream_add_watch_full
by Christophe Fergeau
This is more consistent with what all the other glib _full APIs
are doing.
---
libvirt-gobject/libvirt-gobject-input-stream.c | 1 +
libvirt-gobject/libvirt-gobject-output-stream.c | 1 +
libvirt-gobject/libvirt-gobject-stream.c | 5 +++++
libvirt-gobject/libvirt-gobject-stream.h | 1 +
4 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-input-stream.c b/libvirt-gobject/libvirt-gobject-input-stream.c
index a890471..6b9f075 100644
--- a/libvirt-gobject/libvirt-gobject-input-stream.c
+++ b/libvirt-gobject/libvirt-gobject-input-stream.c
@@ -161,6 +161,7 @@ static void gvir_input_stream_read_async(GInputStream *stream,
g_return_if_fail(input_stream->priv->result == NULL);
gvir_stream_add_watch_full(input_stream->priv->stream,
+ G_PRIORITY_DEFAULT,
GVIR_STREAM_IO_CONDITION_READABLE,
gvir_input_stream_read_ready,
g_object_ref(stream),
diff --git a/libvirt-gobject/libvirt-gobject-output-stream.c b/libvirt-gobject/libvirt-gobject-output-stream.c
index f70f282..741b2bc 100644
--- a/libvirt-gobject/libvirt-gobject-output-stream.c
+++ b/libvirt-gobject/libvirt-gobject-output-stream.c
@@ -161,6 +161,7 @@ static void gvir_output_stream_write_async(GOutputStream *stream,
g_return_if_fail(output_stream->priv->result == NULL);
gvir_stream_add_watch_full(output_stream->priv->stream,
+ G_PRIORITY_DEFAULT,
GVIR_STREAM_IO_CONDITION_WRITABLE,
gvir_output_stream_write_ready,
g_object_ref(stream),
diff --git a/libvirt-gobject/libvirt-gobject-stream.c b/libvirt-gobject/libvirt-gobject-stream.c
index c1ae765..1e4721f 100644
--- a/libvirt-gobject/libvirt-gobject-stream.c
+++ b/libvirt-gobject/libvirt-gobject-stream.c
@@ -605,6 +605,7 @@ guint gvir_stream_add_watch(GVirStream *stream,
gpointer opaque)
{
return gvir_stream_add_watch_full(stream,
+ G_PRIORITY_DEFAULT,
cond,
func,
opaque,
@@ -612,6 +613,7 @@ guint gvir_stream_add_watch(GVirStream *stream,
}
guint gvir_stream_add_watch_full(GVirStream *stream,
+ gint priority,
GVirStreamIOCondition cond,
GVirStreamIOFunc func,
gpointer opaque,
@@ -625,6 +627,9 @@ guint gvir_stream_add_watch_full(GVirStream *stream,
source->stream = stream;
source->cond = cond;
+ if (priority != G_PRIORITY_DEFAULT)
+ g_source_set_priority((GSource*)source, priority);
+
priv->sources = g_list_append(priv->sources, source);
gvir_stream_update_events(source->stream);
diff --git a/libvirt-gobject/libvirt-gobject-stream.h b/libvirt-gobject/libvirt-gobject-stream.h
index 3caadc3..d3c9347 100644
--- a/libvirt-gobject/libvirt-gobject-stream.h
+++ b/libvirt-gobject/libvirt-gobject-stream.h
@@ -109,6 +109,7 @@ guint gvir_stream_add_watch(GVirStream *stream,
GVirStreamIOFunc func,
gpointer opaque);
guint gvir_stream_add_watch_full(GVirStream *stream,
+ gint priority,
GVirStreamIOCondition cond,
GVirStreamIOFunc func,
gpointer opaque,
--
1.7.7.3
13 years
[libvirt] [PATCH] npiv: Auto-generate WWNs if it's not specified
by Osier Yang
To not change the old API behavior (if no WWNs is specified, error
is throwed and the device creation quits), this patch introduce
an new flag (VIR_NODE_DEVICE_CREATE_XML_GENERATE_WWN), which indicates
the WWNs will be generated automatically by libvirt if they are not
specified, and it's ignored if the the WWNs are specified.
The auto-generated WWN comply with the new addressing schema of WWN:
<quote>
the first nibble is either hex 5 or 6 followed by a 3-byte vendor
identifier and 36 bits for a vendor-specified serial number.
</quote>
We choose hex 5 for the first nibble. And use Qumranet's OUI
(00:1A:4A) as the 3-byte vendor indentifier. The last 36 bits
are auto-generated.
Also new option "--generate-wwn" is introduced for virsh command
"nodedev-create".
---
Perhaps "--generate-wwn" is not good option name, considering
virNodeDeviceCreateXML will support other device type?
---
include/libvirt/libvirt.h.in | 13 +++++
src/conf/node_device_conf.c | 99 +++++++++++++++++++++------------
src/conf/node_device_conf.h | 9 ++-
src/libvirt_private.syms | 1 +
src/node_device/node_device_driver.c | 4 +-
src/qemu/qemu_driver.c | 2 +-
src/test/test_driver.c | 8 ++--
src/util/util.c | 20 +++++++
src/util/util.h | 1 +
tests/nodedevxml2xmltest.c | 2 +-
tools/virsh.c | 7 ++-
tools/virsh.pod | 4 +-
12 files changed, 121 insertions(+), 49 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 2480add..dd3e891 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2270,6 +2270,19 @@ int virNodeDeviceDettach (virNodeDevicePtr dev);
int virNodeDeviceReAttach (virNodeDevicePtr dev);
int virNodeDeviceReset (virNodeDevicePtr dev);
+/**
+ * virNodeDeviceCreateXMLFlags
+ *
+ * Flags OR'ed together to provide specific behaviour when creating a
+ * node device.
+ */
+typedef enum {
+ /* Default behavior */
+ VIR_NODE_DEVICE_CREATE_XML_NONE = 0,
+ /* Generate WWN if no WWN is specified. */
+ VIR_NODE_DEVICE_CREATE_XML_GENERATE_WWN = (1 << 0),
+} virNodeDeviceCreateXMLFlags;
+
virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
const char *xmlDesc,
unsigned int flags);
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 084121f..9d48ff8 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -63,20 +63,13 @@ VIR_ENUM_IMPL(virNodeDevHBACap, VIR_NODE_DEV_CAP_HBA_LAST,
static int
virNodeDevCapsDefParseString(const char *xpath,
xmlXPathContextPtr ctxt,
- char **string,
- virNodeDeviceDefPtr def,
- const char *missing_error_fmt)
+ char **string)
{
char *s;
- s = virXPathString(xpath, ctxt);
- if (s == NULL) {
- virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
- missing_error_fmt,
- def->name);
+ if (!(s = virXPathString(xpath, ctxt)))
return -1;
- }
-
+
*string = s;
return 0;
}
@@ -715,7 +708,8 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt,
virNodeDeviceDefPtr def,
xmlNodePtr node,
union _virNodeDevCapData *data,
- int create)
+ int create,
+ unsigned int flags)
{
xmlNodePtr orignode, *nodes = NULL;
int ret = -1, n = 0, i;
@@ -759,20 +753,46 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt,
orignode2 = ctxt->node;
ctxt->node = nodes[i];
- if (virNodeDevCapsDefParseString("string(./wwnn[1])",
- ctxt,
- &data->scsi_host.wwnn,
- def,
- _("no WWNN supplied for '%s'")) < 0) {
- goto out;
- }
+ if (flags & VIR_NODE_DEVICE_CREATE_XML_GENERATE_WWN) {
+ if (virNodeDevCapsDefParseString("string(./wwnn[1])",
+ ctxt,
+ &data->scsi_host.wwnn) < 0) {
+ if (virGenerateWWN(&data->scsi_host.wwnn) < 0) {
+ virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no WWNN supplied for '%s', and automate "
+ "generation failed"), def->name);
+ goto out;
+ }
+ }
- if (virNodeDevCapsDefParseString("string(./wwpn[1])",
- ctxt,
- &data->scsi_host.wwpn,
- def,
- _("no WWPN supplied for '%s'")) < 0) {
- goto out;
+ if (virNodeDevCapsDefParseString("string(./wwpn[1])",
+ ctxt,
+ &data->scsi_host.wwpn) < 0) {
+ if (virGenerateWWN(&data->scsi_host.wwpn) < 0) {
+ virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no WWPN supplied for '%s', and automate "
+ "generation failed"), def->name);
+ goto out;
+ }
+ }
+ } else {
+ if (virNodeDevCapsDefParseString("string(./wwnn[1])",
+ ctxt,
+ &data->scsi_host.wwnn) < 0) {
+ virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no WWNN supplied for '%s'"),
+ def->name);
+ goto out;
+ }
+
+ if (virNodeDevCapsDefParseString("string(./wwpn[1])",
+ ctxt,
+ &data->scsi_host.wwpn) < 0) {
+ virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no WWPN supplied for '%s'"),
+ def->name);
+ goto out;
+ }
}
ctxt->node = orignode2;
@@ -1058,7 +1078,8 @@ static virNodeDevCapsDefPtr
virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
virNodeDeviceDefPtr def,
xmlNodePtr node,
- int create)
+ int create,
+ unsigned int flags)
{
virNodeDevCapsDefPtr caps;
char *tmp;
@@ -1102,7 +1123,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
ret = virNodeDevCapNetParseXML(ctxt, def, node, &caps->data);
break;
case VIR_NODE_DEV_CAP_SCSI_HOST:
- ret = virNodeDevCapScsiHostParseXML(ctxt, def, node, &caps->data, create);
+ ret = virNodeDevCapScsiHostParseXML(ctxt, def, node, &caps->data, create, flags);
break;
case VIR_NODE_DEV_CAP_SCSI_TARGET:
ret = virNodeDevCapScsiTargetParseXML(ctxt, def, node, &caps->data);
@@ -1131,7 +1152,9 @@ error:
}
static virNodeDeviceDefPtr
-virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create)
+virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt,
+ int create,
+ unsigned int flags)
{
virNodeDeviceDefPtr def;
virNodeDevCapsDefPtr *next_cap;
@@ -1178,7 +1201,7 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create)
next_cap = &def->caps;
for (i = 0 ; i < n ; i++) {
- *next_cap = virNodeDevCapsDefParseXML(ctxt, def, nodes[i], create);
+ *next_cap = virNodeDevCapsDefParseXML(ctxt, def, nodes[i], create, flags);
if (!*next_cap) {
VIR_FREE(nodes);
goto error;
@@ -1198,7 +1221,8 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create)
virNodeDeviceDefPtr
virNodeDeviceDefParseNode(xmlDocPtr xml,
xmlNodePtr root,
- int create)
+ int create,
+ unsigned int flags)
{
xmlXPathContextPtr ctxt = NULL;
virNodeDeviceDefPtr def = NULL;
@@ -1218,7 +1242,7 @@ virNodeDeviceDefParseNode(xmlDocPtr xml,
}
ctxt->node = root;
- def = virNodeDeviceDefParseXML(ctxt, create);
+ def = virNodeDeviceDefParseXML(ctxt, create, flags);
cleanup:
xmlXPathFreeContext(ctxt);
@@ -1228,13 +1252,14 @@ cleanup:
static virNodeDeviceDefPtr
virNodeDeviceDefParse(const char *str,
const char *filename,
- int create)
+ int create,
+ unsigned int flags)
{
xmlDocPtr xml;
virNodeDeviceDefPtr def = NULL;
if ((xml = virXMLParse(filename, str, _("(node_device_definition)")))) {
- def = virNodeDeviceDefParseNode(xml, xmlDocGetRootElement(xml), create);
+ def = virNodeDeviceDefParseNode(xml, xmlDocGetRootElement(xml), create, flags);
xmlFreeDoc(xml);
}
@@ -1243,16 +1268,18 @@ virNodeDeviceDefParse(const char *str,
virNodeDeviceDefPtr
virNodeDeviceDefParseString(const char *str,
- int create)
+ int create,
+ unsigned int flags)
{
- return virNodeDeviceDefParse(str, NULL, create);
+ return virNodeDeviceDefParse(str, NULL, create, flags);
}
virNodeDeviceDefPtr
virNodeDeviceDefParseFile(const char *filename,
- int create)
+ int create,
+ unsigned int flags)
{
- return virNodeDeviceDefParse(NULL, filename, create);
+ return virNodeDeviceDefParse(NULL, filename, create, flags);
}
/*
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index 17be031..e317354 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -233,12 +233,15 @@ void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def);
virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str,
- int create);
+ int create,
+ unsigned int flags);
virNodeDeviceDefPtr virNodeDeviceDefParseFile(const char *filename,
- int create);
+ int create,
+ unsigned int flags);
virNodeDeviceDefPtr virNodeDeviceDefParseNode(xmlDocPtr xml,
xmlNodePtr root,
- int create);
+ int create,
+ unsigned int flags);
int virNodeDeviceGetWWNs(virNodeDeviceDefPtr def,
char **wwnn,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 99a1099..463969d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1101,6 +1101,7 @@ virFileWriteStr;
virFindFileInPath;
virFormatMacAddr;
virGenerateMacAddr;
+virGenerateWWN;
virGetGroupID;
virGetHostname;
virGetUserDirectory;
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index 681655e..ddb1236 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -559,11 +559,11 @@ nodeDeviceCreateXML(virConnectPtr conn,
int parent_host = -1;
virNodeDevicePtr dev = NULL;
- virCheckFlags(0, NULL);
+ virCheckFlags(VIR_NODE_DEVICE_CREATE_XML_GENERATE_WWN, NULL);
nodeDeviceLock(driver);
- def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE);
+ def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, flags);
if (def == NULL) {
goto cleanup;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1e5ed9a..97ed1d2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8747,7 +8747,7 @@ qemudNodeDeviceGetPciInfo (virNodeDevicePtr dev,
if (!xml)
goto out;
- def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE);
+ def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, 0);
if (!def)
goto out;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index ce94a17..b0bf0a3 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -607,7 +607,7 @@ static int testOpenDefault(virConnectPtr conn) {
virStoragePoolObjUnlock(poolobj);
/* Init default node device */
- if (!(nodedef = virNodeDeviceDefParseString(defaultNodeXML, 0)))
+ if (!(nodedef = virNodeDeviceDefParseString(defaultNodeXML, 0, 0)))
goto error;
if (!(nodeobj = virNodeDeviceAssignDef(&privconn->devs,
nodedef))) {
@@ -1056,12 +1056,12 @@ static int testOpenFromFile(virConnectPtr conn,
goto error;
}
- def = virNodeDeviceDefParseFile(absFile, 0);
+ def = virNodeDeviceDefParseFile(absFile, 0, 0);
VIR_FREE(absFile);
if (!def)
goto error;
} else {
- if ((def = virNodeDeviceDefParseNode(xml, devs[i], 0)) == NULL)
+ if ((def = virNodeDeviceDefParseNode(xml, devs[i], 0, 0)) == NULL)
goto error;
}
if (!(dev = virNodeDeviceAssignDef(&privconn->devs, def))) {
@@ -5311,7 +5311,7 @@ testNodeDeviceCreateXML(virConnectPtr conn,
testDriverLock(driver);
- def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE);
+ def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, 0);
if (def == NULL) {
goto cleanup;
}
diff --git a/src/util/util.c b/src/util/util.c
index 6f46d53..e6f4559 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1837,6 +1837,26 @@ void virGenerateMacAddr(const unsigned char *prefix,
addr[5] = virRandom(256);
}
+#define QUMRANET_OUI "001a4a"
+
+int virGenerateWWN(char **wwn) {
+ int suffix[5];
+
+ suffix[0] = virRandom(16);
+ suffix[1] = virRandom(256);
+ suffix[2] = virRandom(256);
+ suffix[3] = virRandom(256);
+ suffix[4] = virRandom(256);
+
+ if (virAsprintf(wwn, "%x%s%x%02x%02x%02x%02x", 0x5, QUMRANET_OUI,
+ suffix[0], suffix[1], suffix[2],
+ suffix[3], suffix[4]) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
int virEnumFromString(const char *const*types,
unsigned int ntypes,
diff --git a/src/util/util.h b/src/util/util.h
index c9c785b..d7a0840 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -186,6 +186,7 @@ void virFormatMacAddr(const unsigned char *addr,
char *str);
void virGenerateMacAddr(const unsigned char *prefix,
unsigned char *addr);
+int virGenerateWWN(char **wwn);
int virDiskNameToIndex(const char* str);
char *virIndexToDiskName(int idx, const char *prefix);
diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
index d0deaeb..3487c7e 100644
--- a/tests/nodedevxml2xmltest.c
+++ b/tests/nodedevxml2xmltest.c
@@ -24,7 +24,7 @@ testCompareXMLToXMLFiles(const char *xml)
if (virtTestLoadFile(xml, &xmlData) < 0)
goto fail;
- if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE)))
+ if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE, 0)))
goto fail;
if (!(actual = virNodeDeviceDefFormat(dev)))
diff --git a/tools/virsh.c b/tools/virsh.c
index d02be5c..ca5b209 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -8351,6 +8351,7 @@ static const vshCmdInfo info_node_device_create[] = {
static const vshCmdOptDef opts_node_device_create[] = {
{"file", VSH_OT_DATA, VSH_OFLAG_REQ,
N_("file containing an XML description of the device")},
+ {"generate-wwn", VSH_OT_BOOL, 0, N_("generate WWN if it's not specified")},
{NULL, 0, 0, NULL}
};
@@ -8361,6 +8362,7 @@ cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd)
const char *from = NULL;
bool ret = true;
char *buffer;
+ unsigned int flags = 0;
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
@@ -8371,7 +8373,10 @@ cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd)
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
return false;
- dev = virNodeDeviceCreateXML(ctl->conn, buffer, 0);
+ if (vshCommandOptBool(cmd, "generate-wwn"))
+ flags |= VIR_NODE_DEVICE_CREATE_XML_GENERATE_WWN;
+
+ dev = virNodeDeviceCreateXML(ctl->conn, buffer, flags);
VIR_FREE(buffer);
if (dev != NULL) {
diff --git a/tools/virsh.pod b/tools/virsh.pod
index fe92714..5130859 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1375,13 +1375,15 @@ reattach, even if the guests use the device in managed mode.
=over 4
-=item B<nodedev-create> I<FILE>
+=item B<nodedev-create> I<FILE> [I<--generate-wwn>]
Create a device on the host node that can then be assigned to virtual
machines. Normally, libvirt is able to automatically determine which
host nodes are available for use, but this allows registration of
host hardware that libvirt did not automatically detect. I<file>
contains xml for a top-level <device> description of a node device.
+I<--generate-wwn> indicates the WWNN and WWPN for a vHBA will be
+generated automatically if they are not specified.
=item B<nodedev-destroy> I<nodedev>
--
1.7.1
13 years