[libvirt] [PATCH v2 2/2] Implement SCSI disk unplugging

2010-05-05 Thread Wolfgang Mauerer
With the introduction of the generic qemu device model, unplugging
SCSI disks works like a charm, so support it in libvirt.

* src/qemu/qemu_driver.c: Add qemudDomainDetachSCSIDiskDevice() to do the
  unplugging, extend qemudDomainDetachDeviceAdd().

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
---
 src/qemu/qemu_driver.c |   60 +--
 1 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 63ca57c..7321960 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7940,6 +7940,51 @@ static int qemudDomainDetachPciDiskDevice(struct 
qemud_driver *driver,
 
 qemudShrinkDisks(vm-def, i);
 
+if (driver-securityDriver 
+driver-securityDriver-domainRestoreSecurityImageLabel 
+driver-securityDriver-domainRestoreSecurityImageLabel(vm, 
dev-data.disk)  0)
+VIR_WARN(Unable to restore security label on %s, 
dev-data.disk-src);
+
+ret = 0;
+
+cleanup:
+return ret;
+}
+
+static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
+  virDomainObjPtr vm,
+  virDomainDeviceDefPtr dev,
+  unsigned long long qemuCmdFlags)
+{
+int i, ret = -1;
+virDomainDiskDefPtr detach = NULL;
+qemuDomainObjPrivatePtr priv = vm-privateData;
+
+i = qemudFindDisk(vm-def, dev-data.disk-dst);
+
+if (i  0) {
+qemuReportError(VIR_ERR_OPERATION_FAILED,
+_(disk %s not found), dev-data.disk-dst);
+goto cleanup;
+}
+
+if (!(qemuCmdFlags  QEMUD_CMD_FLAG_DEVICE)) {
+qemuReportError(VIR_ERR_OPERATION_FAILED, 
+ _(Underlying qemu does not support SCSI disk removal));
+goto cleanup;
+}
+
+detach = vm-def-disks[i];
+
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+if (qemuMonitorDelDevice(priv-mon, detach-info.alias)  0) {
+qemuDomainObjExitMonitor(vm);
+goto cleanup;
+}
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+qemudShrinkDisks(vm-def, i);
+
 virDomainDiskDefFree(detach);
 
 if (driver-securityDriver 
@@ -8393,9 +8438,18 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
 goto endjob;
 
 if (dev-type == VIR_DOMAIN_DEVICE_DISK 
-dev-data.disk-device == VIR_DOMAIN_DISK_DEVICE_DISK 
-dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
-ret = qemudDomainDetachPciDiskDevice(driver, vm, dev, qemuCmdFlags);
+dev-data.disk-device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+if (dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
+ret = qemudDomainDetachPciDiskDevice(driver, vm, dev, 
qemuCmdFlags);
+}
+else if (dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ret = qemudDomainDetachSCSIDiskDevice(driver, vm, dev, 
+  qemuCmdFlags);
+}
+else {
+qemuReportError(VIR_ERR_NO_SUPPORT,
+%s, _(This type of disk cannot be hot unplugged));
+}
 } else if (dev-type == VIR_DOMAIN_DEVICE_NET) {
 ret = qemudDomainDetachNetDevice(driver, vm, dev, qemuCmdFlags);
 } else if (dev-type == VIR_DOMAIN_DEVICE_CONTROLLER) {
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] Fix SCSI disk unplugging

2010-05-05 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Tue, May 04, 2010 at 05:18:24PM +0200, Wolfgang Mauerer wrote:
 Detaching disk devices is not only possible for VIR_DOMAIN_DISK_BUS_VIRTIO,
 but also for VIR_DOMAIN_DISK_BUS_SCSI, so take care of this possibility.

 Additionally, when the new-style device syntax is used, we do not need to
 check if the PCI address is valid since we don't need it to do the
 hot-unplugging. And while we're at it, drop the pci part
 in qemudDomainDetachPciDiskDevice() -- it's misleading since we
 do not necessarily have to deal with PCI addresses.

 Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
 ---
  src/qemu/qemu_driver.c |   16 +---
  1 files changed, 9 insertions(+), 7 deletions(-)

 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 704f824..f2b8517 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -7862,10 +7862,10 @@ cleanup:
  }
  
  
 -static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
 -  virDomainObjPtr vm,
 -  virDomainDeviceDefPtr dev,
 -  unsigned long long qemuCmdFlags)
 +static int qemudDomainDetachDiskDevice(struct qemud_driver *driver,
 +   virDomainObjPtr vm,
 +   virDomainDeviceDefPtr dev,
 +   unsigned long long qemuCmdFlags)
 
 I'd rather we introduced a separate method
 
qemudDomainDetachSCSIDiskDevice
 
 since logically these are different types of objects/operations, that just
 happen to share a common monitor command with new QEMU. It also needs to
 give a more explicit error in the case where QEMUD_CMD_FLAG_DEVICE is not
 set for SCSI, since we can't support that for SCSI, but can for VirtIO.

okay, I've created a separate function for SCSI disk unplug. Since
the differences between VirtIO and SCSI disk unplug are tiny,
I've tried to extract at least a few commonalities -- see the two
follow-up patches. Albeit there's much more duplicated code lurking in
qemu_driver.c, it might make sense to look at this some day.

Best, Wolfgang

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 1/2] Refactor disk unplugging

2010-05-05 Thread Wolfgang Mauerer
We can reuse some of the code for other purposes.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
---
 src/qemu/qemu_driver.c |   56 ++-
 1 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 47ae52c..63ca57c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7867,6 +7867,36 @@ cleanup:
 }
 
 
+static inline int qemudFindDisk(virDomainDefPtr def, char *dst)
+{
+int i;
+
+for (i = 0 ; i  def-ndisks ; i++) {
+if (STREQ(def-disks[i]-dst, dst)) {
+return i;
+}
+}
+
+return -1;
+}
+
+static inline void qemudShrinkDisks(virDomainDefPtr def, int i)
+{
+if (def-ndisks  1) {
+memmove(def-disks + i,
+def-disks + i + 1,
+sizeof(*def-disks) *
+(def-ndisks - (i + 1)));
+def-ndisks--;
+if (VIR_REALLOC_N(def-disks, def-ndisks)  0) {
+/* ignore, harmless */
+}
+} else {
+VIR_FREE(def-disks);
+def-ndisks = 0;
+}
+}
+
 static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
   virDomainObjPtr vm,
   virDomainDeviceDefPtr dev,
@@ -7876,19 +7906,16 @@ static int qemudDomainDetachPciDiskDevice(struct 
qemud_driver *driver,
 virDomainDiskDefPtr detach = NULL;
 qemuDomainObjPrivatePtr priv = vm-privateData;
 
-for (i = 0 ; i  vm-def-ndisks ; i++) {
-if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-detach = vm-def-disks[i];
-break;
-}
-}
+i = qemudFindDisk(vm-def, dev-data.disk-dst);
 
-if (!detach) {
+if (i  0) {
 qemuReportError(VIR_ERR_OPERATION_FAILED,
 _(disk %s not found), dev-data.disk-dst);
 goto cleanup;
 }
 
+detach = vm-def-disks[i];
+
 if (!virDomainDeviceAddressIsValid(detach-info,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
 qemuReportError(VIR_ERR_OPERATION_FAILED, %s,
@@ -7911,19 +7938,8 @@ static int qemudDomainDetachPciDiskDevice(struct 
qemud_driver *driver,
 }
 qemuDomainObjExitMonitorWithDriver(driver, vm);
 
-if (vm-def-ndisks  1) {
-memmove(vm-def-disks + i,
-vm-def-disks + i + 1,
-sizeof(*vm-def-disks) *
-(vm-def-ndisks - (i + 1)));
-vm-def-ndisks--;
-if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks)  0) {
-/* ignore, harmless */
-}
-} else {
-VIR_FREE(vm-def-disks);
-vm-def-ndisks = 0;
-}
+qemudShrinkDisks(vm-def, i);
+
 virDomainDiskDefFree(detach);
 
 if (driver-securityDriver 
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH] Fix SCSI disk unplugging

2010-05-04 Thread Wolfgang Mauerer
Detaching disk devices is not only possible for VIR_DOMAIN_DISK_BUS_VIRTIO,
but also for VIR_DOMAIN_DISK_BUS_SCSI, so take care of this possibility.

Additionally, when the new-style device syntax is used, we do not need to
check if the PCI address is valid since we don't need it to do the
hot-unplugging. And while we're at it, drop the pci part
in qemudDomainDetachPciDiskDevice() -- it's misleading since we
do not necessarily have to deal with PCI addresses.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
---
 src/qemu/qemu_driver.c |   16 +---
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 704f824..f2b8517 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7862,10 +7862,10 @@ cleanup:
 }
 
 
-static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
-  virDomainObjPtr vm,
-  virDomainDeviceDefPtr dev,
-  unsigned long long qemuCmdFlags)
+static int qemudDomainDetachDiskDevice(struct qemud_driver *driver,
+   virDomainObjPtr vm,
+   virDomainDeviceDefPtr dev,
+   unsigned long long qemuCmdFlags)
 {
 int i, ret = -1;
 virDomainDiskDefPtr detach = NULL;
@@ -7884,7 +7884,8 @@ static int qemudDomainDetachPciDiskDevice(struct 
qemud_driver *driver,
 goto cleanup;
 }
 
-if (!virDomainDeviceAddressIsValid(detach-info,
+if (!(qemuCmdFlags  QEMUD_CMD_FLAG_DEVICE) 
+!virDomainDeviceAddressIsValid(detach-info,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
 qemuReportError(VIR_ERR_OPERATION_FAILED, %s,
 _(device cannot be detached without a PCI address));
@@ -8373,8 +8374,9 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
 
 if (dev-type == VIR_DOMAIN_DEVICE_DISK 
 dev-data.disk-device == VIR_DOMAIN_DISK_DEVICE_DISK 
-dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
-ret = qemudDomainDetachPciDiskDevice(driver, vm, dev, qemuCmdFlags);
+(dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_VIRTIO ||
+ dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_SCSI)) {
+ret = qemudDomainDetachDiskDevice(driver, vm, dev, qemuCmdFlags);
 } else if (dev-type == VIR_DOMAIN_DEVICE_NET) {
 ret = qemudDomainDetachNetDevice(driver, vm, dev, qemuCmdFlags);
 } else if (dev-type == VIR_DOMAIN_DEVICE_CONTROLLER) {
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] qemudDomainAttachSCSIDisk: handle empty controller list

2010-03-15 Thread Wolfgang Mauerer
Jim Meyering wrote:
 Clang found something that might be a real bug.
 I suspect that ...drive.controller will always be at least one,
it can - explanation below.

 but we should not have to dive into the code trying to figure
 that out.  It's easier/better here just to handle the potential trouble:
 
 clang saw that if it *was* zero, then the following for loop
 would not be entered, and cont would not be initialized.
 On the very next statement cont (uninitialized) would be dereferenced.
(...)
 * src/qemu/qemu_driver.c (qemudDomainAttachSCSIDisk): Handle
 the (theoretical) case of an empty controller list, so that
 clang does not think the subsequent dereference of cont
 would dereference an undefined variable (due to preceding
 loop not iterating even once).
 ---
  src/qemu/qemu_driver.c |6 ++
  1 files changed, 6 insertions(+), 0 deletions(-)
 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 7f7c459..efb1857 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -5671,18 +5671,24 @@ static int qemudDomainAttachSCSIDisk(struct 
 qemud_driver *driver,
(...)
  if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
  goto error;
 
 +if (disk-info.addr.drive.controller = 0) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR,
 +_(no drive controller for %s), disk-dst);
 +goto error;
 +}
 +
  for (i = 0 ; i = disk-info.addr.drive.controller ; i++) {
 (...)

disk-info.addr.drive.controller does not denote the number of
available controllers, but an index -- which can very well be zero,
and the loop is always entered. Besides, checking for  0 in
the test does not make sense since
_virDomainDeviceDriveAddress.controller is unsigned.

Since this commit breaks SCSI disk hotplug on controller 0,
please revert it.

Thanks, Wolfgang

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] qemudDomainAttachSCSIDisk: handle empty controller list

2010-03-15 Thread Wolfgang Mauerer
Jim Meyering wrote:
 Daniel P. Berrange wrote:
 On Mon, Mar 15, 2010 at 03:56:55PM +0100, Wolfgang Mauerer wrote:
 Jim Meyering wrote:
 Clang found something that might be a real bug.
 I suspect that ...drive.controller will always be at least one,
 it can - explanation below.

 but we should not have to dive into the code trying to figure
 that out.  It's easier/better here just to handle the potential trouble:

 clang saw that if it *was* zero, then the following for loop
 would not be entered, and cont would not be initialized.
 On the very next statement cont (uninitialized) would be dereferenced.
 (...)
 * src/qemu/qemu_driver.c (qemudDomainAttachSCSIDisk): Handle
 the (theoretical) case of an empty controller list, so that
 clang does not think the subsequent dereference of cont
 would dereference an undefined variable (due to preceding
 loop not iterating even once).
 ---
  src/qemu/qemu_driver.c |6 ++
  1 files changed, 6 insertions(+), 0 deletions(-)

 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 7f7c459..efb1857 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -5671,18 +5671,24 @@ static int qemudDomainAttachSCSIDisk(struct 
 qemud_driver *driver,
 (...)
  if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
  goto error;

 +if (disk-info.addr.drive.controller = 0) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR,
 +_(no drive controller for %s), disk-dst);
 +goto error;
 +}
 +
  for (i = 0 ; i = disk-info.addr.drive.controller ; i++) {
 (...)
 disk-info.addr.drive.controller does not denote the number of
 available controllers, but an index -- which can very well be zero,
 and the loop is always entered. Besides, checking for  0 in
 the test does not make sense since
 _virDomainDeviceDriveAddress.controller is unsigned.

 Since this commit breaks SCSI disk hotplug on controller 0,
 please revert it.
 Agreed, this is definitely broken.
 
 Thanks.  The patch below reverts it.
 
 However, there's more to it than that.
 The controller index, while technically unsigned, may
 be derived from an expression like -1 / 7,
 since virDomainDiskDefAssignAddress does this:
 
   void
   virDomainDiskDefAssignAddress(virDomainDiskDefPtr def)
   {
   int idx = virDiskNameToIndex(def-dst);
 
   switch (def-bus) {
   case VIR_DOMAIN_DISK_BUS_SCSI:
   ...
   def-info.addr.drive.controller = idx / 7;
   def-info.addr.drive.bus = 0;
   def-info.addr.drive.unit = idx % 7;
   break;
 
   case VIR_DOMAIN_DISK_BUS_IDE:
   ...
 
   case VIR_DOMAIN_DISK_BUS_FDC:
   ...
   ...
 
 and virDiskNameToIndex may return -1.
 And idx is then -1.
 
 While we might have gotten lucky with the -1 - 0 mapping for the
 .controller member, I doubt a .unit (also unsigned int) value that's
 derived from -1 % 7 (not portable, btw) will be safe.
 
 I will propose a patch to change the above function
 to return an indication of success or failure
 and update the few callers.  They're all in
 functions that already return success or failure,
 so this is the only interface that would change.

completely agreed.

Thanks, Wolfgang
 
 Here's the revert:
 
 From 4d7423fc0e27e86c937dde1a5d62f3b7b6e49451 Mon Sep 17 00:00:00 2001
 From: Jim Meyering meyer...@redhat.com
 Date: Mon, 15 Mar 2010 16:43:23 +0100
 Subject: [PATCH] Revert f5a6ce44ce8368d4183b69a31b77f67688d9af43
 
 * src/qemu/qemu_driver.c (qemudDomainAttachSCSIDisk): The .controller
 member is an index, and *may* be 0.  Reported by Wolfgang Mauerer.
 ---
  src/qemu/qemu_driver.c |6 --
  1 files changed, 0 insertions(+), 6 deletions(-)
 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index f8ab545..04344a8 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -6057,12 +6057,6 @@ static int qemudDomainAttachSCSIDisk(struct 
 qemud_driver *driver,
  if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
  goto error;
 
 -if (disk-info.addr.drive.controller = 0) {
 -qemuReportError(VIR_ERR_INTERNAL_ERROR,
 -_(no drive controller for %s), disk-dst);
 -goto error;
 -}
 -
  for (i = 0 ; i = disk-info.addr.drive.controller ; i++) {
  cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i, 
 qemuCmdFlags);
  if (!cont)
 --
 1.7.0.2.398.g10c2f

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 2/6] Always link with libgcrypt

2010-02-26 Thread Wolfgang Mauerer
... not just when using the remote driver: libvirt.c always depends on it.
This unbreaks builds with --without-remote

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/Makefile.am |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 2051e5d..8f0fd30 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -334,8 +334,11 @@ libvirt_la_LIBADD += libvirt_driver.la
 libvirt_driver_la_SOURCES = $(DRIVER_SOURCES)
 
 libvirt_driver_la_CFLAGS = $(NUMACTL_CFLAGS)   \
+   $(GNUTLS_CFLAGS)\
-...@top_srcdir@/src/conf
-libvirt_driver_la_LDFLAGS = $(NUMACTL_LIBS)
+libvirt_driver_la_LDFLAGS = $(NUMACTL_LIBS) \
+   $(GNUTLS_LIBS)
+
 
 USED_SYM_FILES = libvirt_private.syms
 
@@ -362,11 +365,9 @@ noinst_LTLIBRARIES += libvirt_driver_remote.la
 libvirt_la_LIBADD += libvirt_driver_remote.la
 endif
 libvirt_driver_remote_la_CFLAGS =  \
-   $(GNUTLS_CFLAGS)\
$(SASL_CFLAGS)  \
-...@top_srcdir@/src/conf
 libvirt_driver_remote_la_LDFLAGS = \
-   $(GNUTLS_LIBS)  \
$(SASL_LIBS)
 if WITH_DRIVER_MODULES
 libvirt_driver_remote_la_LDFLAGS += -module -avoid-version
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 3/6] Fix data structure handling when controllers are attached.

2010-02-26 Thread Wolfgang Mauerer
We must not delete the data part when the operation succeeds
because it is required later on. The correct pattern to handle
the parsed representation of the device information on success
is dev-data.controller = NULL; virDomainDeviceDefFree(dev);,
which leaves the structure pointed at by data in memory.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1586e35..5394ff5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6111,6 +6111,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
 if (dev-data.controller-type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
 ret = qemudDomainAttachPciControllerDevice(driver, vm,
dev-data.controller, 
qemuCmdFlags);
+if (ret == 0)
+dev-data.controller = NULL;
 } else {
 qemuReportError(VIR_ERR_NO_SUPPORT,
 _(disk controller bus '%s' cannot be 
hotplugged.),
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 0/6] SCSI-Disk-Hotremove

2010-02-26 Thread Wolfgang Mauerer
[PATCH 0/6] SCSI-Disk-Hotremove

This series adds support for hot-removing SCSI disks when
qemu supports the drive/device model. It also contains fixes
for SCSI controller hotremoval and the build process.

Cheers, Wolfgang

---
Siemens AG, Corporate Technology, CT T TC 4
Corporate Competence Centre Embedded Linux

 Makefile.am  |7 +--
 qemu/qemu_driver.c   |   97 +++
 qemu/qemu_monitor.c  |   13 ++
 qemu/qemu_monitor.h  |3 +
 qemu/qemu_monitor_json.c |   24 +++
 qemu/qemu_monitor_json.h |3 +
 qemu/qemu_monitor_text.c |   40 +++
 qemu/qemu_monitor_text.h |3 +
 8 files changed, 180 insertions(+), 10 deletions(-)

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 5/6] Use device_del to remove SCSI controllers

2010-02-26 Thread Wolfgang Mauerer
...when the underlying qemu supports the drive/device model and the
controller has been added this way.

Signed-off-by: Wolfgang Mauerer woilfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c   |   31 +--
 src/qemu/qemu_monitor.c  |   13 +
 src/qemu/qemu_monitor.h  |3 +++
 src/qemu/qemu_monitor_json.c |   24 
 src/qemu/qemu_monitor_json.h |3 +++
 src/qemu/qemu_monitor_text.c |   40 
 src/qemu/qemu_monitor_text.h |3 +++
 7 files changed, 111 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8960ef8..d683b1c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6230,7 +6230,8 @@ cleanup:
 
 static int qemudDomainDetachPciControllerDevice(struct qemud_driver *driver,
 virDomainObjPtr vm,
-virDomainDeviceDefPtr dev)
+virDomainDeviceDefPtr dev,
+unsigned long long 
qemuCmdFlags)
 {
 int i, ret = -1;
 virDomainControllerDefPtr detach = NULL;
@@ -6259,11 +6260,23 @@ static int qemudDomainDetachPciControllerDevice(struct 
qemud_driver *driver,
 goto cleanup;
 }
 
+if (qemuCmdFlags  QEMUD_CMD_FLAG_DEVICE) {
+if (qemuAssignDeviceControllerAlias(detach)  0)
+goto cleanup;
+}
+
 qemuDomainObjEnterMonitorWithDriver(driver, vm);
-if (qemuMonitorRemovePCIDevice(priv-mon,
-   detach-info.addr.pci)  0) {
-qemuDomainObjExitMonitor(vm);
-goto cleanup;
+if (qemuCmdFlags  QEMUD_CMD_FLAG_DEVICE) {
+if (qemuMonitorDelDevice(priv-mon, detach-info.alias)) {
+qemuDomainObjExitMonitor(vm);
+goto cleanup;
+}
+} else {
+if (qemuMonitorRemovePCIDevice(priv-mon,
+   detach-info.addr.pci)  0) {
+qemuDomainObjExitMonitor(vm);
+goto cleanup;
+}
 }
 qemuDomainObjExitMonitorWithDriver(driver, vm);
 
@@ -6513,6 +6526,7 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
const char *xml) {
 struct qemud_driver *driver = dom-conn-privateData;
 virDomainObjPtr vm;
+unsigned long long qemuCmdFlags;
 virDomainDeviceDefPtr dev = NULL;
 int ret = -1;
 
@@ -6540,6 +6554,10 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
 if (dev == NULL)
 goto endjob;
 
+if (qemudExtractVersionInfo(vm-def-emulator,
+NULL,
+qemuCmdFlags)  0)
+goto endjob;
 
 if (dev-type == VIR_DOMAIN_DEVICE_DISK 
 dev-data.disk-device == VIR_DOMAIN_DISK_DEVICE_DISK 
@@ -6549,7 +6567,8 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
 ret = qemudDomainDetachNetDevice(driver, vm, dev);
 } else if (dev-type == VIR_DOMAIN_DEVICE_CONTROLLER) {
 if (dev-data.controller-type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
-ret = qemudDomainDetachPciControllerDevice(driver, vm, dev);
+ret = qemudDomainDetachPciControllerDevice(driver, vm, dev,
+   qemuCmdFlags);
 } else {
 qemuReportError(VIR_ERR_NO_SUPPORT,
 _(disk controller bus '%s' cannot be 
hotunplugged.),
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b88532c..a4d2b89 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1318,6 +1318,19 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
 return ret;
 }
 
+int qemuMonitorDelDevice(qemuMonitorPtr mon,
+ const char *devicestr)
+{
+DEBUG(mon=%p, fd=%d device(del)=%s, mon, mon-fd, devicestr);
+int ret;
+
+if (mon-json)
+ret = qemuMonitorJSONDelDevice(mon, devicestr);
+else
+ret = qemuMonitorTextDelDevice(mon, devicestr);
+return ret;
+}
+
 
 int qemuMonitorAddDevice(qemuMonitorPtr mon,
  const char *devicestr)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 0ac3957..3e55236 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -290,6 +290,9 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
 int qemuMonitorAddDevice(qemuMonitorPtr mon,
  const char *devicestr);
 
+int qemuMonitorDelDevice(qemuMonitorPtr mon,
+ const char *devicestr);
+
 int qemuMonitorAddDrive(qemuMonitorPtr mon,
 const char *drivestr);
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7b45594..3a94dd0 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c

[libvirt] [PATCH 6/6] Implement hotremove for SCSI disks

2010-02-26 Thread Wolfgang Mauerer
Recent qemu versions allow us to add disks dynamically into the system
via the drive_add/device_add mechanism. Removing them is now just a
matter of using device_del, and this patch adds the required bits
and pieces to libvirt.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |   57 
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d683b1c..ecbb23d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5494,6 +5494,60 @@ qemuDomainFindOrCreateSCSIDiskController(struct 
qemud_driver *driver,
 }
 
 
+static int qemudDomainDetachSCSIDisk(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ unsigned int qemuCmdFlags)
+{
+int i;
+qemuDomainObjPrivatePtr priv = vm-privateData;
+virDomainDiskDefPtr detach = NULL;
+
+if (!(qemuCmdFlags  QEMUD_CMD_FLAG_DEVICE)) {
+return -1;
+}
+
+for (i = 0 ; i  vm-def-ndisks ; i++) {
+if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
+detach = vm-def-disks[i];
+break;
+}
+}
+
+if (!detach) {
+qemuReportError(VIR_ERR_OPERATION_FAILED,
+_(disk %s not found), dev-data.disk-dst);
+return -1;
+}
+
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+/* Note: drive_del does not exist, but device_del will
+   automatically erase the associated drive as well */
+if (qemuMonitorDelDevice(priv-mon, detach-info.alias)) {
+qemuDomainObjExitMonitor(vm);
+return -1;
+}
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+if (vm-def-ndisks  1) {
+memmove(vm-def-disks + i,
+vm-def-disks + i + 1,
+sizeof(*vm-def-disks) *
+(vm-def-ndisks - (i + 1)));
+vm-def-ndisks--;
+if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks)  0) {
+/* ignore, harmless */
+}
+} else {
+VIR_FREE(vm-def-disks);
+vm-def-ndisks = 0;
+}
+virDomainDiskDefFree(detach);
+
+return 0;
+}
+
+
 static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver,
  virDomainObjPtr vm,
  virDomainDiskDefPtr disk,
@@ -6563,6 +6617,9 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
 dev-data.disk-device == VIR_DOMAIN_DISK_DEVICE_DISK 
 dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
 ret = qemudDomainDetachPciDiskDevice(driver, vm, dev);
+} else if(dev-type == VIR_DOMAIN_DEVICE_DISK 
+  dev-data.disk-bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ret = qemudDomainDetachSCSIDisk(driver, vm, dev, qemuCmdFlags);
 } else if (dev-type == VIR_DOMAIN_DEVICE_NET) {
 ret = qemudDomainDetachNetDevice(driver, vm, dev);
 } else if (dev-type == VIR_DOMAIN_DEVICE_CONTROLLER) {
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/6] Tiny spelling fix

2010-02-26 Thread Wolfgang Mauerer
---
 src/qemu/qemu_driver.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1e4b493..1586e35 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5475,7 +5475,7 @@ qemuDomainFindOrCreateSCSIDiskController(struct 
qemud_driver *driver,
 return cont;
 }
 
-/* No SCSI controller present, for back compatability we
+/* No SCSI controller present, for backward compatibility we
  * now hotplug a controller */
 if (VIR_ALLOC(cont)  0) {
 virReportOOMError();
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 4/6] Fix PCI address handling when controllers are deleted.

2010-02-26 Thread Wolfgang Mauerer
When a controller is not present in the system anymore, the PCI address
must be deleted from libvirt's hashtable because it can be re-used for
other purposes.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5394ff5..8960ef8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6280,6 +6280,11 @@ static int qemudDomainDetachPciControllerDevice(struct 
qemud_driver *driver,
 VIR_FREE(vm-def-controllers);
 vm-def-ncontrollers = 0;
 }
+
+if (qemuDomainPCIAddressReleaseAddr(priv-pciaddrs, detach-info)  0) {
+VIR_WARN0(Unable to release PCI address on controller);
+}
+
 virDomainControllerDefFree(detach);
 
 ret = 0;
-- 
1.6.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 00/34] Add device addressing and disk controller support

2010-01-13 Thread Wolfgang Mauerer
Hi,

On Fri, Jan 8, 2010 at 6:22 PM, Daniel P. Berrange berra...@redhat.com
wrote:
 This series is a merge of two previous series I posted

  http://www.redhat.com/archives/libvir-list/2009-December/msg00232.html
  http://www.redhat.com/archives/libvir-list/2009-December/msg00392.html

 It accomplishes quite a lot of things, having major impact on the QEMU
 driver, hopefully all in a postive way :-)

do you happen to have a git repository from which the patches can
be pulled? This would ease testing quite a bit since it's become
a rather voluminous series ;-)

Thanks, Wolfgang

 In particular it does

  * Add standard XML syntax for addressing of PCI devices, and disk drives
  * Add support for disk controllers as a managed device in XML
  * Add support for disk controller hotplug/unplug
  * Convert everything over to use QEMU's -device flag where available
  * Add PCI addressing when using -device
  * Introduce a way to give every device a unique 'alias' name in
   the XML format

 I can't promise it works perfectly, but i've done quite alot of positive
 testing with it now  believe all the back comptability stuff is working
 right.

 --
 Libvir-list mailing list
 Libvir-list@redhat.com
 https://www.redhat.com/mailman/listinfo/libvir-list


--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 0/12] Standardized device addressing SCSI controller/disk hotplug

2009-12-18 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Thu, Dec 10, 2009 at 10:22:20PM +, Daniel P. Berrange wrote:
 The XML for each address type looks like

   address type='pci' mode='static' domain='0x' bus='0x1e' 
 slot='0x07' function='0x0'/
   address type='usb' mode='dynamic' bus='007' dev='003'/
   address type='drive' mode='dynamic' controller='1' bus='0' unit='5'/


 The 'mode' attribute for any of them is allowed to be either
 'static' or 'dynamic'. A static address is one specified by
 the end user when defining the XML, while a dynamic address is
 one automatically chosen by libvirt/QEMU every time a guest
 boots. The idea of static addresses is to allow management
 apps to guarentee that PCI device  drive numbering never
 changes. This series does not actually implement static
 addressing for PCI yet, because it requires that we change
 the way we generate QEMU command line arguments. It does
 do static addressing for disks.
 
 I'm now wondering whether we actually truely need the 'dynamic'
 option. It already doesn't really make sense for disks. For PCI
 though I'm not sure anyone would ever want the dynamic mode, 
 where addresses can change at every boot. I think I should just
 remove the 'mode' attribute here, and just have libvirt detect
 PCI addresses the first time, and keep them the same thereafter.

Maybe there are two things to distinguish: If you read dynamic
in the sense of I don't care which address the device/disk/whatever
uses, and I don't want to specify it explicitely, then having the
option is reasonable . I agree that  it does not make any sense
to have dynamic in the sense explicitely assign new addresses every
time system boots, but that would not happen any way: Given the same
set of devices, the underlying hypervisor should assign the same
addresses.

Your suggestion would essentially imply that an initial dynamic
specification is converted into a static one after the first boot.
You are only referring to the in-memory configuration of libvirt
when you talk about subsequent boots, or are you also thinking
about modifying the persistent configuration?

 The second thought is whether we should put the address
 data inside a device element, so it looked like
 
   device type='pci'
  address domain='0x' bus='0x1e' slot='0x07' function='0x0'/
   /device
 
 The reason being, that I think it might be interesting to  also add in
 the vendor / product info at a later date 
 
   device type='pci'
  vendor id='0x8086'/
  product id='0x1234'/
  address domain='0x' bus='0x1e' slot='0x07' function='0x0'/
   /device

Can't certainly do any harm to keep the format extensible.

Regards,

Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] Re: [PATCH 0/12] Standardized device addressing SCSI controller/disk hotplug

2009-12-15 Thread Wolfgang Mauerer
Hi,

Daniel P. Berrange wrote:
 This patch series is a combination of series done by
 Wolfgang Mauerer to support proper SCSI drive hotplug
 and new work by myself to introduce generic addressing
 for all devices.

 Wolfgang's most recent posting was

 http://www.redhat.com/archives/libvir-list/2009-November/msg00574.html
 http://www.redhat.com/archives/libvir-list/2009-November/msg00701.html

 When testing that series I came across a few minor issues,
 but more importantly it made me realize how important it is
 that we introduce explicit device addressing in our XML format.
 (...)

essentially, this all looks good to me - thanks for the extensions.
Unfortunately, I was not yet successful in fully testing the code
because I have some issues with the underlying qemu that prevent my
machines from booting correctly with recent qemu-kvms. However, I came
across a small issue: When certain PCI devices are not present in the
system, libvirt can crash at startup. The attached patch fixes this.

Best, Wolfgang
commit 9d183e9710f8a062c4a95f208e0c39652016f729
Author: Wolfgang Mauerer wolfgang.maue...@siemens.com
Date:   Mon Dec 14 17:09:37 2009 +0100

Fix crashes at startup when certain devices are not present

At startup, libvirt tries to detect which devices are available by parsing the
output of info pci. However, some of the possible devices (like watchdogs)
might not be available, which must be taken into account by the code.

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9b5fac6..5d63108 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1754,6 +1754,9 @@ qemuGetPCIDiskVendorProduct(virDomainDiskDefPtr def,
 unsigned *vendor,
 unsigned *product)
 {
+if (!def)
+return -1;
+
 switch (def-bus) {
 case VIR_DOMAIN_DISK_BUS_VIRTIO:
 *vendor = QEMU_PCI_VENDOR_REDHAT;
@@ -1772,7 +1775,7 @@ qemuGetPCINetVendorProduct(virDomainNetDefPtr def,
 unsigned *vendor,
 unsigned *product)
 {
-if (!def-model)
+if (!def || !def-model)
 return -1;
 
 if (STREQ(def-model, ne2k_pci)) {
@@ -1803,6 +1806,9 @@ qemuGetPCIControllerVendorProduct(virDomainControllerDefPtr def,
   unsigned *vendor,
   unsigned *product)
 {
+if (!def)
+return -1;
+
 switch (def-type) {
 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
 *vendor = QEMU_PCI_VENDOR_LSI_LOGIC;
@@ -1833,6 +1839,9 @@ qemuGetPCIVideoVendorProduct(virDomainVideoDefPtr def,
  unsigned *vendor,
  unsigned *product)
 {
+if (!def)
+return -1;
+
 switch (def-type) {
 case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
 *vendor = QEMU_PCI_VENDOR_CIRRUS;
@@ -1860,6 +1869,9 @@ qemuGetPCISoundVendorProduct(virDomainSoundDefPtr def,
  unsigned *vendor,
  unsigned *product)
 {
+if (!def)
+return -1;
+
 switch (def-model) {
 case VIR_DOMAIN_SOUND_MODEL_ES1370:
 *vendor = QEMU_PCI_VENDOR_ENSONIQ;
@@ -1883,6 +1895,9 @@ qemuGetPCIWatchdogVendorProduct(virDomainWatchdogDefPtr def,
 unsigned *vendor,
 unsigned *product)
 {
+if (!def)
+return -1;
+
 switch (def-model) {
 case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB:
 *vendor = QEMU_PCI_VENDOR_INTEL;
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] Re: [PATCH 0/12] Standardized device addressing SCSI controller/disk hotplug

2009-12-15 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Tue, Dec 15, 2009 at 01:06:51PM +0100, Wolfgang Mauerer wrote:
 Hi,

 Daniel P. Berrange wrote:
 This patch series is a combination of series done by
 Wolfgang Mauerer to support proper SCSI drive hotplug
 and new work by myself to introduce generic addressing
 for all devices.

 Wolfgang's most recent posting was

 http://www.redhat.com/archives/libvir-list/2009-November/msg00574.html
 http://www.redhat.com/archives/libvir-list/2009-November/msg00701.html

 When testing that series I came across a few minor issues,
 but more importantly it made me realize how important it is
 that we introduce explicit device addressing in our XML format.
 (...)
 essentially, this all looks good to me - thanks for the extensions.
 Unfortunately, I was not yet successful in fully testing the code
 because I have some issues with the underlying qemu that prevent my
 machines from booting correctly with recent qemu-kvms. However, I came
 across a small issue: When certain PCI devices are not present in the
 system, libvirt can crash at startup. The attached patch fixes this.
 
 Hmm, which particular device did you see it crash on? These
 functions are only called with 'def' straight out of the
 virDomainDefPtr struct, (eg, vm-def-disks[INDEX]) and those
 are all supposed to be non-NULL at all times. So if one is NULL
 then I've introduced a bug somewhere else ! I guess most likely
 in the new controllers code.

it crashed with a missing watchdog. I realise that the other
checks are not strictly necessary when users stick to the calling
conventions, but figured that one check too many in the startup phase
doesn't do any harm and is better than a crash.

Best regards,

Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] Re: [PATCH 10/12] Implement SCSI controller hotplug/unplug for QEMU

2009-12-15 Thread Wolfgang Mauerer
Hi,

Daniel P. Berrange wrote:
 From: Wolfgang Mauerer wolfgang.maue...@siemens.com
 
 This patch allows for explicit hotplug/unplug of SCSI controllers.
 Ordinarily this is not required, since QEMU/libvirt will attach
 a new SCSI controller whenever one is required. Allowing explicit
 hotplug of controllers though, enables the caller to specify a
 static PCI address, instead of auto-assigning the next available
 PCI slot. Or it will when we have static PCI addressing.
 
 This patch is derived from Wolfgang Mauerer's disk controller
 patch series.
 
 * src/qemu/qemu_driver.c: Support hotplug  unplug of SCSI
   controllers
 * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
   src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
   src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add
   new API for attaching PCI SCSI controllers
(...)
 +int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon,
 +   const char *bus,
 +   virDomainDevicePCIAddress 
 *guestAddr)
 +{
 +char *cmd = NULL;
 +char *reply = NULL;
 +int tryOldSyntax = 0;
 +int ret = -1;
 +
 +try_command:
 +if (virAsprintf(cmd, pci_add %s storage if=%s,
 +(tryOldSyntax ? 0: pci_addr=auto), bus)  0) {
 +virReportOOMError(NULL);
 +goto cleanup;
 +}

I just realised that qemu-kvm HEAD prohibits adding empty SCSI
controllers currently, they consider this to be a bug. I've asked
to revert the corresponding patch on qemu-devel, but if this does
not happen, we will need to devise some other mechanism.

Regards, Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2] Disk- and Controller Hotplug

2009-12-02 Thread Wolfgang Mauerer
Hi,

Some time ago, Daniel P. Berrange wrote:
 On Tue, Nov 24, 2009 at 02:15:58PM +0100, Wolfgang Mauerer wrote:
 Daniel P. Berrange wrote:
 On Mon, Nov 23, 2009 at 02:15:06PM +0100, Wolfgang Mauerer wrote:
 Daniel P. Berrange wrote:
 Wolfgang Mauerer wrote:

 okay, to avoid flooding the mailing list with nearly identical 
 patches, I've put the rebased versions into a repository at 
 git://git.kiszka.org/libvirt.git queue
 
 I've been taking a closer look at this, and I think the final state 
 of patch series as a whole looks good. The minor issue is that the 
 intermediate patches don't compile, since they rely on compile fixes 
 at the end of the series. Rather than ask you to re-format the
 patches yet again, I'm going to just merge the patches into a smaller
 set myself.

yes, I've sacrificed individual compilability when I did the forward
porting because I the amount of time I can dedicate to this right
now is a bit restricted for various reasons. Thanks for doing the
missing cleanups!

 I've got just one question I'd like to understand before doing this.
 On the disk element's new controller element, you are allowing
 two mutually exclusive ways of specifying the controller
 
 disk ... controller name=identifier bus=number
 unit=number/ /disk
 
 and
 
 disk ... controller pci_addr=addr bus=number
 unit=number/ /disk
 
 I think it is going to cause unneccessary pain for applications to
 have to cope with two different ways of specifying the same
 relationship. So my intention is to remove the 'pci_addr' variant,
 since that information can easily be got directly from the separate
 top level controller device itself

Getting rid of pci_addr is perfectly okay. I've kept it in the current
series for setups that don't provide controllers, but it's supposed
to be eliminated by design. Just go ahead if you want to do this
it already now ;-)

 On a side note, once we've applied this initial series, I think we'll
  also need to be automatically adding a controller element in all
 guest domains which have IDE or SCSI controllers present by default.
 This is going to also force us to hook into QEMU's 'info pci' monitor
 command to figure out their PCI address. This is long overdue though
 and needed for NIC  Disk devices added at startup too, so this is
 good motivation :-)

agreed. I can try to address this when I bring back hot-removal.

Best regards,

Wolfgang

--
Siemens AG, Corporate Technology CT T DE IT 1
Corporate Competence Centre Embedded Linux

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2] Disk- and Controller Hotplug

2009-11-24 Thread Wolfgang Mauerer
Hi,

Daniel P. Berrange wrote:
 On Mon, Nov 23, 2009 at 02:15:06PM +0100, Wolfgang Mauerer wrote:
 Daniel P. Berrange wrote:
 On Tue, Nov 17, 2009 at 12:53:31AM +0100, wolfgang.maue...@siemens.com 
 wrote:
 this is the second revision of a patch series to improve disk
 hotadd support for libvirt. It focuses on the qemu backend, but
 is naturally designed to be compatible with other backends as
 well. The objective is two-fold:

 1.) Split off controller from disk handling. This is done by
 introducing a new domain element controller that is used to
 describe disk controllers. Support for hotplugging such
 controllers is added.  Support to reference controllers by
 name is also included.
 2.) disks can now be associated with a specific controller;
 this is done by means of a controller subelemnt for disks.

 This patch addresses the questions that were raised during the
 review of the initial submission, massages the code by fixing
 some whitespace issues, gets static controller configurations to
 work, and adds documentation. Notice that in contrast to the
 first submission I did not include the patch that adds support
 for disk- and controller hot_remove_. Since the qemu codebase is
 still in bit of a flux wrt.  the necessary patches required for
 this functionality, it will reappear some time later as a
 separate submission.
 What libvirt version / GIT changeset  did you create these patches
 against ?  The current libvirt QEMU driver code in GIT is quite
 different, so the patches here don't apply for me as is.
 sorry for the late reply, I could not access my eMail during
 the last couple of days. Patches are on top of
 790f0b3057787bb64, I did not realise that this one was only
 in the middle of qemu refactoring, not at the end :-(

 Do you plan any more refactorings to the qemu base in the near
 future, and if yes, are these already available somewhere? I'd
 like to avoid another useless rebase...
 
 No, the monitor code for the QEMU driver is stable now. I'll only be adding
 extra functionality, not changing existing stuff, so it should be good to
 rebase against now.

okay, to avoid flooding the mailing list with nearly identical
patches, I've put the rebased versions into a repository at
git://git.kiszka.org/libvirt.git queue

Best regards,

Wolfgang



The following changes since commit
8f147d16f1ccdd1f2ce063823fcf961e7bf396a5:
  Daniel P. Berrange (1):

Fix default disk type when parsing QEMU argv


are available in the git repository at:

  git://git.kiszka.org/libvirt.git queue

Wolfgang Mauerer (13):
  Fix help message
  Clarify documentation for private symbols
  Extend disk element with controller information
  Add new domain device: controller
  Add disk-based hotplugging for the qemu backend
  Drop qemudAttachPciDiskDevice
  Implement controller hotplugging
  Allow controller selection by ID
  Remove surprises in the semantics of disk-hotadd
  Factor out the method to get the PCI address of a controller for a
given disk
  Extract qemu monitor parts for controller hotplug
  Extract monitor parts from the qemu interaction for disk hotplug
  Update documentation: Controller

 daemon/libvirtd.c|2 +-
 docs/formatdomain.html.in|   38 +
 docs/schemas/domain.rng  |  160 --
 src/conf/domain_conf.c   |  314
+-
 src/conf/domain_conf.h   |   62 -
 src/libvirt_private.syms |7 +-
 src/qemu/qemu_driver.c   |  194 --
 src/qemu/qemu_monitor_text.c |  199 ++
 src/qemu/qemu_monitor_text.h |9 ++
 9 files changed, 925 insertions(+), 60 deletions(-)

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2] Disk- and Controller Hotplug

2009-11-16 Thread wolfgang . mauerer
Hi,

this is the second revision of a patch series to improve disk
hotadd support for libvirt. It focuses on the qemu backend, but
is naturally designed to be compatible with other backends as
well. The objective is two-fold:

1.) Split off controller from disk handling. This is done by
introducing a new domain element controller that is used to
describe disk controllers. Support for hotplugging such
controllers is added.  Support to reference controllers by
name is also included.
2.) disks can now be associated with a specific controller;
this is done by means of a controller subelemnt for disks.

This patch addresses the questions that were raised during the
review of the initial submission, massages the code by fixing
some whitespace issues, gets static controller configurations to
work, and adds documentation. Notice that in contrast to the
first submission I did not include the patch that adds support
for disk- and controller hot_remove_. Since the qemu codebase is
still in bit of a flux wrt.  the necessary patches required for
this functionality, it will reappear some time later as a
separate submission.
   
Best,

Wolfgang


 daemon/libvirtd.c|2 +-
 docs/formatdomain.html.in|   38 +
 docs/schemas/domain.rng  |  158 -
 src/conf/domain_conf.c   |  314 +-
 src/conf/domain_conf.h   |   62 -
 src/libvirt_private.syms |7 +-
 src/qemu/qemu_driver.c   |  184 +++--
 src/qemu/qemu_monitor_text.c |  197 ++
 src/qemu/qemu_monitor_text.h |7 +
 9 files changed, 910 insertions(+), 59 deletions(-)

--
Siemens AG, CT T DE
Corporate Competence Centre Embedded Linux

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 09/13] Remove surprises in the semantics of disk-hotadd

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

When a disk is added without an explicitly specified
controller as host, then try to find the first available
controller. If none exists, do not (as in previous versions)
add a new PCI controller device with the disk attached,
but bail out with an error. Notice that this patch changes
the behaviour as compared to older libvirt releases, as
has been discussed on the mailing list (see
http://thread.gmane.org/gmane.comp.emulators.libvirt/15860)

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |  122 +++-
 1 files changed, 68 insertions(+), 54 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d3395a7..4f647c4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4406,68 +4406,82 @@ try_command:
 controller_specified = 1;
 }
 
-if (controller_specified) {
-if (dev-data.disk-controller_name) {
-for (i = 0 ; i  vm-def-ncontrollers ; i++) {
-if (STREQ(dev-data.disk-controller_name,
-  vm-def-controllers[i]-name)) {
-break;
-}
-}
-
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(Controller does not exist));
-return -1;
-}
-
-domain = vm-def-controllers[i]-address-data.pci.domain;
-bus= vm-def-controllers[i]-address-data.pci.bus;
-slot   = vm-def-controllers[i]-address-data.pci.slot;
-} else {
-domain = dev-data.disk-controller_pci_addr.domain;
-bus= dev-data.disk-controller_pci_addr.bus;
-slot   = dev-data.disk-controller_pci_addr.slot;
-
-for (i = 0 ; i  vm-def-ncontrollers ; i++) {
-if (domain == 
vm-def-controllers[i]-address-data.pci.domain 
-bus== vm-def-controllers[i]-address-data.pci.bus 
-slot   == vm-def-controllers[i]-address-data.pci.slot)
-break;
-}
-
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(Controller does not exist));
-return -1;
+   if (!controller_specified) {
+   /* Find an appropriate controller for disk-hotadd. Notice that
+  the admissible controller types (SCSI, virtio) have already
+  been checked in qemudDomainAttachDevice. */
+   for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+   if (vm-def-controllers[i]-type == dev-data.disk-type)
+   break;
+   }
+
+   if (i == vm-def-ncontrollers) {
+   qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Cannot find appropriate controller for hot-add));
+   return -1;
+   }
+
+   domain = vm-def-controllers[i]-address-data.pci.domain;
+   bus= vm-def-controllers[i]-address-data.pci.bus;
+   slot   = vm-def-controllers[i]-address-data.pci.slot;
+   }
+
+   if (controller_specified  dev-data.disk-controller_name) {
+   for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+   if (STREQ(dev-data.disk-controller_name,
+ vm-def-controllers[i]-name)) {
+   break;
 }
-   }
-
-if (dev-data.disk-bus_id != -1) {
-virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
 }
 
-if (dev-data.disk-unit_id != -1) {
-virBufferVSprintf(buf, ,unit=%d, dev-data.disk-unit_id);
+   if (i == vm-def-ncontrollers) {
+   qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+_(Controller does not exist));
+   return -1;
+   }
+
+   domain = vm-def-controllers[i]-address-data.pci.domain;
+   bus= vm-def-controllers[i]-address-data.pci.bus;
+   slot   = vm-def-controllers[i]-address-data.pci.slot;
+   } else if (controller_specified) {
+   domain = dev-data.disk-controller_pci_addr.domain;
+   bus= dev-data.disk-controller_pci_addr.bus;
+   slot   = dev-data.disk-controller_pci_addr.slot;
+
+   for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+   if (domain ==  vm-def-controllers[i]-address-data.pci.domain 
+   bus==  vm-def-controllers[i]-address-data.pci.bus 
+   slot   ==  vm-def-controllers[i]-address-data.pci.slot)
+   break;
 }
 
-bus_unit_string = virBufferContentAndReset(buf);
-
-VIR_DEBUG (%s: drive_add %d:%d:%d file=%s,if=%s%s, vm-def-name,
-   domain, bus, slot, safe_path, type, bus_unit_string);
-ret = virAsprintf(cmd, drive_add %s%d:%d:%d file=%s,if=%s%s

[libvirt] [PATCH 01/13] Fix help message

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

The configuration file setting is overriden by -f or --config, but
not with -c

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
---
 daemon/libvirtd.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index daf06bc..5cedd17 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -2931,7 +2931,7 @@ libvirt management daemon:\n\
 \n\
   Default paths:\n\
 \n\
-Configuration file (unless overridden by -c):\n\
+Configuration file (unless overridden by -f):\n\
SYSCONF_DIR /libvirt/libvirtd.conf\n\
 \n\
 Sockets (as root):\n\
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 05/13] Add disk-based hotplugging for the qemu backend

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

When disks are added to a qemu backend with attach-device,
not just the disk, but a complete new PCI controller with
the disk attached is brought into the system. This patch
implements a proper disk hotplugging scheme for qemu.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/conf/domain_conf.c   |   33 ++-
 src/conf/domain_conf.h   |5 +-
 src/libvirt_private.syms |3 +-
 src/qemu/qemu_driver.c   |  243 +-
 4 files changed, 278 insertions(+), 6 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4e2b84e..91115b6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -896,7 +896,6 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 char *driverType = NULL;
 char *source = NULL;
 char *target = NULL;
-char *controller = NULL;
 char *controller_pci_addr = NULL;
 char *bus_id = NULL;
 char *unit_id = NULL;
@@ -953,7 +952,8 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 if (target 
 STRPREFIX(target, ioemu:))
 memmove(target, target+6, strlen(target)-5);
-} else if ((controller == NULL) 
+} else if ((controller_name == NULL 
+controller_pci_addr == NULL) 
(xmlStrEqual(cur-name, BAD_CAST controller))) {
 controller_name = virXMLPropString(cur, name);
 controller_pci_addr =  virXMLPropString(cur, pci_addr);
@@ -1059,7 +1059,13 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 }
 }
 
-if (controller) {
+if (controller_name  controller_pci_addr) {
+virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+ _(Both controller ID and address specified!));
+goto error;
+}
+
+if (controller_name) {
 def-controller_name = controller_name;
 
 def-bus_id = -1;
@@ -1090,6 +1096,23 @@ virDomainDiskDefParseXML(virConnectPtr conn,
}
 }
 
+/* TODO: Should we re-use devaddr for this purpose,
+   or is an extra field justified? */
+def-controller_pci_addr.domain = -1;
+def-controller_pci_addr.bus = -1;
+def-controller_pci_addr.slot = -1;
+
+if (controller_pci_addr 
+sscanf(controller_pci_addr, %x:%x:%x,
+   def-controller_pci_addr.domain,
+   def-controller_pci_addr.bus,
+   def-controller_pci_addr.slot)  3) {
+virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _(Unable to parse controller 'pciaddr' 
parameter '%s'),
+ controller_pci_addr);
+goto error;
+}
+
 VIR_DEBUG(Controller PCI addr for disk parsed as %x:%x:%x\n,
   def-controller_pci_addr.domain,
   def-controller_pci_addr.bus,
@@ -1101,6 +1124,7 @@ virDomainDiskDefParseXML(virConnectPtr conn,
  _(Invalid bus type '%s' for floppy disk), bus);
 goto error;
 }
+
 if (def-device != VIR_DOMAIN_DISK_DEVICE_FLOPPY 
 def-bus == VIR_DOMAIN_DISK_BUS_FDC) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -1126,6 +1150,9 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 goto error;
 }
 
+VIR_DEBUG(Disk PCI address parsed as %d:%d:%d\n,
+  def-pci_addr.domain, def-pci_addr.bus, def-pci_addr.slot);
+
 def-src = source;
 source = NULL;
 def-dst = target;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 591143f..b30d08c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -133,7 +133,7 @@ struct _virDomainDiskDef {
 int device;
 int bus;  /* Bus type, e.g. scsi or ide */
 int bus_id;   /* Bus number on the controller */
-int unit_id;  /* Unit on the controller */
+int unit_id;  /* Unit on the controller (both -1 if unspecified) */
 char *src;
 char *dst;
 char *controller_name;
@@ -744,6 +744,9 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def);
 void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
 void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
 void virDomainDeviceAddressFree(virDomainDeviceAddressPtr def);
+int virDomainCompareDeviceAddresses(virDomainDeviceAddressPtr a,
+virDomainDeviceAddressPtr b);
+const char *virDomainFormatDeviceAddress(virDomainDeviceAddressPtr address);
 void virDomainDefFree(virDomainDefPtr vm);
 void virDomainObjFree(virDomainObjPtr vm);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 92cf86c..e73ed94 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -152,7 +152,8 @@ virDomainObjListGetActiveIDs;
 virDomainObjListNumOfDomains;
 virDomainObjListInit;
 virDomainObjListDeinit

[libvirt] [PATCH 06/13] Drop qemudAttachPciDiskDevice

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This function is not necessary anymore

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |   33 -
 1 files changed, 0 insertions(+), 33 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9f71562..1fbfdde 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4597,39 +4597,6 @@ try_command:
 return 0;
 }
 
-static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
-  virDomainObjPtr vm,
-  virDomainDeviceDefPtr dev)
-{
-int i;
-const char* type = virDomainDiskBusTypeToString(dev-data.disk-bus);
-
-for (i = 0 ; i  vm-def-ndisks ; i++) {
-if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-   _(target %s already exists), dev-data.disk-dst);
-return -1;
-}
-}
-
-if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks+1)  0) {
-virReportOOMError(conn);
-return -1;
-}
-
-if (qemuMonitorAddPCIDisk(vm,
-  dev-data.disk-src,
-  type,
-  dev-data.disk-pci_addr.domain,
-  dev-data.disk-pci_addr.bus,
-  dev-data.disk-pci_addr.slot)  0)
-return -1;
-
-virDomainDiskInsertPreAlloced(vm-def, dev-data.disk);
-
-return 0;
-}
-
 static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
  virDomainObjPtr vm,
  virDomainDeviceDefPtr dev)
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 03/13] Extend disk element with controller information

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This allows us to connect a disk with a specific controller,
which is required for disk hotadd/remove. A new XML child
element is added to the disk container:

disk
...
controller name=identifier pci_addr=addr bus=number 
unit=number/
/disk

Normally the name of the controller must be specified. Using pci_addr
instead is supported for qemu guests that don't define a controller
in their main configuration file and cannot hotplug controllers.
When the controller has been brought into the system via the hotplug
mechanism also included in this patch series, it will have an ID.

Wrt. the data structures touched in this commit, notice
that while bus as subelement of target specifies
the type of bus (e.g., scsi, ide,...), it is used
to enumerate the buses on the controller here.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/conf/domain_conf.c |   29 +
 src/conf/domain_conf.h |5 -
 2 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 28bee54..ecddb68 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -724,7 +724,12 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 char *driverType = NULL;
 char *source = NULL;
 char *target = NULL;
+char *controller = NULL;
+char *bus_id = NULL;
+char *unit_id = NULL;
+char *controller_id = NULL;
 char *bus = NULL;
+char *unit = NULL;
 char *cachetag = NULL;
 char *devaddr = NULL;
 virStorageEncryptionPtr encryption = NULL;
@@ -768,12 +773,18 @@ virDomainDiskDefParseXML(virConnectPtr conn,
(xmlStrEqual(cur-name, BAD_CAST target))) {
 target = virXMLPropString(cur, dev);
 bus = virXMLPropString(cur, bus);
+unit = virXMLPropString(cur, unit);
 
 /* HACK: Work around for compat with Xen
  * driver in previous libvirt releases */
 if (target 
 STRPREFIX(target, ioemu:))
 memmove(target, target+6, strlen(target)-5);
+} else if ((controller == NULL) 
+   (xmlStrEqual(cur-name, BAD_CAST controller))) {
+   controller_id = virXMLPropString(cur, id);
+   bus_id = virXMLPropString(cur, bus);
+   unit_id = virXMLPropString(cur, unit);
 } else if ((driverName == NULL) 
(xmlStrEqual(cur-name, BAD_CAST driver))) {
 driverName = virXMLPropString(cur, name);
@@ -874,6 +885,24 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 }
 }
 
+if (controller) {
+def-controller_id = controller_id;
+
+def-bus_id = -1;
+   if (bus_id  virStrToLong_i(bus_id, NULL, 10, def-bus_id)  0) {
+   virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+_(Cannot parse controller 'bus' attribute));
+   goto error;
+  }
+
+   def-unit_id = -1;
+   if (unit_id  virStrToLong_i(unit_id, NULL, 10, def-unit_id)  0) {
+   virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+_(Cannot parse controller 'unit' attribute));
+   goto error;
+   }
+}
+
 if (def-device == VIR_DOMAIN_DISK_DEVICE_FLOPPY 
 def-bus != VIR_DOMAIN_DISK_BUS_FDC) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fadf43f..c034ae4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -107,9 +107,12 @@ typedef virDomainDiskDef *virDomainDiskDefPtr;
 struct _virDomainDiskDef {
 int type;
 int device;
-int bus;
+int bus;  /* Bus type, e.g. scsi or ide */
+int bus_id;   /* Bus number on the controller */
+int unit_id;  /* Unit on the controller */
 char *src;
 char *dst;
+char *controller_id;
 char *driverName;
 char *driverType;
 char *serial;
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 02/13] Clarify documentation for private symbols

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

The instruction See Makefile.am in libvirt.private_syms
always makes me think that this file is autogenerated
and should not be touched manually. This patch spares
every reader of libvirt.private_syms the hassle of
reading Makefile.am before augmenting libvirt.private_syms.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/libvirt_private.syms |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 310376b..fb81ace 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1,5 +1,6 @@
 #
-# General private symbols. See Makefile.am.
+# General private symbols. Add symbols here, and see Makefile.am for
+# more details.
 #
 
 
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 08/13] Allow controller selection by ID

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

... by simply traversing the list of controllers
to find the associated PCI address.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c |   37 +
 1 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1b20937..d3395a7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4407,19 +4407,40 @@ try_command:
 }
 
 if (controller_specified) {
-/* NOTE: Proper check for the controller will be implemented
-   in a later commit */
-   domain = dev-data.disk-controller_pci_addr.domain;
-   bus= dev-data.disk-controller_pci_addr.bus;
-   slot   = dev-data.disk-controller_pci_addr.slot;
-
 if (dev-data.disk-controller_name) {
-/* TODO: Obtain the PCI address of the controller
-   from the data structures using the ID */
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (STREQ(dev-data.disk-controller_name,
+  vm-def-controllers[i]-name)) {
+break;
+}
+}
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
+
+domain = vm-def-controllers[i]-address-data.pci.domain;
+bus= vm-def-controllers[i]-address-data.pci.bus;
+slot   = vm-def-controllers[i]-address-data.pci.slot;
 } else {
 domain = dev-data.disk-controller_pci_addr.domain;
 bus= dev-data.disk-controller_pci_addr.bus;
 slot   = dev-data.disk-controller_pci_addr.slot;
+
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (domain == 
vm-def-controllers[i]-address-data.pci.domain 
+bus== vm-def-controllers[i]-address-data.pci.bus 
+slot   == vm-def-controllers[i]-address-data.pci.slot)
+break;
+}
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
}
 
 if (dev-data.disk-bus_id != -1) {
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 04/13] Add new domain device: controller

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This augments virDomainDevice with a controller element
that is used to represent disk controllers (e.g., scsi
controllers). The XML format is given by

controller type=scsi name=my_id
   address type=pci domain=0xNUM bus=0xNUM slot=0xNUM/
/controller

where type denotes the disk interface (scsi, ide,...), name
is an arbitrary string that identifies the controller for
disk hotadd/remove, and the address element specifies
the controller address on the PCI bus. Domain, bus and
slot are specified as hexadecimal numbers.

The address element can be omitted; in this case,
an address will be assigned automatically. Currently,
only hotplugging scsi controllers on a PCI bus
is supported, and this only for qemu guests

Routines for parsing this definition and the associated data
structures are included in this commit.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 docs/schemas/domain.rng  |  158 ++--
 src/conf/domain_conf.c   |  279 +-
 src/conf/domain_conf.h   |   48 +++-
 src/libvirt_private.syms |1 -
 src/qemu/qemu_driver.c   |1 -
 src/qemu/qemu_monitor_text.c |   47 +++
 6 files changed, 488 insertions(+), 46 deletions(-)

diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index b75f17e..0d5fb47 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -393,49 +393,129 @@
   define name=disk
 element name=disk
   optional
-attribute name=device
+   attribute name=device
+ choice
+   valuefloppy/value
+   valuedisk/value
+   valuecdrom/value
+ /choice
+   /attribute
+  /optional
+  optional
+   element name=controller
+ optional
+   attribute name=bus
+ ref name=unsignedInt/
+   /attribute
+ /optional
+ optional
+   attribute name=unit
+ ref name=unsignedInt/
+   /attribute
+ /optional
+ choice
+   attribute name=name
+ ref name=genericName/
+   /attribute
+   attribute name=pciaddr
+ !-- Just for testing --
+ ref name=deviceName/
+   /attribute
+ /choice
+   /element
+  /optional
+  choice
+   group
+ attribute name=type
+   valuefile/value
+ /attribute
+ interleave
+   optional
+ element name=source
+   attribute name=file
+ ref name=absFilePath/
+   /attribute
+   empty/
+ /element
+   /optional
+   ref name=diskspec/
+ /interleave
+   /group
+   group
+ attribute name=type
+   valueblock/value
+ /attribute
+ interleave
+   optional
+ element name=source
+   attribute name=dev
+ ref name=deviceName/
+   /attribute
+   empty/
+ /element
+   /optional
+   ref name=diskspec/
+ /interleave
+   /group
+   ref name=diskspec/
+  /choice
+/element
+  /define
+  define name=target
+element name=target
+  attribute name=dev
+ref name=deviceName/
+  /attribute
+  optional
+attribute name=bus
   choice
-valuefloppy/value
-valuedisk/value
-valuecdrom/value
+valueide/value
+valuefdc/value
+valuescsi/value
+valuevirtio/value
+valuexen/value
+valueusb/value
+valueuml/value
   /choice
 /attribute
   /optional
-  choice
-group
-  attribute name=type
-valuefile/value
-  /attribute
-  interleave
-optional
-  element name=source
-attribute name=file
-  ref name=absFilePath/
-/attribute
-empty/
-  /element
-/optional
-ref name=diskspec/
-  /interleave
-/group
-group
-  attribute name=type
-valueblock/value
-  /attribute
-  interleave
-optional
-  element name=source
-attribute name=dev
-  ref name=deviceName/
-/attribute
-empty/
-  /element
-/optional
-ref name=diskspec/
-  /interleave
-/group
-ref name=diskspec/
-  /choice
+/element
+  /define
+
+  define name=controller
+element name=controller
+  interleave
+   attribute name=type
+ choice
+   !-- For now, only SCSI is supported --
+   valuescsi/value
+ /choice
+   /attribute

[libvirt] [PATCH 07/13] Implement controller hotplugging

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This enables to hot-add disk controllers without attached
disks into the system. Previously, it was only possible to
(implicitly) add disk controllers in the static machine
configuration.

Notice that the actual functionality is only available
for qemu at present, but other emulators can be extended
likewise.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/conf/domain_conf.c |5 +
 src/qemu/qemu_driver.c |   19 ++-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 91115b6..e90975f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -880,7 +880,6 @@ error:
  goto cleanup;
 }
 
-
 /* Parse the XML definition for a disk
  * @param node XML nodeset to parse for disk definition
  */
@@ -2940,7 +2939,6 @@ virDomainDeviceDefPtr 
virDomainDeviceDefParse(virConnectPtr conn,
 }
 #endif
 
-
 int virDomainDiskInsert(virDomainDefPtr def,
 virDomainDiskDefPtr disk)
 {
@@ -3326,8 +3324,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr 
conn,
 
 def-controllers[def-ncontrollers++] = controller;
 }
-/*qsort(def-controllers, def-ncontrollers, sizeof(*def-controllers),
-  virDomainControllerQSort); */
+
 VIR_FREE(nodes);
 
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1fbfdde..1b20937 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4413,6 +4413,15 @@ try_command:
bus= dev-data.disk-controller_pci_addr.bus;
slot   = dev-data.disk-controller_pci_addr.slot;
 
+if (dev-data.disk-controller_name) {
+/* TODO: Obtain the PCI address of the controller
+   from the data structures using the ID */
+} else {
+domain = dev-data.disk-controller_pci_addr.domain;
+bus= dev-data.disk-controller_pci_addr.bus;
+slot   = dev-data.disk-controller_pci_addr.slot;
+   }
+
 if (dev-data.disk-bus_id != -1) {
 virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
 }
@@ -4568,6 +4577,8 @@ try_command:
 
 VIR_FREE(cmd);
 
+/* Naturally, the controller hotplug reply is identical with
+   any other PCI hotplug reply */
 if (qemudParsePciAddReply(vm, reply, domain, bus, slot)  0) {
 if (!tryOldSyntax  strstr(reply, invalid char in expression)) {
VIR_FREE(reply);
@@ -4582,18 +4593,14 @@ try_command:
 }
 
 /* Also fill in when the address was explicitely specified in
-   case qemu changed it (TODO: Can this really happen?) */
+   case qemu changed it */
 dev-data.controller-address-data.pci.domain = domain;
 dev-data.controller-address-data.pci.bus= bus;
 dev-data.controller-address-data.pci.slot   = slot;
 
 VIR_FREE(reply);
 
-/* NOTE: Sort function is added in a later commit */
 vm-def-controllers[vm-def-ncontrollers++] = dev-data.controller;
-/*qsort(vm-def-disks, vm-def-ndisks, sizeof(*vm-def-disks),
-virDomainDiskQSort);*/
-
 return 0;
 }
 
@@ -4947,6 +4954,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
 virCgroupDenyDevicePath(cgroup,
 dev-data.disk-src);
 }
+} else if (dev-type == VIR_DOMAIN_DEVICE_CONTROLLER) {
+ret = qemudDomainAttachDiskController(dom-conn, vm, dev);
 } else if (dev-type == VIR_DOMAIN_DEVICE_NET) {
 ret = qemudDomainAttachNetDevice(dom-conn, driver, vm, dev, 
qemuCmdFlags);
 } else if (dev-type == VIR_DOMAIN_DEVICE_HOSTDEV) {
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 13/13] Update documentation: Controller

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

Document the controller specification, that is, the controller element
within domain
---
 docs/formatdomain.html.in |   38 ++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 52889af..aada7d9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -345,6 +345,7 @@
   lt;disk type='file'gt;
 lt;driver name=tap type=aiogt;
 lt;source file='/var/lib/xen/images/fv0'/gt;
+lt;controller name='controller0' bus='0' unit='5'gt;
 lt;target dev='hda' bus='ide'/gt;
 lt;encryption type='...'gt;
   ...
@@ -366,6 +367,13 @@
 specifies the fully-qualified path to the file holding the disk. If 
the disk
 codetype/code is block, then the codedev/code attribute 
specifies
 the path to the host device to serve as the disk. span 
class=sinceSince 0.0.3/span/dd
+  dtcodecontroller/code/dt
+  ddIf present, specifies the controller to which the disk is
+  connected. This is useful for disk hotplug as it allows to add 
+  disks to specific controlers. This is currently only possible
+  for scsi drivers. codebus/code and codeunit/unit are
+  facultative and specify the drive position on the controller.
+  /dd
   dtcodetarget/code/dt
   ddThe codetarget/code element controls the bus / device under 
which the
 disk is exposed to the guest OS. The codedev/code attribute 
indicates
@@ -675,6 +683,36 @@ qemu-kvm -net nic,model=? /dev/null
 It takes values xen (paravirtualized), ps2 and usb./dd
 /dl
 
+h4a name=elementsControllerDisk controllers/a/h4
+
+p
+Disk controllers are hosts for hard disks.
+/p
+
+pre
+  ...
+  lt;controller type='scsi' name='controller0'gt;
+ lt;address type='pci' bus='0x00' domain='0x00' slot='0x0a'/gt;
+ lt;/controllergt;
+  .../pre
+
+dl
+  dtcodecontroller/code/dt
+  ddThe codecontroller/code element has a mandatory codetype/code
+   attribute which takes the type of the controller,
+   e.g., codescsi/code. br/
+   codename/code specifies a symbolic identifier for the
+   controller by which it can be addressed.
+
+   The address of the controller on the underlying bus is given
+   by the codeaddress/code subelement. The mandatory
+   element codetype/code specified the bus type for which
+   the address holds and must be the same as for the controller.
+   Currently, only pci is supported, which requires three
+   parameters to denote address: codebus/code, codedomain/code,
+   and codedevice/code. All must be given as hexadecimal numbers.
+  /dd
+/dl
 
 h4a name=elementsGraphicsGraphical framebuffers/a/h4
 
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 11/13] Extract qemu monitor parts for controller hotplug

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This separates the communication with qemu a bit from the more
libvirtish actions.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c   |   61 +--
 src/qemu/qemu_monitor_text.c |   65 ++
 src/qemu/qemu_monitor_text.h |2 +
 3 files changed, 69 insertions(+), 59 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9f44685..289c3c6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4580,12 +4580,7 @@ static int qemudDomainAttachDiskController(virConnectPtr 
conn,
   virDomainObjPtr vm,
   virDomainDeviceDefPtr dev)
 {
-int ret, i;
-char *cmd, *reply;
-char *tmp;
-const char* type = 
virDomainDiskBusTypeToString(dev-data.controller-type);
-int tryOldSyntax = 0;
-unsigned domain, bus, slot;
+int i;
 
 /* Only SCSI controllers are supported at the moment */
 if (dev-data.controller-address 
@@ -4618,59 +4613,7 @@ static int qemudDomainAttachDiskController(virConnectPtr 
conn,
 return -1;
 }
 
-try_command:
-if (dev-data.controller-address != NULL) {
-domain = dev-data.controller-address-data.pci.domain;
-bus= dev-data.controller-address-data.pci.bus;
-slot   = dev-data.controller-address-data.pci.slot;
-
-   ret = virAsprintf(tmp, %.2x:%.2x:%.2x, domain, bus, slot);
-ret |= virAsprintf(cmd, pci_add %s%s storage if=%s,
-  (tryOldSyntax ?  : pci_addr=), tmp, type);
-} else {
-ret = virAsprintf(cmd, pci_add %s storage if=%s,
-  (tryOldSyntax ? 0 : pci_addr=auto), type);
-}
-
-if (ret == -1) {
-virReportOOMError(conn);
-return ret;
-}
-
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(cannot attach %s controller), type);
-VIR_FREE(cmd);
-return -1;
-}
-
-VIR_FREE(cmd);
-
-/* Naturally, the controller hotplug reply is identical with
-   any other PCI hotplug reply */
-if (qemudParsePciAddReply(vm, reply, domain, bus, slot)  0) {
-if (!tryOldSyntax  strstr(reply, invalid char in expression)) {
-   VIR_FREE(reply);
-   tryOldSyntax = 1;
-   goto try_command;
-   }
-
-   qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(adding %s controller failed: %s), type, reply);
-   VIR_FREE(reply);
-   return -1;
-}
-
-/* Also fill in when the address was explicitely specified in
-   case qemu changed it */
-dev-data.controller-address-data.pci.domain = domain;
-dev-data.controller-address-data.pci.bus= bus;
-dev-data.controller-address-data.pci.slot   = slot;
-
-VIR_FREE(reply);
-
-vm-def-controllers[vm-def-ncontrollers++] = dev-data.controller;
-return 0;
+return qemuMonitorAttachDiskController(vm, dev);
 }
 
 static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index f6f3e58..7326d05 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1529,6 +1529,71 @@ qemudParseDriveAddReply(virDomainObjPtr vm,
 return 0;
 }
 
+int qemuMonitorAttachDiskController(virDomainObjPtr vm,
+virDomainDeviceDefPtr dev)
+{
+int ret;
+char *cmd, *reply;
+char *tmp;
+const char* type = 
virDomainDiskBusTypeToString(dev-data.controller-type);
+int tryOldSyntax = 0;
+unsigned domain, bus, slot;
+
+try_command:
+if (dev-data.controller-address != NULL) {
+domain = dev-data.controller-address-data.pci.domain;
+   bus= dev-data.controller-address-data.pci.bus;
+   slot   = dev-data.controller-address-data.pci.slot;
+
+   ret = virAsprintf(tmp, %.2x:%.2x:%.2x, domain, bus, slot);
+ret |= virAsprintf(cmd, pci_add %s%s storage if=%s,
+  (tryOldSyntax ?  : pci_addr=), tmp, type);
+} else {
+ret = virAsprintf(cmd, pci_add %s storage if=%s,
+  (tryOldSyntax ? 0 : pci_addr=auto), type);
+}
+
+if (ret == -1) {
+virReportOOMError(NULL);
+return ret;
+}
+
+if (qemuMonitorCommand(vm, cmd, reply)  0) {
+qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ _(cannot attach %s controller), type);
+VIR_FREE(cmd);
+return -1;
+}
+
+VIR_FREE(cmd);
+
+/* Naturally, the controller hotplug reply is identical with
+   any other PCI hotplug reply */
+if (qemuMonitorParsePciAddReply(vm, reply, domain, bus, slot)  0

[libvirt] [PATCH 10/13] Factor out the method to get the PCI address of a controller for a given disk

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

We need this multiple times later on.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/conf/domain_conf.c |   26 ++
 src/conf/domain_conf.h |8 ++
 src/qemu/qemu_driver.c |  242 +++-
 3 files changed, 153 insertions(+), 123 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e90975f..48015a2 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1077,37 +1077,20 @@ virDomainDiskDefParseXML(virConnectPtr conn,
def-unit_id = -1;
if (unit_id  virStrToLong_i(unit_id, NULL, 10, def-unit_id)  0) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
-_(Cannot parse controller 'unit' attribute));
-   goto error;
-   }
-
-   /* TODO: Should we re-use devaddr for this purpose,
-   or is an extra field justified? */
-   if (controller_pci_addr 
-   sscanf(controller_pci_addr, %x:%x:%x,
-  def-controller_pci_addr.domain,
-  def-controller_pci_addr.bus,
-  def-controller_pci_addr.slot)  3) {
-   virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
- _(Unable to parse controller 'pci_addr' parameter '%s'),
-controller_pci_addr);
+   _(Cannot parse controller 'unit' 
attribute));
goto error;
}
 }
 
 /* TODO: Should we re-use devaddr for this purpose,
or is an extra field justified? */
-def-controller_pci_addr.domain = -1;
-def-controller_pci_addr.bus = -1;
-def-controller_pci_addr.slot = -1;
-
 if (controller_pci_addr 
 sscanf(controller_pci_addr, %x:%x:%x,
def-controller_pci_addr.domain,
def-controller_pci_addr.bus,
def-controller_pci_addr.slot)  3) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
- _(Unable to parse controller 'pciaddr' 
parameter '%s'),
+   _(Unable to parse controller 'pci_addr' parameter '%s'),
  controller_pci_addr);
 goto error;
 }
@@ -1215,6 +1198,11 @@ virDomainControllerDefParseXML(virConnectPtr conn,
 }
 
 def-name = virXMLPropString(node, name);
+if (!def-name) {
+virDomainReportError(conn, VIR_ERR_INVALID_ARG,
+ _(cannot use controller without name));
+goto error;
+}
 
 cur = node-children;
 while (cur != NULL) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b30d08c..e058c56 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -171,6 +171,14 @@ virDiskHasValidPciAddr(virDomainDiskDefPtr def)
 return def-pci_addr.domain || def-pci_addr.bus || def-pci_addr.slot;
 }
 
+static inline int
+virDiskHasValidController(virDomainDiskDefPtr def)
+{
+return def-controller_name != NULL ||
+def-controller_pci_addr.domain || def-controller_pci_addr.domain
+|| def-controller_pci_addr.slot;
+}
+
 
 /* Two types of disk backends */
 enum virDomainFSType {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4f647c4..9f44685 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4356,44 +4356,20 @@ static int 
qemudDomainChangeEjectableMedia(virConnectPtr conn,
 return ret;
 }
 
-static int qemudDomainAttachDiskDevice(virConnectPtr conn,
-   virDomainObjPtr vm,
-   virDomainDeviceDefPtr dev)
-{
-int ret, i;
-char *cmd, *reply;
-char *safe_path;
-/* NOTE: Later patch will use type of the controller instead
-   of the disk */
-const char* type = virDomainDiskBusTypeToString(dev-data.disk-bus);
-int tryOldSyntax = 0;
-unsigned domain, bus, slot;
-int bus_id, unit_id;
-virBuffer buf = VIR_BUFFER_INITIALIZER;
-char* bus_unit_string;
-int controller_specified;
-
-for (i = 0 ; i  vm-def-ndisks ; i++) {
-if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-   _(target %s already exists), dev-data.disk-dst);
-return -1;
-}
-}
-
-if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks+1)  0) {
-virReportOOMError(conn);
-return -1;
-}
-
-try_command:
-safe_path = qemudEscapeMonitorArg(dev-data.disk-src);
-if (!safe_path) {
-virReportOOMError(conn);
-return -1;
-}
+enum {
+CONTROLLER_FOUND  =  0,
+NO_CONTROLLER_FOUND   = -1, /* None specified, and none found */
+CONTROLLER_INEXISTENT = -2, /* Controller specified, but not found */
+};
+static virDomainControllerDefPtr
+qemudGetDiskController(virDomainObjPtr vm

[libvirt] [PATCH 12/13] Extract monitor parts from the qemu interaction for disk hotplug

2009-11-16 Thread wolfgang . mauerer
From: Wolfgang Mauerer wolfgang.maue...@siemens.com

This separates the communication with qemu a bit from the more
libvirtish actions.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu/qemu_driver.c   |   82 ++--
 src/qemu/qemu_monitor_text.c |   85 ++
 src/qemu/qemu_monitor_text.h |5 ++
 3 files changed, 95 insertions(+), 77 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 289c3c6..df22035 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4445,15 +4445,8 @@ static int qemudDomainAttachDiskDevice(virConnectPtr 
conn,
   virDomainDeviceDefPtr dev)
 {
 int ret, i;
-char *cmd, *reply;
-char *safe_path;
-const char* type = NULL;
-int tryOldSyntax = 0;
-int bus_id, unit_id;
-int domain, bus, slot;
 virDomainControllerDefPtr conPtr;
-virBuffer buf = VIR_BUFFER_INITIALIZER;
-char* bus_unit_string;
+const char* type = NULL;
 
 /* Both controller and disk can specify a type like SCSI. While
a virtual disk as such is not bound to a specific bus type,
@@ -4485,13 +4478,6 @@ static int qemudDomainAttachDiskDevice(virConnectPtr 
conn,
 return -1;
 }
 
-try_command:
-safe_path = qemudEscapeMonitorArg(dev-data.disk-src);
-if (!safe_path) {
-virReportOOMError(conn);
-return -1;
-}
-
 conPtr = qemudGetDiskController(vm, dev, ret);
 if (!conPtr) {
 switch (ret) {
@@ -4510,70 +4496,12 @@ try_command:
 
 /* At this point, we have a valid controller, regardless if an explicit
controller has been specified or not. */
-domain = conPtr-address-data.pci.domain;
-bus= conPtr-address-data.pci.bus;
-slot   = conPtr-address-data.pci.slot;
-
-if (dev-data.disk-bus_id != -1) {
-   virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
-}
-
-if (dev-data.disk-unit_id != -1) {
-virBufferVSprintf(buf, ,unit=%d, dev-data.disk-unit_id);
-}
-
-bus_unit_string = virBufferContentAndReset(buf);
-
-VIR_DEBUG (%s: drive_add %.2x:%.2x:%.2x file=%s,if=%s%s, vm-def-name,
-   domain, bus, slot, safe_path, type,
-   bus_unit_string ? bus_unit_string : );
-ret = virAsprintf(cmd, drive_add %s%.2x:%.2x:%.2x file=%s,if=%s%s,
-  (tryOldSyntax ?  : pci_addr=), domain, bus,
-  slot, safe_path, type,
-  bus_unit_string ? bus_unit_string : );
-
-VIR_FREE(safe_path);
-if (ret == -1) {
-virReportOOMError(conn);
-return ret;
-}
+ret = qemuMonitorAttachDiskDevice(vm, dev, conPtr, type);
 
-if (qemudMonitorCommand(vm, cmd, reply)  0) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(cannot attach %s disk), type);
-VIR_FREE(cmd);
-return -1;
-}
-
-VIR_FREE(cmd);
-
-if (qemudParseDriveAddReply(vm, reply, bus_id, unit_id)  0) {
-if (!tryOldSyntax  strstr(reply, invalid char in expression)) {
-VIR_FREE(reply);
-tryOldSyntax = 1;
-goto try_command;
-}
-qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(adding %s disk failed: %s), type, reply);
-VIR_FREE(reply);
-return -1;
-}
-
-if (dev-data.disk-bus_id == -1) {
-dev-data.disk-bus_id = bus_id;
-}
-
-if (dev-data.disk-unit_id == -1) {
-dev-data.disk-unit_id = unit_id;
-}
-
-dev-data.disk-pci_addr.domain = domain;
-dev-data.disk-pci_addr.bus= bus;
-dev-data.disk-pci_addr.slot   = slot;
-
-virDomainDiskInsertPreAlloced(vm-def, dev-data.disk);
+if (!ret)
+virDomainDiskInsertPreAlloced(vm-def, dev-data.disk);
 
-return 0;
+return ret;
 }
 
 static int qemudDomainAttachDiskController(virConnectPtr conn,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 7326d05..371388f 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1594,6 +1594,91 @@ try_command:
 return 0;
 }
 
+int qemuMonitorAttachDiskDevice(virDomainObjPtr vm,
+virDomainDeviceDefPtr dev,
+virDomainControllerDefPtr conPtr,
+const char *type)
+{
+int ret;
+char *cmd, *reply;
+char *safe_path;
+int tryOldSyntax = 0;
+int bus_id, unit_id;
+int domain, bus, slot;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char* bus_unit_string;
+
+domain = conPtr-address-data.pci.domain;
+bus= conPtr-address-data.pci.bus;
+slot   = conPtr-address-data.pci.slot;
+
+if (dev-data.disk-bus_id != -1) {
+   virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
+}
+
+if (dev

Re: [libvirt] [PATCH 0/9] Support disk-hotremove and controller hotplugging

2009-10-13 Thread Wolfgang Mauerer
Hi,

Gerd Hoffmann wrote:
 On 10/09/09 18:32, Daniel Veillard wrote:
 On Fri, Sep 18, 2009 at 05:26:07PM +0200, Wolfgang Mauerer wrote:
 Hi,
Hi Wolfgang,

 this patch reworks libvirt's disk-hotadd support and
 introduces support for disk controller hotplugging and disk-hotremove
 (see http://thread.gmane.org/gmane.comp.emulators.libvirt/15860 for
 more details). Currently, it targets only qemu and also requires some
 additions to qemu that have only recently been submitted, which is
 why this  is cross-posted to qemu-devel. Hopefully the lack of support
 in qemu does not prevent the community from reviewing the code,
 though ;-)
Could you update us on the status for those patches, is there
 any chance to get this in QEmu upstream ? I have only seen feddback
 from Gerd Hoffmann on that thread but maybe I'm missing some of the
 action !

sorry, I did not get that mail for some reason, so I did not reply.
 
 Note: upstream qemu got device_add and device_del monitor commands 
 meanwhile which can be used to hotplug devices.
 
 device_add accepts the same syntax the -device command line switch expects.
 
 device_del expectes an id.
 
 For libvirt it probably makes sense to start supporting this when 
 switching over to -device (probably for qemu 0.12+).

Since it does most likely not make sense to include my
drive_del implementation into qemu 0.11 mainline, I'll add libvirt
support for these after I finish doing the structural changes
suggested by Daniel Berrange.

Cheers, Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 5/9] Implement controller hotplugging

2009-09-25 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Fri, Sep 18, 2009 at 05:26:12PM +0200, Wolfgang Mauerer wrote:
 This enables to hot-add disk controllers without attached
 disks into the system. Previously, it was only possible to
 (implicitly) add disk controllers in the static machine
 configuration.

 Notice that the actual functionality is only available
 for qemu at present, but other emulators can be extended
 likewise.
 
 Any idea what we can do about initial startup? eg, if we start
 a guest with 1 SCSI controller and 1 disk, and then we've then
 hotplugged a 2nd controller, and 1 disk.  When we later boot
 or migrate the same guest, we need to have suitable QEMU command
 line args to make sure we get 2 controllers each with the same
 disk, rather than 1 controller with 2 disks. I'm not sure how
 we do this in QEMU, hopefully the existing args support it in
 some way I've not realized, or failing that the new qdev -device
 args might help us.

I'm not yet sure how to solve that best. I'll take a look at how
the -device can help exactly.

 
 Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
 Signed-off-by: Jan Kiszka jan.kis...@siemens.com
 ---
  src/domain_conf.c|   26 +++---
  src/domain_conf.h|2 ++
  src/libvirt_private.syms |1 +
  src/qemu_driver.c|   21 +
  4 files changed, 43 insertions(+), 7 deletions(-)

 diff --git a/src/domain_conf.c b/src/domain_conf.c
 index d0fda64..ea51fda 100644
 --- a/src/domain_conf.c
 +++ b/src/domain_conf.c
 @@ -647,7 +647,6 @@ void virDomainRemoveInactive(virDomainObjListPtr doms,
  
  }
  
 -
  /* Parse the XML definition for a disk
   * @param node XML nodeset to parse for disk definition
   */
 @@ -2554,6 +2553,27 @@ virDomainDeviceDefPtr 
 virDomainDeviceDefParse(virConnectPtr conn,
  #endif
  
  
 +static int virDomainControllerCompare(virDomainControllerDefPtr a,
 +  virDomainControllerDefPtr b) {
 +if (a-pci_addr.bus == b-pci_addr.bus) {
 +if (a-pci_addr.domain == b-pci_addr.domain) 
 +return a-pci_addr.slot - b-pci_addr.slot;
 +
 +return a-pci_addr.domain - b-pci_addr.domain;
 +}
 +
 +return a-pci_addr.bus - b-pci_addr.bus;
 +}
 +
 +
 +int virDomainControllerQSort(const void *a, const void *b)
 +{
 +const virDomainControllerDefPtr *da = a;
 +const virDomainControllerDefPtr *db = b;
 +
 +return virDomainControllerCompare(*da, *db);
 +}
 +
 
 I know we used todo this for disk devices, but I'd recommand not
 going a qsort of devices when hotplugging/unplugging. For hotplug
 always append to the list, for unplug just shuffle down later 
 devices in the list to fill the hole.

okay.

Thanks, Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 9/9] Implement disk- and controller hotremove

2009-09-25 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Fri, Sep 18, 2009 at 05:26:16PM +0200, Wolfgang Mauerer wrote:
 Since both disks and disk controllers can be dynamically
 added to the system, it makes sense to be also able to remove
 them.
 
 This is the main patch which requires additional support in QEMu
 if I'm understanding your patcheset to qemu-devel correctly. 
Yes, that's right.

 
 diff --git a/src/domain_conf.h b/src/domain_conf.h
 index 17f8b14..c7d49cf 100644
 --- a/src/domain_conf.h
 +++ b/src/domain_conf.h
 @@ -149,6 +149,14 @@ virDiskHasValidPciAddr(virDomainDiskDefPtr def)
  return def-pci_addr.domain || def-pci_addr.domain || 
 def-pci_addr.slot;
  }
  
 +static inline int
 +virDiskHasValidController(virDomainDiskDefPtr def)
 +{
 +return def-controller_id != NULL ||
 +def-controller_pci_addr.domain || def-controller_pci_addr.domain 
 +|| def-controller_pci_addr.slot;
 +}
 +
  
  /* Two types of disk backends */
  enum virDomainFSType {
 diff --git a/src/qemu_driver.c b/src/qemu_driver.c
 index ddc46f6..5ac89a1 100644
 --- a/src/qemu_driver.c
 +++ b/src/qemu_driver.c
 @@ -6204,32 +6204,31 @@ cleanup:
  return ret;
  }
  
 -static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
 -  virDomainObjPtr vm, 
 virDomainDeviceDefPtr dev)
 +static int qemudDomainDetachDiskController(virConnectPtr conn,
 +   virDomainObjPtr vm, 
 virDomainDeviceDefPtr dev)
  {
  int i, ret = -1;
  char *cmd = NULL;
  char *reply = NULL;
 -virDomainDiskDefPtr detach = NULL;
 +virDomainControllerDefPtr detach = NULL;
  int tryOldSyntax = 0;
  
 -for (i = 0 ; i  vm-def-ndisks ; i++) {
 -if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
 -detach = vm-def-disks[i];
 +//virDomainControllerDefPtr is dev-data.controller
 +for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 +if (vm-def-controllers[i]-pci_addr.domain == 
 +dev-data.controller-pci_addr.domain 
 +vm-def-controllers[i]-pci_addr.bus == 
 +dev-data.controller-pci_addr.bus 
 +vm-def-controllers[i]-pci_addr.slot == 
 +dev-data.controller-pci_addr.slot) {
 +detach = vm-def-controllers[i];
  break;
  }
  }
  
  if (!detach) {
  qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
 - _(disk %s not found), dev-data.disk-dst);
 -goto cleanup;
 -}
 -
 -if (!virDiskHasValidPciAddr(detach)) {
 -qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
 - _(disk %s cannot be detached - no PCI address for 
 device),
 -   detach-dst);
 + _(Controller %s not found), dev-data.disk-dst);
  goto cleanup;
  }
  
 @@ -6251,7 +6250,9 @@ try_command:
  
  if (qemudMonitorCommand(vm, cmd, reply)  0) {
  qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
 -  _(failed to execute detach disk %s command), 
 detach-dst);
 + _(failed to execute detach controller %d:%d:%d  \
 +   command), detach-pci_addr.domain,
 + detach-pci_addr.bus, detach-pci_addr.slot);
  goto cleanup;
  }
  
 @@ -6267,6 +6268,124 @@ try_command:
  if (strstr(reply, invalid slot) ||
  strstr(reply, Invalid pci address)) {
  qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
 +  _(failed to detach controller: invalid PCI 
 address %.4x:%.2x:%.2x: %s),
 +  detach-pci_addr.domain,
 +  detach-pci_addr.bus,
 +  detach-pci_addr.slot,
 +  reply);
 +goto cleanup;
 +}
 +
 +if (vm-def-ncontrollers  1) {
 +vm-def-controllers[i] = 
 vm-def-controllers[--vm-def-ncontrollers];
 +if (VIR_REALLOC_N(vm-def-controllers, vm-def-ncontrollers)  0) 
 {
 +virReportOOMError(conn);
 +goto cleanup;
 +}
 +qsort(vm-def-disks, vm-def-ncontrollers, 
 +  sizeof(*vm-def-controllers),
 +  virDomainControllerQSort);
 +} else {
 +VIR_FREE(vm-def-controllers[0]);
 +vm-def-controllers = 0;
 +}
 +ret = 0;
 +
 +cleanup:
 +VIR_FREE(reply);
 +VIR_FREE(cmd);
 +return ret;
 +}
 +
 +static int qemudDomainDetachDiskDevice(virConnectPtr conn,
 +   virDomainObjPtr vm, 
 virDomainDeviceDefPtr dev)
 +{
 +int i, ret = -1;
 +char *cmd = NULL;
 +char *reply = NULL;
 +const char* type;
 +virDomainDiskDefPtr detach = NULL;
 +int tryOldSyntax = 0;
 +
 +/* If bus and unit are specified, use these first to identify
 +   the disk */
 +if (dev-data.disk-controller_pci_addr.domain != -1

Re: [libvirt] [PATCH 3/9] Add new domain device: controller

2009-09-25 Thread Wolfgang Mauerer
Daniel P. Berrange wrote:
 On Fri, Sep 18, 2009 at 05:26:10PM +0200, Wolfgang Mauerer wrote:
 This augments virDomainDevice with a controller element
 that is used to represent disk controllers (e.g., scsi
 controllers). The XML format is given by

 controller type=scsi id=my_id
bus addr=Domain:Bus:Slot
 /controller

 where type denotes the disk interface (scsi, ide,...), id
 is an arbitrary string that identifies the controller for
 disk hotadd/remove, and bus addr denotes the controller address
 on the PCI bus.

 The bus element can be omitted; in this case,
 an address will be assigned automatically. Currently,
 only hotplugging scsi controllers on a PCI bus
 is supported, and this only for qemu guests
 
 As mentioned in the previous patch, I reckon 'id' is better
 called 'name'. 
 
 For PCI addresses, it is desirable to fully normalize the XML
 format, by which I mean have separate attributes for domain,
 bus and slot. We already have a syntax for PCI addresses used
 for host device passthrough, so it'd make sense to use the
 same syntax here for controllers. More broadly, we're probably
 going to have to add a PCI address element to all our devices.
 While it is unlikely we'll need non-PCI addresses, it doesn't
 hurt to make it explicit by adding a type='pci' attribute
 
 Thus I'd suggest
 
 address type='pci' domain='0x' bus='0x06' slot='0x12'/
 
 Instead of
 
 bus addr=Domain:Bus:Slot
 
 In the domain_conf.c/.h parser, we could have a datatype like
 
enum {
   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
 
   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
};
 
typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress;
struct _virDomainDevicePCIAddress {
 unsigned domain;
 unsigned bus;
 unsigned slot;
 unsigned function;
};
typedef struct _virDomainDeviceAddress virDomainDeviceAddress;
struct _virDomainDeviceAddress {
   int type;
   union {
  virDomainDevicePCIAddress pci;
   } data;
};
 
 
 Which we then use in all the places in domain_conf.h wanting
 address information. Obviously we'd not use the 'function'
 field in most places, but doesn't hurt to have it.
 
 And a pair of methods for parsing/formatting this address info
 we can call from all the appropriate locations.

using a generic format for PCi addresses surely makes sense,
especially wrt. the common data structure and parsing routines -
I'll add these into the next series. However, I'm not sure
if using address type='pci' domain='0x' bus='0x06' slot='0x12'/
instead of a simple string provides much of an advantage
and does not just increase the typing strain (though there are
maybe some small advantages for computerised parsing of libvirt
configuration files by other apps).

There's already a generic definition of PCI addresses in
docs/schemas/domain.rng:\approx 1140, I suppose it's your
intention to extend if by a type field?

Thanks, Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/9] Extend disk element with controller information

2009-09-25 Thread Wolfgang Mauerer
Matthias Bolte wrote:
 2009/9/24 Daniel P. Berrange berra...@redhat.com:
 Outside the scope of your patches, I think it would be
 worth adding a 'name' attribute to all devices in the
 libvirt XML as a standardized unique identifier. We
 already have to keep track of a 'name' internally for
 NIC hotplug with QEMU, and with QEMU's qdev work we're
 going to end up having to track a 'name' for pretty much
 all devices. Thus we might as well expose it in the XML

 
 Would this device name be read-only, or would it be editable/writable
 by the user (e.g. through virsh edit)? If it should be read-only, I
 see no problem supporting device names in the ESX driver. But If it
 should be editable/writable it may be a problem to implement this for
 the ESX driver, as I'm currently not aware of any sensible way to
 store such an custom device name in a persistent manner on an ESX
 server.

I suppose having the name read-only suffices. At least I
don't see any particularly important use cases for a
writeable name, especially considering that the name can be
chosen arbitrarily at creation time. And there's still the possibility
to shut down the virtual machine, change names, and restart again
if new names are absolutely required.

Thanks, Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 0/9] Support disk-hotremove and controller hotplugging

2009-09-18 Thread Wolfgang Mauerer
Hi,

this patch reworks libvirt's disk-hotadd support and 
introduces support for disk controller hotplugging and disk-hotremove 
(see http://thread.gmane.org/gmane.comp.emulators.libvirt/15860 for
more details). Currently, it targets only qemu and also requires some 
additions to qemu that have only recently been submitted, which is 
why this  is cross-posted to qemu-devel. Hopefully the lack of support 
in qemu does not prevent the community from reviewing the code, 
though ;-) 

Notice that no documentation and testcases are included yet; I'll
supply those once the interface is fixed and possible issues
are settled.

Thanks for your comments,

Wolfgang

 docs/schemas/domain.rng  |  145 ++
 src/domain_conf.c|  208 -
 src/domain_conf.h|   39 -
 src/libvirt_private.syms |4 +-
 src/qemu_driver.c|  479 +++---
 5 files changed, 802 insertions(+), 73 deletions(-)

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 7/9] Remove surprises in the semantics of disk-hotadd

2009-09-18 Thread Wolfgang Mauerer
When a disk is added without an explicitly specified
controller as host, then try to find the first available
controller. If none exists, do not (as in previous versions)
add a new PCI controller device with the disk attached,
but bail out with an error. Notice that this patch changes
the behaviour as compared to older libvirt releases, as
has been discussed on the mailing list (see
http://thread.gmane.org/gmane.comp.emulators.libvirt/15860)

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu_driver.c |  172 ++---
 1 files changed, 85 insertions(+), 87 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 990f05a..f1c2a45 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5417,68 +5417,81 @@ try_command:
 controller_specified = 1;
 }
 
-if (controller_specified) {
-if (dev-data.disk-controller_id) {
-for (i = 0 ; i  vm-def-ncontrollers ; i++) {
-if (STREQ(dev-data.disk-controller_id, 
-  vm-def-controllers[i]-id)) {
-break;
-}
-}
-
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(Controller does not exist));
-return -1;
-}
+if (!controller_specified) {
+/* Find an appropriate controller for disk-hotadd. Notice that
+   the admissible controller types (SCSI, virtio) have already
+   been checked in qemudDomainAttachDevice. */
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (vm-def-controllers[i]-type ==  dev-data.disk-type)
+break;
+}
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+  _(Cannot find appropriate controller for hot-add));
+return -1;
+}
 
-domain = vm-def-controllers[i]-pci_addr.domain;
-bus= vm-def-controllers[i]-pci_addr.bus;
-slot   = vm-def-controllers[i]-pci_addr.slot;
-} else {
-domain = dev-data.disk-controller_pci_addr.domain;
-bus= dev-data.disk-controller_pci_addr.bus;
-slot   = dev-data.disk-controller_pci_addr.slot;
-
-for (i = 0 ; i  vm-def-ncontrollers ; i++) {
-if (domain ==  vm-def-controllers[i]-pci_addr.domain 
-bus==  vm-def-controllers[i]-pci_addr.bus 
-slot   ==  vm-def-controllers[i]-pci_addr.slot)
-break;
-}
+domain = vm-def-controllers[i]-pci_addr.domain;
+bus= vm-def-controllers[i]-pci_addr.bus;
+slot   = vm-def-controllers[i]-pci_addr.slot;
+}
 
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(Controller does not exist));
-return -1;
+if (controller_specified  dev-data.disk-controller_id) {
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (STREQ(dev-data.disk-controller_id, 
+  vm-def-controllers[i]-id)) {
+break;
 }
-   }
-
-if (dev-data.disk-bus_id != -1) {
-virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
 }
 
-if (dev-data.disk-unit_id != -1) {
-virBufferVSprintf(buf, ,unit=%d, dev-data.disk-unit_id);
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
+
+domain = vm-def-controllers[i]-pci_addr.domain;
+bus= vm-def-controllers[i]-pci_addr.bus;
+slot   = vm-def-controllers[i]-pci_addr.slot;
+} else if (controller_specified) {
+domain = dev-data.disk-controller_pci_addr.domain;
+bus= dev-data.disk-controller_pci_addr.bus;
+slot   = dev-data.disk-controller_pci_addr.slot;
+
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (domain ==  vm-def-controllers[i]-pci_addr.domain 
+bus==  vm-def-controllers[i]-pci_addr.bus 
+slot   ==  vm-def-controllers[i]-pci_addr.slot)
+break;
 }
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
+}
 
-bus_unit_string = virBufferContentAndReset(buf);
-
-VIR_DEBUG (%s: drive_add %d:%d:%d file=%s,if=%s%s, vm-def-name,
-   domain, bus, slot, safe_path, type

[libvirt] [PATCH 9/9] Implement disk- and controller hotremove

2009-09-18 Thread Wolfgang Mauerer
Since both disks and disk controllers can be dynamically
added to the system, it makes sense to be also able to remove
them.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/domain_conf.h |8 +++
 src/qemu_driver.c |  161 +++-
 2 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/src/domain_conf.h b/src/domain_conf.h
index 17f8b14..c7d49cf 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -149,6 +149,14 @@ virDiskHasValidPciAddr(virDomainDiskDefPtr def)
 return def-pci_addr.domain || def-pci_addr.domain || def-pci_addr.slot;
 }
 
+static inline int
+virDiskHasValidController(virDomainDiskDefPtr def)
+{
+return def-controller_id != NULL ||
+def-controller_pci_addr.domain || def-controller_pci_addr.domain 
+|| def-controller_pci_addr.slot;
+}
+
 
 /* Two types of disk backends */
 enum virDomainFSType {
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index ddc46f6..5ac89a1 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6204,32 +6204,31 @@ cleanup:
 return ret;
 }
 
-static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
-  virDomainObjPtr vm, 
virDomainDeviceDefPtr dev)
+static int qemudDomainDetachDiskController(virConnectPtr conn,
+   virDomainObjPtr vm, 
virDomainDeviceDefPtr dev)
 {
 int i, ret = -1;
 char *cmd = NULL;
 char *reply = NULL;
-virDomainDiskDefPtr detach = NULL;
+virDomainControllerDefPtr detach = NULL;
 int tryOldSyntax = 0;
 
-for (i = 0 ; i  vm-def-ndisks ; i++) {
-if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-detach = vm-def-disks[i];
+//virDomainControllerDefPtr is dev-data.controller
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (vm-def-controllers[i]-pci_addr.domain == 
+dev-data.controller-pci_addr.domain 
+vm-def-controllers[i]-pci_addr.bus == 
+dev-data.controller-pci_addr.bus 
+vm-def-controllers[i]-pci_addr.slot == 
+dev-data.controller-pci_addr.slot) {
+detach = vm-def-controllers[i];
 break;
 }
 }
 
 if (!detach) {
 qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _(disk %s not found), dev-data.disk-dst);
-goto cleanup;
-}
-
-if (!virDiskHasValidPciAddr(detach)) {
-qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _(disk %s cannot be detached - no PCI address for 
device),
-   detach-dst);
+ _(Controller %s not found), dev-data.disk-dst);
 goto cleanup;
 }
 
@@ -6251,7 +6250,9 @@ try_command:
 
 if (qemudMonitorCommand(vm, cmd, reply)  0) {
 qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
-  _(failed to execute detach disk %s command), 
detach-dst);
+ _(failed to execute detach controller %d:%d:%d  \
+   command), detach-pci_addr.domain,
+ detach-pci_addr.bus, detach-pci_addr.slot);
 goto cleanup;
 }
 
@@ -6267,6 +6268,124 @@ try_command:
 if (strstr(reply, invalid slot) ||
 strstr(reply, Invalid pci address)) {
 qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+  _(failed to detach controller: invalid PCI address 
%.4x:%.2x:%.2x: %s),
+  detach-pci_addr.domain,
+  detach-pci_addr.bus,
+  detach-pci_addr.slot,
+  reply);
+goto cleanup;
+}
+
+if (vm-def-ncontrollers  1) {
+vm-def-controllers[i] = 
vm-def-controllers[--vm-def-ncontrollers];
+if (VIR_REALLOC_N(vm-def-controllers, vm-def-ncontrollers)  0) {
+virReportOOMError(conn);
+goto cleanup;
+}
+qsort(vm-def-disks, vm-def-ncontrollers, 
+  sizeof(*vm-def-controllers),
+  virDomainControllerQSort);
+} else {
+VIR_FREE(vm-def-controllers[0]);
+vm-def-controllers = 0;
+}
+ret = 0;
+
+cleanup:
+VIR_FREE(reply);
+VIR_FREE(cmd);
+return ret;
+}
+
+static int qemudDomainDetachDiskDevice(virConnectPtr conn,
+   virDomainObjPtr vm, 
virDomainDeviceDefPtr dev)
+{
+int i, ret = -1;
+char *cmd = NULL;
+char *reply = NULL;
+const char* type;
+virDomainDiskDefPtr detach = NULL;
+int tryOldSyntax = 0;
+
+/* If bus and unit are specified, use these first to identify
+   the disk */
+if (dev-data.disk-controller_pci_addr.domain != -1) {
+for (i = 0 ; i  vm-def-ndisks ; i++) {
+if (dev-data.disk-bus_id != -1 
+dev

[libvirt] [PATCH 2/9] Extend disk element with controller information

2009-09-18 Thread Wolfgang Mauerer
This allows us to connect a disk with a specific controller,
which is required for disk hotadd/remove. A new XML child
element is added to the disk container:

disk
...
controller pci_addr=addr id=identifier bus=number 
unit=number/
/disk

Either id _or_ pci_addr can be specified. When the controller
has been brought into the system via tghe hotplug mechanism also
included in this patch series, it will typically have an ID.
In other cases, the controller can also be specified with
the PCI address.

Wrt. the data structures touched in this commit, notice
that while bus as subelement of target specifies
the type of bus (e.g., scsi, ide,...), it is used
to enumerate the buses on the controller here.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/domain_conf.c |   29 +
 src/domain_conf.h |5 -
 2 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/src/domain_conf.c b/src/domain_conf.c
index 5ae0775..a6120c8 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -650,7 +650,12 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 char *driverType = NULL;
 char *source = NULL;
 char *target = NULL;
+char *controller = NULL;
+char *bus_id = NULL;
+char *unit_id = NULL;
+char *controller_id = NULL;
 char *bus = NULL;
+char *unit = NULL;
 char *cachetag = NULL;
 char *devaddr = NULL;
 virStorageEncryptionPtr encryption = NULL;
@@ -694,12 +699,18 @@ virDomainDiskDefParseXML(virConnectPtr conn,
(xmlStrEqual(cur-name, BAD_CAST target))) {
 target = virXMLPropString(cur, dev);
 bus = virXMLPropString(cur, bus);
+unit = virXMLPropString(cur, unit);
 
 /* HACK: Work around for compat with Xen
  * driver in previous libvirt releases */
 if (target 
 STRPREFIX(target, ioemu:))
 memmove(target, target+6, strlen(target)-5);
+} else if ((controller == NULL) 
+   (xmlStrEqual(cur-name, BAD_CAST controller))) {
+ controller_id = virXMLPropString(cur, id);
+ bus_id = virXMLPropString(cur, bus);
+ unit_id = virXMLPropString(cur, unit);
 } else if ((driverName == NULL) 
(xmlStrEqual(cur-name, BAD_CAST driver))) {
 driverName = virXMLPropString(cur, name);
@@ -800,6 +811,24 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 }
 }
 
+if (controller) {
+def-controller_id = controller_id;
+
+   def-bus_id = -1;
+   if (bus_id  virStrToLong_i(bus_id, NULL, 10, def-bus_id)  0) {
+   virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+_(Cannot parse controller 'bus' attribute));
+   goto error;
+  } 
+
+   def-unit_id = -1;
+   if (unit_id  virStrToLong_i(unit_id, NULL, 10, def-unit_id)  0) {
+   virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+_(Cannot parse controller 'unit' attribute));
+   goto error;
+   } 
+}
+
 if (def-device == VIR_DOMAIN_DISK_DEVICE_FLOPPY 
 def-bus != VIR_DOMAIN_DISK_BUS_FDC) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 09368d9..898f6c9 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -105,9 +105,12 @@ typedef virDomainDiskDef *virDomainDiskDefPtr;
 struct _virDomainDiskDef {
 int type;
 int device;
-int bus;
+int bus;  /* Bus type, e.g. scsi or ide */
+int bus_id;   /* Bus number on the controller */
+int unit_id;  /* Unit on the controller */
 char *src;
 char *dst;
+char *controller_id;
 char *driverName;
 char *driverType;
 char *serial;
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 5/9] Implement controller hotplugging

2009-09-18 Thread Wolfgang Mauerer
This enables to hot-add disk controllers without attached
disks into the system. Previously, it was only possible to
(implicitly) add disk controllers in the static machine
configuration.

Notice that the actual functionality is only available
for qemu at present, but other emulators can be extended
likewise.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/domain_conf.c|   26 +++---
 src/domain_conf.h|2 ++
 src/libvirt_private.syms |1 +
 src/qemu_driver.c|   21 +
 4 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/domain_conf.c b/src/domain_conf.c
index d0fda64..ea51fda 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -647,7 +647,6 @@ void virDomainRemoveInactive(virDomainObjListPtr doms,
 
 }
 
-
 /* Parse the XML definition for a disk
  * @param node XML nodeset to parse for disk definition
  */
@@ -2554,6 +2553,27 @@ virDomainDeviceDefPtr 
virDomainDeviceDefParse(virConnectPtr conn,
 #endif
 
 
+static int virDomainControllerCompare(virDomainControllerDefPtr a,
+  virDomainControllerDefPtr b) {
+if (a-pci_addr.bus == b-pci_addr.bus) {
+if (a-pci_addr.domain == b-pci_addr.domain) 
+return a-pci_addr.slot - b-pci_addr.slot;
+
+return a-pci_addr.domain - b-pci_addr.domain;
+}
+
+return a-pci_addr.bus - b-pci_addr.bus;
+}
+
+
+int virDomainControllerQSort(const void *a, const void *b)
+{
+const virDomainControllerDefPtr *da = a;
+const virDomainControllerDefPtr *db = b;
+
+return virDomainControllerCompare(*da, *db);
+}
+
 int virDomainDiskInsert(virDomainDefPtr def,
 virDomainDiskDefPtr disk)
 {
@@ -2935,8 +2955,8 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr 
conn,
 
 def-controllers[def-ncontrollers++] = controller;
 }
-/*qsort(def-controllers, def-ncontrollers, sizeof(*def-controllers),
-  virDomainControllerQSort); */
+qsort(def-controllers, def-ncontrollers, sizeof(*def-controllers),
+  virDomainControllerQSort);
 VIR_FREE(nodes);
 
 
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 41df8f6..17f8b14 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -728,6 +728,8 @@ int virDomainDiskInsert(virDomainDefPtr def,
 void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
virDomainDiskDefPtr disk);
 
+int virDomainControllerQSort(const void *a, const void *b);
+
 int virDomainSaveXML(virConnectPtr conn,
  const char *configDir,
  virDomainDefPtr def,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f724493..ecc1123 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -86,6 +86,7 @@ virDomainDiskDefFree;
 virDomainDiskDeviceTypeToString;
 virDomainDiskInsert;
 virDomainDiskInsertPreAlloced;
+virDomainControllerQSort;
 virDomainFindByID;
 virDomainFindByName;
 virDomainFindByUUID;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 4a30615..3bdd2d7 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5424,6 +5424,15 @@ try_command:
bus= dev-data.disk-controller_pci_addr.bus;
slot   = dev-data.disk-controller_pci_addr.slot;
 
+if (dev-data.disk-controller_id) {
+/* TODO: Obtain the PCI address of the controller
+   from the data structures using the ID */
+} else {
+domain = dev-data.disk-controller_pci_addr.domain;
+bus= dev-data.disk-controller_pci_addr.bus;
+slot   = dev-data.disk-controller_pci_addr.slot;
+   }
+
 if (dev-data.disk-bus_id != -1) {
 virBufferVSprintf(buf, ,bus=%d, dev-data.disk-bus_id);
 }
@@ -5582,6 +5591,8 @@ try_command:
 
 VIR_FREE(cmd);
 
+/* Naturally, the controller hotplug reply is identical with
+   any other PCI hotplug reply */
 if (qemudParsePciAddReply(vm, reply, domain, bus, slot)  0) {
 if (!tryOldSyntax  strstr(reply, invalid char in expression)) {
VIR_FREE(reply);
@@ -5596,17 +5607,17 @@ try_command:
 }

 /* Also fill in when the address was explicitely specified in
-   case qemu changed it (TODO: Can this really happen?) */
+   case qemu changed it */
 dev-data.controller-pci_addr.domain = domain;
 dev-data.controller-pci_addr.bus= bus;
 dev-data.controller-pci_addr.slot   = slot;
 
 VIR_FREE(reply);
 
-/* NOTE: Sort function is added in a later commit */
 vm-def-controllers[vm-def-ncontrollers++] = dev-data.controller;
-/*qsort(vm-def-disks, vm-def-ndisks, sizeof(*vm-def-disks),
-virDomainDiskQSort);*/
+qsort(vm-def-controllers, vm-def-ncontrollers, 
+  sizeof(*vm-def-controllers),
+  virDomainControllerQSort);
 
 return 0;
 }
@@ -6104,6 +6115,8

[libvirt] [PATCH 3/9] Add new domain device: controller

2009-09-18 Thread Wolfgang Mauerer
This augments virDomainDevice with a controller element
that is used to represent disk controllers (e.g., scsi
controllers). The XML format is given by

controller type=scsi id=my_id
   bus addr=Domain:Bus:Slot
/controller

where type denotes the disk interface (scsi, ide,...), id
is an arbitrary string that identifies the controller for
disk hotadd/remove, and bus addr denotes the controller address
on the PCI bus.

The bus element can be omitted; in this case,
an address will be assigned automatically. Currently,
only hotplugging scsi controllers on a PCI bus
is supported, and this only for qemu guests

Routines for parsing this definition and the associated data
structures are included in this commit.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 docs/schemas/domain.rng |  145 ++-
 src/domain_conf.c   |  125 
 src/domain_conf.h   |   24 
 3 files changed, 255 insertions(+), 39 deletions(-)

diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 70e98a7..dc9b849 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -364,49 +364,116 @@
   define name=disk
 element name=disk
   optional
-attribute name=device
+   attribute name=device
+ choice
+   valuefloppy/value
+   valuedisk/value
+   valuecdrom/value
+ /choice
+   /attribute
+  /optional
+  optional
+   element name=controller
+ optional
+   attribute name=bus
+ ref name=unsignedInt/
+   /attribute
+ /optional
+ optional
+   attribute name=unit
+ ref name=unsignedInt/
+   /attribute
+ /optional
+ choice
+   attribute name=id
+ ref name=genericName/
+   /attribute
+   attribute name=pciaddr
+ !-- Just for testing --
+ ref name=deviceName/
+   /attribute
+ /choice
+   /element
+  /optional
+  choice
+   group
+ attribute name=type
+   valuefile/value
+ /attribute
+ interleave
+   optional
+ element name=source
+   attribute name=file
+ ref name=absFilePath/
+   /attribute
+   empty/
+ /element
+   /optional
+   ref name=diskspec/
+ /interleave
+   /group
+   group
+ attribute name=type
+   valueblock/value
+ /attribute
+ interleave
+   optional
+ element name=source
+   attribute name=dev
+ ref name=deviceName/
+   /attribute
+   empty/
+ /element
+   /optional
+   ref name=diskspec/
+ /interleave
+   /group
+   ref name=diskspec/
+  /choice
+/element
+  /define
+  define name=target
+element name=target
+  attribute name=dev
+ref name=deviceName/
+  /attribute
+  optional
+attribute name=bus
   choice
-valuefloppy/value
-valuedisk/value
-valuecdrom/value
+valueide/value
+valuefdc/value
+valuescsi/value
+valuevirtio/value
+valuexen/value
+valueusb/value
+valueuml/value
   /choice
 /attribute
   /optional
-  choice
-group
-  attribute name=type
-valuefile/value
-  /attribute
-  interleave
-optional
-  element name=source
-attribute name=file
-  ref name=absFilePath/
-/attribute
-empty/
-  /element
-/optional
-ref name=diskspec/
-  /interleave
-/group
-group
-  attribute name=type
-valueblock/value
-  /attribute
-  interleave
-optional
-  element name=source
-attribute name=dev
-  ref name=deviceName/
-/attribute
-empty/
-  /element
-/optional
-ref name=diskspec/
-  /interleave
-/group
-ref name=diskspec/
-  /choice
+/element
+  /define
+
+  define name=controller
+element name=controller
+  interleave
+   attribute name=type
+ choice
+   !-- For now, only SCSI is supported --
+   valuescsi/value
+ /choice
+   /attribute
+   attribute name=id
+ ref name=genericName/
+   /attribute
+  /interleave
+  optional
+   element name=bus
+ attribute name=addr
+   !-- Just for testing, should be pciaddress --
+   ref name=deviceName/
+ /attribute

[libvirt] [PATCH 6/9] Allow controller selection by ID

2009-09-18 Thread Wolfgang Mauerer
... by simply traversing the list of controllers
to find the associated PCI address.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu_driver.c |   41 +++--
 1 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 3bdd2d7..990f05a 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5418,19 +5418,40 @@ try_command:
 }
 
 if (controller_specified) {
-/* NOTE: Proper check for the controller will be implemented
-   in a later commit */
-   domain = dev-data.disk-controller_pci_addr.domain;
-   bus= dev-data.disk-controller_pci_addr.bus;
-   slot   = dev-data.disk-controller_pci_addr.slot;
-
 if (dev-data.disk-controller_id) {
-/* TODO: Obtain the PCI address of the controller
-   from the data structures using the ID */
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (STREQ(dev-data.disk-controller_id, 
+  vm-def-controllers[i]-id)) {
+break;
+}
+}
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
+
+domain = vm-def-controllers[i]-pci_addr.domain;
+bus= vm-def-controllers[i]-pci_addr.bus;
+slot   = vm-def-controllers[i]-pci_addr.slot;
 } else {
 domain = dev-data.disk-controller_pci_addr.domain;
 bus= dev-data.disk-controller_pci_addr.bus;
 slot   = dev-data.disk-controller_pci_addr.slot;
+
+for (i = 0 ; i  vm-def-ncontrollers ; i++) {
+if (domain ==  vm-def-controllers[i]-pci_addr.domain 
+bus==  vm-def-controllers[i]-pci_addr.bus 
+slot   ==  vm-def-controllers[i]-pci_addr.slot)
+break;
+}
+
+if (i == vm-def-ncontrollers) {
+qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _(Controller does not exist));
+return -1;
+}
}
 
 if (dev-data.disk-bus_id != -1) {
@@ -5457,13 +5478,13 @@ try_command:
 ret = virAsprintf(cmd, pci_add %s storage file=%s,if=%s,
(tryOldSyntax ? 0: pci_addr=auto), safe_path, type);
 }
-
+
 VIR_FREE(safe_path);
 if (ret == -1) {
 virReportOOMError(conn);
 return ret;
 }
-
+
 if (qemudMonitorCommand(vm, cmd, reply)  0) {
 qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
  _(cannot attach %s disk), type);
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 4/9] Add disk-based hotplugging for the qemu backend

2009-09-18 Thread Wolfgang Mauerer
When disks are added to a qemu backend with attach-device,
not just the disk, but a complete new PCI controller with
the disk attached is brought into the system. This patch
implements a proper disk hotplugging scheme for qemu.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/domain_conf.c |   46 --
 src/domain_conf.h |2 +-
 src/qemu_driver.c |  257 
 3 files changed, 277 insertions(+), 28 deletions(-)

diff --git a/src/domain_conf.c b/src/domain_conf.c
index bbaf944..d0fda64 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -663,7 +663,6 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 char *driverType = NULL;
 char *source = NULL;
 char *target = NULL;
-char *controller = NULL;
 char *controller_pci_addr = NULL;
 char *bus_id = NULL;
 char *unit_id = NULL;
@@ -720,12 +719,13 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 if (target 
 STRPREFIX(target, ioemu:))
 memmove(target, target+6, strlen(target)-5);
-} else if ((controller == NULL) 
+} else if ((controller_id == NULL  
+controller_pci_addr == NULL) 
(xmlStrEqual(cur-name, BAD_CAST controller))) {
- controller_id = virXMLPropString(cur, id);
- controller_pci_addr =  virXMLPropString(cur, pci_addr);
- bus_id = virXMLPropString(cur, bus);
- unit_id = virXMLPropString(cur, unit);
+controller_id = virXMLPropString(cur, id);
+controller_pci_addr = virXMLPropString(cur, pciaddr);
+bus_id = virXMLPropString(cur, bus);
+unit_id = virXMLPropString(cur, unit);
 } else if ((driverName == NULL) 
(xmlStrEqual(cur-name, BAD_CAST driver))) {
 driverName = virXMLPropString(cur, name);
@@ -826,7 +826,13 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 }
 }
 
-if (controller) {
+if (controller_id  controller_pci_addr) {
+virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, %s,
+ _(Both controller ID and address specified!));
+goto error;
+}
+
+if (controller_id) {
 def-controller_id = controller_id;
 
def-bus_id = -1;
@@ -857,12 +863,35 @@ virDomainDiskDefParseXML(virConnectPtr conn,
}
 }
 
+/* TODO: Should we re-use devaddr for this purpose,
+   or is an extra field justified? */
+def-controller_pci_addr.domain = -1;
+def-controller_pci_addr.bus = -1;
+def-controller_pci_addr.slot = -1;
+
+if (controller_pci_addr 
+sscanf(controller_pci_addr, %x:%x:%x,
+   def-controller_pci_addr.domain,
+   def-controller_pci_addr.bus,
+   def-controller_pci_addr.slot)  3) {
+virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _(Unable to parse controller 'pciaddr' 
parameter '%s'),
+ controller_pci_addr);
+goto error;
+} 
+
+VIR_DEBUG(Controller PCI addr for disk parsed as %d:%d:%d\n,
+  def-controller_pci_addr.domain,
+  def-controller_pci_addr.bus,
+  def-controller_pci_addr.slot);
+
 if (def-device == VIR_DOMAIN_DISK_DEVICE_FLOPPY 
 def-bus != VIR_DOMAIN_DISK_BUS_FDC) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
  _(Invalid bus type '%s' for floppy disk), bus);
 goto error;
 }
+
 if (def-device != VIR_DOMAIN_DISK_DEVICE_FLOPPY 
 def-bus == VIR_DOMAIN_DISK_BUS_FDC) {
 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -888,6 +917,9 @@ virDomainDiskDefParseXML(virConnectPtr conn,
 goto error;
 }
 
+VIR_DEBUG(Disk PCI address parsed as %d:%d:%d\n, 
+  def-pci_addr.domain, def-pci_addr.bus, def-pci_addr.slot);
+
 def-src = source;
 source = NULL;
 def-dst = target;
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 6b3cb09..41df8f6 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -107,7 +107,7 @@ struct _virDomainDiskDef {
 int device;
 int bus;  /* Bus type, e.g. scsi or ide */
 int bus_id;   /* Bus number on the controller */
-int unit_id;  /* Unit on the controller */
+int unit_id;  /* Unit on the controller (both -1 if unspecified) */
 char *src;
 char *dst;
 char *controller_id;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index a65334f..4a30615 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5264,7 +5264,7 @@ qemudParsePciAddReply(virDomainObjPtr vm,
 {
 char *s, *e;
 
-DEBUG(%s: pci_add reply: %s, vm-def-name, reply);
+VIR_DEBUG(%s: pci_add reply: %s, vm-def-name, reply);
 
 /* If the command succeeds qemu

[libvirt] [PATCH 1/9] Clarify documentation for private symbols

2009-09-18 Thread Wolfgang Mauerer
The instruction See Makefile.am in libvirt.private_syms
always makes me think that this file is autogenerated
and should not be touched manually. This patch spares
every reader of libvirt.private_syms the hassle of
reading Makefile.am before augmenting libvirt.private_syms.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/libvirt_private.syms |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 867678f..f724493 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1,5 +1,6 @@
 #
-# General private symbols. See Makefile.am.
+# General private symbols. Add symbols here, and see Makefile.am for
+# more details.
 #
 
 
-- 
1.6.4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 8/9] Factor out the method to get the PCI address of a controller for a given disk

2009-09-18 Thread Wolfgang Mauerer
We need this multiple times later on.

Signed-off-by: Wolfgang Mauerer wolfgang.maue...@siemens.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 src/qemu_driver.c |  155 +
 1 files changed, 97 insertions(+), 58 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index f1c2a45..ddc46f6 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5370,44 +5370,20 @@ qemudParseDriveAddReply(virDomainObjPtr vm,
 return 0;
 }
 
-static int qemudDomainAttachDiskDevice(virConnectPtr conn,
-  virDomainObjPtr vm,
-  virDomainDeviceDefPtr dev)
-{
-int ret, i;
-char *cmd, *reply;
-char *safe_path;
-/* NOTE: Later patch will use type of the controller instead
-   of the disk */
-const char* type = virDomainDiskBusTypeToString(dev-data.disk-bus);
-int tryOldSyntax = 0;
-unsigned domain, bus, slot;
-int bus_id, unit_id;
-virBuffer buf = VIR_BUFFER_INITIALIZER;
-char* bus_unit_string;
-int controller_specified;
-
-for (i = 0 ; i  vm-def-ndisks ; i++) {
-if (STREQ(vm-def-disks[i]-dst, dev-data.disk-dst)) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-   _(target %s already exists), dev-data.disk-dst);
-return -1;
-}
-}
-
-if (VIR_REALLOC_N(vm-def-disks, vm-def-ndisks+1)  0) {
-virReportOOMError(conn);
-return -1;
-}
-
-try_command:
-safe_path = qemudEscapeMonitorArg(dev-data.disk-src);
-if (!safe_path) {
-virReportOOMError(conn);
-return -1;
-}
+enum {
+CONTROLLER_FOUND  =  0,
+NO_CONTROLLER_FOUND   = -1, /* None specified, and none found */
+CONTROLLER_INEXISTENT = -2, /* Controller specified, but not found */
+};
+static virDomainControllerDefPtr 
+qemudGetDiskController(virDomainObjPtr vm, virDomainDeviceDefPtr dev,
+   int* ret) {
+int controller_specified = 0;
+int domain, bus, slot;
+virDomainControllerDefPtr conPtr = NULL;
+int i;
+*ret = CONTROLLER_FOUND;
 
-controller_specified = 0;
 /* Partially specified PCI addresses (should not happen, anyway)
don't count as specification */
 if (dev-data.disk-controller_id != NULL || 
@@ -5422,38 +5398,28 @@ try_command:
the admissible controller types (SCSI, virtio) have already
been checked in qemudDomainAttachDevice. */
 for (i = 0 ; i  vm-def-ncontrollers ; i++) {
-if (vm-def-controllers[i]-type ==  dev-data.disk-type)
+if (vm-def-controllers[i]-type == dev-data.disk-type)
+conPtr = vm-def-controllers[i]; 
 break;
 }
 
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-  _(Cannot find appropriate controller for hot-add));
-return -1;
+if (!conPtr) {
+*ret = NO_CONTROLLER_FOUND;
 }
-
-domain = vm-def-controllers[i]-pci_addr.domain;
-bus= vm-def-controllers[i]-pci_addr.bus;
-slot   = vm-def-controllers[i]-pci_addr.slot;
 }
 
 if (controller_specified  dev-data.disk-controller_id) {
 for (i = 0 ; i  vm-def-ncontrollers ; i++) {
 if (STREQ(dev-data.disk-controller_id, 
   vm-def-controllers[i]-id)) {
+conPtr = vm-def-controllers[i]; 
 break;
 }
 }
 
-if (i == vm-def-ncontrollers) {
-qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _(Controller does not exist));
-return -1;
+if (!conPtr) {
+*ret = CONTROLLER_INEXISTENT;
 }
-
-domain = vm-def-controllers[i]-pci_addr.domain;
-bus= vm-def-controllers[i]-pci_addr.bus;
-slot   = vm-def-controllers[i]-pci_addr.slot;
 } else if (controller_specified) {
 domain = dev-data.disk-controller_pci_addr.domain;
 bus= dev-data.disk-controller_pci_addr.bus;
@@ -5463,19 +5429,92 @@ try_command:
 if (domain ==  vm-def-controllers[i]-pci_addr.domain 
 bus==  vm-def-controllers[i]-pci_addr.bus 
 slot   ==  vm-def-controllers[i]-pci_addr.slot)
+conPtr = vm-def-controllers[i];
 break;
 }
 
-if (i == vm-def-ncontrollers) {
+if (!conPtr) {
+*ret = CONTROLLER_INEXISTENT;
+}
+}
+
+return conPtr;
+}
+
+static int qemudDomainAttachDiskDevice(virConnectPtr conn,
+  virDomainObjPtr vm,
+  virDomainDeviceDefPtr dev)
+{
+int ret, i;
+char *cmd, *reply;
+char *safe_path;
+const char* type = NULL;
+int

[libvirt] [RFC] Interface for disk hotadd/remove

2009-08-13 Thread Wolfgang Mauerer
Hi,

I'm currently interested in implementing hard disk hot-add and -remove support
for qemu (as opposed to controller-based hotplugging), and this brings up the
question how to best support this feature in libvirt. Many SCSI-Controllers in
real machines, for instance, allow to add and remove disks (without adding or
removing the controller itself) while the system is up and running, so it
would be nice to emulate this in a virtual machine. I'm focusing on
qemu on the backend side, but the problem is not related to this
particular backend. Rather, the question is how to integrate such
a feature best into libvirt.

Before implementing the functionality, it would be great to hear the
community's opinion which route to take wrt. the interface. Essentially, I can
see two options:

- Naturally, there are virDomain{At,De}tachDevice, but the pair implements
 drive-hotadding via adding a new controller with an attached hard disk to
 the system. By extending the XML description of the drive with a parameter
 that specifies whether controller- or disk-based hotplugging is to be
 performed, it would be possible to implement the desired functionality,
 whilst preserving compatibility with existing semantics. Removing the drive
 would then require another new parameter in the XML description to identify
 the drive on the controller, which does not really prettify the thing.

- Extend the API with a new method (for instance virDomainDiskAttach) that
 takes a hard disk description, a controller identifier, and a parameter that
 identifies the disk on the controller.

- (Theoretically, it would also be possible to implement media exchange for
 hard disks in qemu  and re-use the media exchange infrastructure already
 present in libvirt for CD-ROMs, but since this possibility comes to use on
 real hardware only very occasionally, guest operating systems are typically
 not really prepared to handle this well)

My preference would be to go for option 2, that is, implement a new API
method. Would there be any obstacles against adding such a patch to
mainline? Or is anyone already working on similar functionality?  Or can this
be done in a much simpler way I've missed?  If not, then I'd send patches
for more detailed review before long.

Thanks,

Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [RFC] Interface for disk hotadd/remove

2009-08-13 Thread Wolfgang Mauerer
Hi,

On Thu, Aug 13, 2009 at 8:31 PM, Daniel P. Berrangeberra...@redhat.com wrote:
 On Thu, Aug 13, 2009 at 12:54:00PM +0200, Wolfgang Mauerer wrote:
 I'm currently interested in implementing hard disk hot-add and -remove 
 support
 for qemu (as opposed to controller-based hotplugging), and this brings up the
 question how to best support this feature in libvirt. Many SCSI-Controllers 
 in
 real machines, for instance, allow to add and remove disks (without adding or
 removing the controller itself) while the system is up and running, so it
 would be nice to emulate this in a virtual machine. I'm focusing on
 qemu on the backend side, but the problem is not related to this
 particular backend. Rather, the question is how to integrate such
 a feature best into libvirt.

 Before implementing the functionality, it would be great to hear the
 community's opinion which route to take wrt. the interface. Essentially, I 
 can
 see two options:

 - Naturally, there are virDomain{At,De}tachDevice, but the pair implements
  drive-hotadding via adding a new controller with an attached hard disk to
  the system. By extending the XML description of the drive with a parameter
  that specifies whether controller- or disk-based hotplugging is to be
  performed, it would be possible to implement the desired functionality,
  whilst preserving compatibility with existing semantics. Removing the drive
  would then require another new parameter in the XML description to identify
  the drive on the controller, which does not really prettify the thing.

 - Extend the API with a new method (for instance virDomainDiskAttach) that
  takes a hard disk description, a controller identifier, and a parameter that
  identifies the disk on the controller.

 I don't think its desirable to extend the API. The virDomainAttachDevice
 API's XML parameter is intended to take any XML element that is valid
 inside the domain devices XML section.

okay, that's good to know.

 So the key to deciding how to deal with hotplug, is to first decide how
 to represent disk controllers in the domain XML.

 At boot time, if you list multiple  SCSI disks in the XML, you get a single
 controller with multiple disks attached. As such the current semantics of
 the hotplug implementation for SCSI are divergant from the semantics at
 boot time. This has the consequence that if you boot a guest with 2 SCSI
 drives, then hot-attach one more you get 2 controllers, 3 disk. If you
 then shutdown  boot the guest again, you'll have 1 controller, 1 disks.

 This says to me that the hotplug implementation for QEMU SCSI should be
 fixed so that if you supply disk it adds a disk to the existing SCSI
 controller. Obviously it requires some QEMU support for this first.

Qemu support for this is already there (I was not quite clear on that,
the thing I'm currently adding additionally is hot-remove). I completely
agree that the current semantics of libvirt-controlled disk-hotplug in qemu
provide some possibilities for improvement, but I was not sure if it's
okay to change the semantics of a libvirt command whilst preserving its syntax.

 Thus my feeling would be todo something like adding a new controller
 element to represent a disk controller. Support hotplugging controller
 instances directly with obvious semantics.

 Then extend the disk schema to allow a controller name/identifier to
 be provided. If no controller is listed then plug the disk into the
 first available controller slot, otherwise use the explicitly requested
 controller. Never implicitily add new controllers, unless dealing with
 a legacy QEMU without the disk hotplug support that you're writing.

Sounds reasonable to me. Roughly, that would lead to something along
the lines of (for a SCSI host on the PCI bus)

controller type=scsi id=my_controller 
bus addr=00:04/
/controller

disk type=scsi
source file=disk.img/
controller id=my_controller unit=0/
/disk

This allows for specifying both the address of the controller on the
bus, and to identify the disk on the controller -- this is important for
hot-remove if multiple physically identical disks are attached to a single
controller.

If virDomainAttachDevice is fed with a disk element containing
an explicitely specified controller id, libvirt can then simply add the
disk if the controller exists, or add controller+disk if the controller
is not yet present on the machine. If the controller is not specified
and none is present in the system, follow the current behaviour. If
no controller is specified, but a controller is present, just add the
disk, not controller+disk, breaking current behaviour. For hot-remove,
do the reverse action (though I'll consider under which circumstances
it is desirable to remove the controller when a disk is supposed to be
removed, but these details are best discussed once I've done the
code, I suppose).  Does what I've outlined correspond to your idea?

Thanks,

Wolfgang

--
Libvir-list mailing list
Libvir-list@redhat.com