On-behalf-of: SAP stefan.kober@sap.com
Signed-off-by: Stefan Kober <stefan.kober@cyberus-technology.de>
---
po/POTFILES | 1 +
src/ch/ch_hotplug.c | 131 ++++++++++++++++++++++++++++++++++++++++++--
src/ch/ch_monitor.c | 17 ++++++
src/ch/ch_monitor.h | 4 ++
4 files changed, 149 insertions(+), 4 deletions(-)
diff --git a/po/POTFILES b/po/POTFILES
index dc7293d0cd..50a055fb73 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -24,6 +24,7 @@ src/ch/ch_domain.c
src/ch/ch_driver.c
src/ch/ch_events.c
src/ch/ch_hostdev.c
+src/ch/ch_hotplug.c
src/ch/ch_interface.c
src/ch/ch_monitor.c
src/ch/ch_process.c
diff --git a/src/ch/ch_hotplug.c b/src/ch/ch_hotplug.c
index c46628e7e9..524355b93c 100644
--- a/src/ch/ch_hotplug.c
+++ b/src/ch/ch_hotplug.c
@@ -18,18 +18,141 @@
#include <config.h>
+#include "ch_alias.h"
+#include "ch_domain.h"
#include "ch_hotplug.h"
+#include "domain_event.h"
+#include "domain_validate.h"
+#include "virlog.h"
+
#define VIR_FROM_THIS VIR_FROM_CH
+VIR_LOG_INIT("ch.ch_hotplug");
+
+static int
+chDomainAddDisk(virCHMonitor *mon, virDomainObj *vm, virDomainDiskDef *disk)
+{
+ if (chAssignDeviceDiskAlias(disk) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Assigning disk alias failed"));
+ return -1;
+ }
+
+ if (virCHMonitorAddDisk(mon, disk) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Adding disk to domain failed"));
+ return -1;
+ }
+
+ virDomainDiskInsert(vm->def, disk);
+
+ return 0;
+}
+
+static int
+chDomainAttachDeviceLive(virDomainObj *vm,
+ virDomainDeviceDef *dev)
+{
+ int ret = -1;
+ virCHDomainObjPrivate *priv = vm->privateData;
+ virCHMonitor *mon = priv->monitor;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_DEVICE_DISK: {
+ if (chDomainAddDisk(mon, vm, dev->data.disk) < 0) {
+ break;
+ }
+
+ dev->data.disk = NULL;
+ ret = 0;
+ break;
+ }
+ case VIR_DOMAIN_DEVICE_NET:
+ case VIR_DOMAIN_DEVICE_LEASE:
+ case VIR_DOMAIN_DEVICE_FS:
+ case VIR_DOMAIN_DEVICE_INPUT:
+ case VIR_DOMAIN_DEVICE_HOSTDEV:
+ case VIR_DOMAIN_DEVICE_WATCHDOG:
+ case VIR_DOMAIN_DEVICE_CONTROLLER:
+ case VIR_DOMAIN_DEVICE_REDIRDEV:
+ case VIR_DOMAIN_DEVICE_CHR:
+ case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_SHMEM:
+ case VIR_DOMAIN_DEVICE_MEMORY:
+ case VIR_DOMAIN_DEVICE_VSOCK:
+ case VIR_DOMAIN_DEVICE_NONE:
+ case VIR_DOMAIN_DEVICE_SOUND:
+ case VIR_DOMAIN_DEVICE_VIDEO:
+ case VIR_DOMAIN_DEVICE_GRAPHICS:
+ case VIR_DOMAIN_DEVICE_HUB:
+ case VIR_DOMAIN_DEVICE_SMARTCARD:
+ case VIR_DOMAIN_DEVICE_MEMBALLOON:
+ case VIR_DOMAIN_DEVICE_NVRAM:
+ case VIR_DOMAIN_DEVICE_TPM:
+ case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_IOMMU:
+ case VIR_DOMAIN_DEVICE_AUDIO:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ case VIR_DOMAIN_DEVICE_PSTORE:
+ case VIR_DOMAIN_DEVICE_LAST:
+ default:
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("live attach of device '%1$s' is not supported"),
+ virDomainDeviceTypeToString(dev->type));
+ break;
+ }
+
+ return ret;
+}
+
int
-chDomainAttachDeviceLiveAndUpdateConfig(virDomainObj *vm G_GNUC_UNUSED,
- virCHDriver *driver G_GNUC_UNUSED,
- const char *xml G_GNUC_UNUSED,
+chDomainAttachDeviceLiveAndUpdateConfig(virDomainObj *vm,
+ virCHDriver *driver,
+ const char *xml,
unsigned int flags)
{
+ unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_ABI_UPDATE;
+ g_autoptr(virDomainDeviceDef) devLive = NULL;
+ g_autoptr(virDomainDef) vmdef = NULL;
+ g_autoptr(virCHDriverConfig) cfg = NULL;
+ g_autoptr(virDomainDeviceDef) devConf = NULL;
+
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
- return -1;
+ cfg = virCHDriverGetConfig(driver);
+
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Persistent domain state changes are not supported"));
+ return -1;
+ }
+
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+ if (!(devLive = virDomainDeviceDefParse(xml, vm->def,
+ driver->xmlopt, NULL,
+ parse_flags))) {
+ return -1;
+ }
+
+ if (virDomainDeviceValidateAliasForHotplug(vm, devLive,
+ VIR_DOMAIN_AFFECT_LIVE) < 0)
+ return -1;
+
+ if (virDomainDefCompatibleDevice(vm->def, devLive, NULL,
+ VIR_DOMAIN_DEVICE_ACTION_ATTACH,
+ true) < 0) {
+ return -1;
+ }
+
+ if (chDomainAttachDeviceLive(vm, devLive) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to add device"));
+ return -1;
+ }
+ }
+
+ return 0;
}
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 5f3e2adbee..8968d84a71 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -314,6 +314,23 @@ virCHMonitorBuildDisksJson(virJSONValue *content, virDomainDef *vmdef)
return 0;
}
+int
+virCHMonitorAddDisk(virCHMonitor *monitor,
+ virDomainDiskDef *diskdef)
+{
+ g_autofree char *payload = NULL;
+ g_autoptr(virJSONValue) disks = virJSONValueNewArray();
+ g_autoptr(virJSONValue) response = NULL;
+
+ if (virCHMonitorBuildDiskJson(disks, diskdef) < 0) {
+ return -1;
+ }
+
+ payload = virJSONValueToString(virJSONValueArrayGet(disks, 0), false);
+
+ return virCHMonitorPut(monitor, URL_VM_ADD_DISK, payload, NULL, NULL);
+}
+
static int
virCHMonitorBuildRngJson(virJSONValue *content, virDomainDef *vmdef)
{
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index ffac9e938e..8338059c7c 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -40,6 +40,7 @@
#define URL_VM_INFO "vm.info"
#define URL_VM_SAVE "vm.snapshot"
#define URL_VM_RESTORE "vm.restore"
+#define URL_VM_ADD_DISK "vm.add-disk"
#define VIRCH_THREAD_NAME_LEN 16
@@ -138,6 +139,9 @@ int
virCHMonitorBuildNetJson(virDomainNetDef *netdef,
int netindex,
char **jsonstr);
+int
+virCHMonitorAddDisk(virCHMonitor* mon, virDomainDiskDef *diskdef);
+
int virCHMonitorBuildRestoreJson(virDomainDef *vmdef,
const char *from,
char **jsonstr);
--
2.50.1