[libvirt] PATCH: update the XML domain RelaxNG schemas
by Daniel Veillard
pritesh raised the issue on IRC, so I checked the schemas against the
current parsing routines and found a few missing items, I also sorted
the device lice to match the enum sequence in the C file.
One thing missing and still TODO is the interface definition block,
the C parser accepts the "server", "client" and "mcast" types but the
RNG doesn't list them in the choice for "interface"
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
15 years, 7 months
[libvirt] PATCH: Fix 2 build bugs on mingw
by Daniel P. Berrange
The Mingw platform lacks readlink(), so we stub out this method on that
platform.
The plain write() implementation of safezero() was not actually doing
anything with the 'offset' arg. This makes it seek to the offset
location before writing data.
The mmap implementation of safezero() was also not quite right, truncating
to len, so if offset was non-zero, it would not be large enough.
Daniel
Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.211
diff -u -p -r1.211 configure.in
--- configure.in 1 Apr 2009 10:40:38 -0000 1.211
+++ configure.in 1 Apr 2009 15:53:35 -0000
@@ -72,7 +72,7 @@ dnl Use --disable-largefile if you don't
AC_SYS_LARGEFILE
dnl Availability of various common functions (non-fatal if missing).
-AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid posix_fallocate mmap])
+AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid posix_fallocate mmap readlink])
dnl Availability of various not common threadsafe functions
AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r])
Index: src/util.c
===================================================================
RCS file: /data/cvs/libvirt/src/util.c,v
retrieving revision 1.98
diff -u -p -r1.98 util.c
--- src/util.c 1 Apr 2009 10:26:22 -0000 1.98
+++ src/util.c 1 Apr 2009 15:53:35 -0000
@@ -136,7 +136,7 @@ int safezero(int fd, int flags ATTRIBUTE
/* memset wants the mmap'ed file to be present on disk so create a
* sparse file
*/
- r = ftruncate(fd, len);
+ r = ftruncate(fd, offset + len);
if (r < 0)
return -errno;
@@ -158,6 +158,9 @@ int safezero(int fd, int flags ATTRIBUTE
char *buf;
unsigned long long remain, bytes;
+ if (lseek(fd, offset, SEEK_SET) < 0)
+ return errno;
+
/* Split up the write in small chunks so as not to allocate lots of RAM */
remain = len;
bytes = 1024 * 1024;
@@ -949,6 +952,7 @@ int virFileLinkPointsTo(const char *chec
int virFileResolveLink(const char *linkpath,
char **resultpath)
{
+#ifdef HAVE_READLINK
struct stat st;
char *buf;
int n;
@@ -981,6 +985,11 @@ int virFileResolveLink(const char *linkp
*resultpath = buf;
return 0;
+#else
+ if (!(*resultpath = strdup(linkpath)))
+ return -ENOMEM;
+ return 0;
+#endif
}
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months
[libvirt] existing bridge and no iptable rules
by Markus
hi,
i try to setup libvirt with an existing network setup (bridge with NO
physical device, routes and iptables are already configured, dhcp named
..) . this bridge should be available for the libvirt domains.
now the problem: every configuration i tried ends in iptable rules
beeing created which mess with my network setup (e.g. i try to route vpn
traffic from a guest to another network outside)
is there a way of defining a virtual network / network source / bridge
for domains that takes an existing bridge and does no setup ( ip,
iptables, .. )?
thanks, markus
15 years, 7 months
[libvirt] error in libvirt.py from libvirt-0.6.1 ?
by Gerrit Slomma
Hello
Is there a paticular reason for having "def migrate" two times in
libvirt.py?
The first occurence is on line 345 with parameters (self, dconn, flags,
dname, uri, bandwidth)
The second occurence is on line 1102 with parameters (self, domain,
flags, dname, uri, bandwidth)
Which one is correct?
And i am no python programmer in the least, but isn't the ret set false?
ret = libvirtmod.virDomainMigrate(domain__o, self._o, flags, dname, uri,
bandwidth)
That doesn't correspond to the def some above this earlier.
diff /tmp/migrate_1st_occurance /tmp/migrate_2nd_occurance
1c1
< def migrate(self, dconn, flags, dname, uri, bandwidth):
---
> def migrate(self, domain, flags, dname, uri, bandwidth):
31,34c31,34
< if dconn is None: dconn__o = None
< else: dconn__o = dconn._o
< ret = libvirtmod.virDomainMigrate(self._o, dconn__o, flags,
dname, uri, bandwidth)
< if ret is None:raise libvirtError('virDomainMigrate() failed',
dom=self)
---
> if domain is None: domain__o = None
> else: domain__o = domain._o
> ret = libvirtmod.virDomainMigrate(domain__o, self._o, flags,
dname, uri, bandwidth)
> if ret is None:raise libvirtError('virDomainMigrate()
failed', conn=self)
15 years, 7 months
[libvirt] [PATCH 0/1] SCSI host pools
by David Allan
Hi All,
Here is reworked SCSI host pool code. I have tested it with FC, iSCSI
and SATA, and it works correctly in all those cases. I have not tried
parallel SCSI, but I don't see any reason why it wouldn't work there
also, as it should be transport independent. This patch is so
different from the earlier revision that a diff from the earlier
version would be pointless, and I have only included a patch against
the current head.
Dave
15 years, 7 months
[libvirt] PATCH: Allow running of console after creating guest
by Daniel P. Berrange
This patch adds a new flag to the 'create' and 'start' commands in
virsh, making it immeditely spawn the builtin virsh console, eg
# virsh start --console demo
At the same time, I also add in a check for virConnectGetHostname() against
the local hostname, and refuse to launch the console if they differ. With
remote hypervisors it is obviously not possible to access the /dev/pts
files directly. Without this check, the console may work by pure luck if
there happens to be a matching device name on the local host. Rather
confusing, and even potentially dangerous.
# virsh -c qemu+ssh://root@demo.example.com/system console someguest
error: Cannot connect to a remote console device
Finally, when starting the console print a message telling the user the
hotkey to quit
# virsh start --console VirtTest
Domain VirtTest started
Connecting to console, type Ctrl+] to quit
Daniel
diff -r a203154020dd src/virsh.c
--- a/src/virsh.c Wed Apr 01 11:57:25 2009 +0100
+++ b/src/virsh.c Wed Apr 01 13:36:40 2009 +0100
@@ -500,20 +500,30 @@ static const vshCmdOptDef opts_console[]
#ifndef __MINGW32__
static int
-cmdConsole(vshControl *ctl, const vshCmd *cmd)
+cmdRunConsole(vshControl *ctl, virDomainPtr dom)
{
xmlDocPtr xml = NULL;
xmlXPathObjectPtr obj = NULL;
xmlXPathContextPtr ctxt = NULL;
- virDomainPtr dom;
int ret = FALSE;
char *doc;
-
- if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
- return FALSE;
-
- if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
- return FALSE;
+ char *thatHost = NULL;
+ char *thisHost = NULL;
+
+ if (!(thisHost = virGetHostname())) {
+ vshError(ctl, FALSE, "%s", _("Failed to get local hostname"));
+ goto cleanup;
+ }
+
+ if (!(thatHost = virConnectGetHostname(ctl->conn))) {
+ vshError(ctl, FALSE, "%s", _("Failed to get connection hostname"));
+ goto cleanup;
+ }
+
+ if (STRNEQ(thisHost, thatHost)) {
+ vshError(ctl, FALSE, "%s", _("Cannot connect to a remote console device"));
+ goto cleanup;
+ }
doc = virDomainGetXMLDesc(dom, 0);
if (!doc)
@@ -532,6 +542,7 @@ cmdConsole(vshControl *ctl, const vshCmd
obj = xmlXPathEval(BAD_CAST "string(/domain/devices/console/@tty)", ctxt);
if ((obj != NULL) && ((obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0))) {
+ vshPrintExtra(ctl, "%s", _("Connecting to console, type Ctrl+] to quit\n"));
if (vshRunConsole((const char *)obj->stringval) == 0)
ret = TRUE;
} else {
@@ -543,14 +554,16 @@ cmdConsole(vshControl *ctl, const vshCmd
xmlXPathFreeContext(ctxt);
if (xml)
xmlFreeDoc(xml);
- virDomainFree(dom);
+ free(thisHost);
+ free(thatHost);
+
return ret;
}
#else /* __MINGW32__ */
static int
-cmdConsole(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+cmdRunConsole(vshControl *ctl, virDomainPtr dom ATTRIBUTE_UNUSED)
{
vshError (ctl, FALSE, "%s", _("console not implemented on this platform"));
return FALSE;
@@ -558,6 +571,24 @@ cmdConsole(vshControl *ctl, const vshCmd
#endif /* __MINGW32__ */
+static int
+cmdConsole(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom;
+ int ret;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return FALSE;
+
+ ret = cmdRunConsole(ctl, dom);
+
+ virDomainFree(dom);
+ return ret;
+}
+
/*
* "list" command
*/
@@ -882,6 +913,7 @@ static const vshCmdInfo info_create[] =
static const vshCmdOptDef opts_create[] = {
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing an XML domain description")},
+ {"console", VSH_OT_BOOL, 0, gettext_noop("attach to console after creation")},
{NULL, 0, 0, NULL}
};
@@ -893,6 +925,7 @@ cmdCreate(vshControl *ctl, const vshCmd
int found;
int ret = TRUE;
char *buffer;
+ int console = vshCommandOptBool(cmd, "console");
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
@@ -910,6 +943,8 @@ cmdCreate(vshControl *ctl, const vshCmd
if (dom != NULL) {
vshPrint(ctl, _("Domain %s created from %s\n"),
virDomainGetName(dom), from);
+ if (console)
+ cmdRunConsole(ctl, dom);
virDomainFree(dom);
} else {
vshError(ctl, FALSE, _("Failed to create domain from %s"), from);
@@ -1030,6 +1065,7 @@ static const vshCmdInfo info_start[] = {
static const vshCmdOptDef opts_start[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the inactive domain")},
+ {"console", VSH_OT_BOOL, 0, gettext_noop("attach to console after creation")},
{NULL, 0, 0, NULL}
};
@@ -1038,6 +1074,7 @@ cmdStart(vshControl *ctl, const vshCmd *
{
virDomainPtr dom;
int ret = TRUE;
+ int console = vshCommandOptBool(cmd, "console");
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
@@ -1054,6 +1091,8 @@ cmdStart(vshControl *ctl, const vshCmd *
if (virDomainCreate(dom) == 0) {
vshPrint(ctl, _("Domain %s started\n"),
virDomainGetName(dom));
+ if (console)
+ cmdRunConsole(ctl, dom);
} else {
vshError(ctl, FALSE, _("Failed to start domain %s"),
virDomainGetName(dom));
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months
[libvirt] PATCH: Fix misc memory alloc/free/usage bugs
by Daniel P. Berrange
A few more small bugs
* src/node_device.c: Don't strdup() a NULL device parent
* src/qemu_conf.c: Don't try to run access() on a NULL binary path
* src/security_selinux.c Make sure result from readlink() is NULL
terminated
* src/storage_conf.c: DOn't free 'mode' while it is still used
diff -r b73fe666feff src/node_device.c
--- a/src/node_device.c Fri Mar 27 16:14:49 2009 +0000
+++ b/src/node_device.c Mon Mar 30 14:37:45 2009 +0100
@@ -176,9 +176,14 @@ static char *nodeDeviceGetParent(virNode
goto cleanup;
}
- ret = strdup(obj->def->parent);
- if (!ret)
- virReportOOMError(dev->conn);
+ if (obj->def->parent) {
+ ret = strdup(obj->def->parent);
+ if (!ret)
+ virReportOOMError(dev->conn);
+ } else {
+ virNodeDeviceReportError(dev->conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("no parent for this device"));
+ }
cleanup:
if (obj)
diff -r b73fe666feff src/qemu_conf.c
--- a/src/qemu_conf.c Fri Mar 27 16:14:49 2009 +0000
+++ b/src/qemu_conf.c Mon Mar 30 14:37:45 2009 +0100
@@ -269,7 +269,7 @@ qemudCapsInitGuest(virCapsPtr caps,
* which can be used with magic cpu choice
*/
hasbase = (access(info->binary, X_OK) == 0);
- hasaltbase = (access(info->altbinary, X_OK) == 0);
+ hasaltbase = (info->altbinary && access(info->altbinary, X_OK) == 0);
/* Can use acceleration for KVM/KQEMU if
* - host & guest arches match
diff -r b73fe666feff src/security_selinux.c
--- a/src/security_selinux.c Fri Mar 27 16:14:49 2009 +0000
+++ b/src/security_selinux.c Mon Mar 30 14:37:45 2009 +0100
@@ -303,11 +303,13 @@ SELinuxRestoreSecurityImageLabel(virConn
return -1;
if (S_ISLNK(buf.st_mode)) {
+ int n;
if (VIR_ALLOC_N(newpath, buf.st_size + 1) < 0)
return -1;
- if (readlink(path, newpath, buf.st_size) < 0)
+ if ((n =readlink(path, newpath, buf.st_size)) < 0)
goto err;
+ buf.st_size[n] = '\0';
path = newpath;
if (stat(path, &buf) != 0)
goto err;
diff -r b73fe666feff src/storage_conf.c
--- a/src/storage_conf.c Fri Mar 27 16:14:49 2009 +0000
+++ b/src/storage_conf.c Mon Mar 30 14:37:45 2009 +0100
@@ -401,12 +401,13 @@ virStorageDefParsePerms(virConnectPtr co
} else {
char *end = NULL;
perms->mode = strtol(mode, &end, 8);
- VIR_FREE(mode);
if (*end || perms->mode < 0 || perms->mode > 0777) {
+ VIR_FREE(mode);
virStorageReportError(conn, VIR_ERR_XML_ERROR,
"%s", _("malformed octal mode"));
goto error;
}
+ VIR_FREE(mode);
}
if (virXPathNode(conn, "./owner", ctxt) == NULL) {
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months
[libvirt] PATCH: Add --tree flag to virsh nodedev-list
by Daniel P. Berrange
The virsh noddev-list command is used to display node devices. It just
prints out their names in a flat list. When detaching devices for purposes
of PCI passthrough though, it is important to understand what devices are
children of the PCI device about to be detached. It is tedious to find
this out, the user having to run virsh nodedev-dumpxml and look at the
parent field.
# virsh -c qemu:///system nodedev-list
computer
DVD_GCC_4247N
net_00_13_02_b9_f9_d3
net_00_13_02_b9_f9_d3_0
net_00_15_58_2f_e9_55
pci_1002_71c4
pci_104c_ac56
pci_8086_27c5_scsi_host
pci_8086_27c5_scsi_host_0
pci_8086_27c5_scsi_host_1
pci_8086_27c5_scsi_host_2
pci_8086_27c5_scsi_host_scsi_device_lun0
pci_8086_27c5_scsi_host_scsi_host
pci_8086_27c8
pci_8086_27da
pci_8086_27df
pci_8086_27df_scsi_host
pci_8086_27df_scsi_host_0
pci_8086_27df_scsi_host_scsi_device_lun0
pci_8086_27df_scsi_host_scsi_host
pci_8086_4227
storage_serial_SATA_HTS721010G9SA00_MPCZ12Y0GNGWSE
usb_device_a5c_2110_noserial_if3
This patch adds a new '--tree' flag to the nodedev-list command, allowing
a prettier format to be used
# virsh -c qemu:///system nodedev-list --tree
computer
|
+-pci_8086_2448
| |
| +-pci_104c_ac56
|
+-pci_8086_27a0
+-pci_8086_27a1
| |
| +-pci_1002_71c4
|
+-pci_8086_27b9
+-pci_8086_27c5
| |
| +-pci_8086_27c5_scsi_host
| | |
| | +-pci_8086_27c5_scsi_host_scsi_device_lun0
| | | |
| | | +-storage_serial_SATA_HTS721010G9SA00_MPCZ12Y0GNGWSE
| | |
| | +-pci_8086_27c5_scsi_host_scsi_host
| |
| +-pci_8086_27c5_scsi_host_0
| +-pci_8086_27c5_scsi_host_1
| +-pci_8086_27c5_scsi_host_2
|
+-pci_8086_27c8
| |
| +-usb_device_1d6b_1_0000_00_1d_0
| |
| +-usb_device_1d6b_1_0000_00_1d_0_if0
|
+-pci_8086_27c9
| |
| +-usb_device_1d6b_1_0000_00_1d_1
| |
| +-usb_device_1d6b_1_0000_00_1d_1_if0
|
+-pci_8086_27ca
| |
| +-usb_device_1d6b_1_0000_00_1d_2
| |
| +-usb_device_1d6b_1_0000_00_1d_2_if0
|
+-pci_8086_27cb
| |
| +-usb_device_1d6b_1_0000_00_1d_3
| |
| +-usb_device_1d6b_1_0000_00_1d_3_if0
| +-usb_device_483_2016_noserial
| | |
| | +-usb_device_483_2016_noserial_if0
| |
| +-usb_device_a5c_2110_noserial
| |
| +-usb_device_a5c_2110_noserial_if0
| +-usb_device_a5c_2110_noserial_if1
| +-usb_device_a5c_2110_noserial_if2
| +-usb_device_a5c_2110_noserial_if3
|
+-pci_8086_27cc
| |
| +-usb_device_1d6b_2_0000_00_1d_7
| |
| +-usb_device_1d6b_2_0000_00_1d_7_if0
|
+-pci_8086_27d0
| |
| +-pci_8086_109a
| |
| +-net_00_15_58_2f_e9_55
|
+-pci_8086_27d2
| |
| +-pci_8086_4227
| |
| +-net_00_13_02_b9_f9_d3
| +-net_00_13_02_b9_f9_d3_0
|
+-pci_8086_27d4
+-pci_8086_27d6
+-pci_8086_27d8
+-pci_8086_27da
+-pci_8086_27df
|
+-pci_8086_27df_scsi_host
| |
| +-pci_8086_27df_scsi_host_scsi_device_lun0
| | |
| | +-DVD_GCC_4247N
| |
| +-pci_8086_27df_scsi_host_scsi_host
|
+-pci_8086_27df_scsi_host_0
Daniel
diff -r b73fe666feff src/virsh.c
--- a/src/virsh.c Fri Mar 27 16:14:49 2009 +0000
+++ b/src/virsh.c Mon Mar 30 14:37:45 2009 +0100
@@ -4391,16 +4391,77 @@ static const vshCmdInfo info_node_list_d
};
static const vshCmdOptDef opts_node_list_devices[] = {
+ {"tree", VSH_OT_BOOL, 0, gettext_noop("list devices in a tree")},
{"cap", VSH_OT_STRING, VSH_OFLAG_NONE, gettext_noop("capability name")},
{NULL, 0, 0, NULL}
};
+#define MAX_INDENT 100
+
+static void
+cmdNodeListDevicesPrint(vshControl *ctl,
+ char **devices,
+ char **parents,
+ int num_devices,
+ int devid,
+ int lastdev,
+ unsigned int depth,
+ char *indent)
+{
+ int i;
+ int nextlastdev = -1;
+
+ if (depth) {
+ indent[depth] = '+';
+ indent[depth+1] = '-';
+ }
+
+ vshPrint(ctl, indent);
+ if (depth) {
+ if (devid == lastdev)
+ indent[depth] = ' ';
+ else
+ indent[depth] = '|';
+ indent[depth+1] = ' ';
+ depth+=2;
+ }
+ vshPrint(ctl, "%s\n", devices[devid]);
+
+ for (i = 0 ; i < num_devices ; i++) {
+ if (parents[i] &&
+ STREQ(parents[i], devices[devid])) {
+ //fprintf(stderr, "%s %s %d %d\n", parents[i], devices[devid], i, devid);
+ nextlastdev = i;
+ }
+ }
+
+ if (nextlastdev != -1) {
+ vshPrint(ctl, indent);
+ vshPrint(ctl, " |\n");
+ }
+
+ indent[depth] = ' ';
+ for (i = 0 ; i < num_devices ; i++) {
+ indent[depth] = ' ';
+ indent[depth+1] = ' ';
+ if (parents[i] &&
+ STREQ(parents[i], devices[devid]))
+ cmdNodeListDevicesPrint(ctl, devices, parents, num_devices, i, nextlastdev, depth + 2, indent);
+ indent[depth] = '\0';
+ }
+ if (nextlastdev == -1 && devid == lastdev) {
+ vshPrint(ctl, indent);
+ vshPrint(ctl, "\n");
+ }
+}
+
static int
cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
char *cap;
char **devices;
int found, num_devices, i;
+ int tree = vshCommandOptBool(cmd, "tree");
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
@@ -4426,9 +4487,39 @@ cmdNodeListDevices (vshControl *ctl, con
return FALSE;
}
qsort(&devices[0], num_devices, sizeof(char*), namesorter);
- for (i = 0; i < num_devices; i++) {
- vshPrint(ctl, "%s\n", devices[i]);
- free(devices[i]);
+ if (tree) {
+ char indent[MAX_INDENT];
+ char **parents = vshMalloc(ctl, sizeof(char *) * num_devices);
+ for (i = 0; i < num_devices; i++) {
+ virNodeDevicePtr dev = virNodeDeviceLookupByName(ctl->conn, devices[i]);
+ if (dev && STRNEQ(devices[i], "computer")) {
+ const char *parent = virNodeDeviceGetParent(dev);
+ parents[i] = parent ? strdup(parent) : NULL;
+ } else {
+ parents[i] = NULL;
+ }
+ virNodeDeviceFree(dev);
+ }
+ for (i = 0 ; i < num_devices ; i++) {
+ memset(indent, '\0', sizeof indent);
+ if (parents[i] == NULL)
+ cmdNodeListDevicesPrint(ctl,
+ devices,
+ parents,
+ num_devices,
+ i,
+ i,
+ 0,
+ indent);
+ }
+ for (i = 0 ; i < num_devices ; i++)
+ free(parents[i]);
+ free(parents);
+ } else {
+ for (i = 0; i < num_devices; i++) {
+ vshPrint(ctl, "%s\n", devices[i]);
+ free(devices[i]);
+ }
}
free(devices);
return TRUE;
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months