On Fri, 25 Feb 2011 15:08:19 +0800
Hu Tao <hutao(a)cn.fujitsu.com> wrote:
> +static int qemuDomainFindNetByName(virDomainDefPtr vmdef,
> + const unsigned char *mac)
> +{
> + virDomainNetDefPtr net;
> + int i;
> +
> + for (i = 0; i < vmdef->nnets; i++) {
> + net = vmdef->nets[i];
> + /* For now, only MAC can be the key */
> + if (!strcmp((char*)net->mac, (char*)mac))
ack with STREQ and email address fixed.
fixed.
==
From b2ef98f15a973b134cf1d98f6eee08831d134e89 Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
Date: Fri, 25 Feb 2011 17:19:12 +0900
Subject: [PATCH 3/4] libvirt/qemu - support updating inactive domain interfaces.
Now, virsh attach-disk/detach-disk has --persistent option and
it can update XML definition of inactive domains. But, it's only
supported in Xen.
This patch adds support for attach-disk/detach-disk for qemu.
Note: This patch just allows to modify XML definition of 'inactive'
domain. More patches will be required for modify 'active' domain
in persistent mode. (modify XML + do hotplug)
Changelog v3->v3.1
- use STREQ() instead of strcmp.
Changelog v2->v3:
- clean ups.
- handle all VIR_DOMAIN_DEVICE_MODIFY_XXX flags.
---
src/conf/domain_conf.c | 24 +++++++++++++++++++++
src/conf/domain_conf.h | 3 ++
src/libvirt_private.syms | 2 +
src/qemu/qemu_driver.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b4193b9..6f28c9a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4926,6 +4926,30 @@ void virDomainDiskRemove(virDomainDefPtr def, size_t i)
}
}
+int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net)
+{
+ if (VIR_REALLOC_N(def->nets, def->nnets) < 0)
+ return -1;
+ def->nets[def->nnets] = net;
+ def->nnets++;
+ return 0;
+}
+
+void virDomainNetRemove(virDomainDefPtr def, size_t i)
+{
+ if (def->nnets > 1) {
+ memmove(def->nets + i,
+ def->nets + i + 1,
+ sizeof(*def->nets) * (def->nnets - (i + 1)));
+ def->nnets--;
+ if (VIR_REALLOC_N(def->nets, def->nnets) < 0) {
+ /* ignore harmless */
+ }
+ } else {
+ VIR_FREE(def->nets);
+ def->nnets = 0;
+ }
+}
int virDomainControllerInsert(virDomainDefPtr def,
virDomainControllerDefPtr controller)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 30aeccc..d7d973e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1270,6 +1270,9 @@ int virDomainDiskDefAssignAddress(virCapsPtr caps,
virDomainDiskDefPtr def);
void virDomainDiskRemove(virDomainDefPtr def, size_t i);
+int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
+void virDomainNetRemove(virDomainDefPtr def, size_t i);
+
int virDomainControllerInsert(virDomainDefPtr def,
virDomainControllerDefPtr controller);
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 66917ca..08c06d9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -246,6 +246,8 @@ virDomainDiskIoTypeToString;
virDomainDiskRemove;
virDomainDiskTypeFromString;
virDomainDiskTypeToString;
+virDomainNetInsert;
+virDomainNetRemove;
virDomainFSDefFree;
virDomainFindByID;
virDomainFindByName;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 53f3d95..ca6dfb7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4109,6 +4109,21 @@ static int qemuDomainFindDiskByName(virDomainDefPtr vmdef, const
char *name)
}
return -1;
}
+
+static int qemuDomainFindNetByName(virDomainDefPtr vmdef,
+ const unsigned char *mac)
+{
+ virDomainNetDefPtr net;
+ int i;
+
+ for (i = 0; i < vmdef->nnets; i++) {
+ net = vmdef->nets[i];
+ /* For now, only MAC can be the key */
+ if (STREQ((char*)net->mac, (char*)mac))
+ return i;
+ }
+ return -1;
+}
/*
* Attach a device given by XML, the change will be persistent
* and domain XML definition file is updated.
@@ -4117,6 +4132,7 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef,
virDomainDeviceDefPtr newdev)
{
virDomainDiskDefPtr disk;
+ virDomainNetDefPtr net;
/* At first, check device confliction */
switch(newdev->type) {
@@ -4136,6 +4152,23 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef,
return -1;
newdev->data.disk = NULL;
break;
+ case VIR_DOMAIN_DEVICE_NET:
+ net =
newdev->data.net;
+ if (qemuDomainFindNetByName(vmdef, net->mac) >= 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("target %s already exists."), net->mac);
+ return -1;
+ }
+
+ if (virDomainNetInsert(vmdef, net)) {
+ virReportOOMError();
+ return -1;
+ }
+ /* always PCI ? */
+ if (qemuDomainAssignPCIAddresses(vmdef) < 0)
+ return -1;
+
newdev->data.net = NULL;
+ break;
default:
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
_("Sorry, the device is not suppored for now"));
@@ -4150,6 +4183,7 @@ static int qemuDomainDetachDevicePersistent(virDomainDefPtr vmdef,
{
int x;
virDomainDiskDefPtr disk;
+ virDomainNetDefPtr net;
switch(device->type) {
case VIR_DOMAIN_DEVICE_DISK:
@@ -4162,6 +4196,23 @@ static int qemuDomainDetachDevicePersistent(virDomainDefPtr vmdef,
}
virDomainDiskRemove(vmdef, x);
break;
+ case VIR_DOMAIN_DEVICE_NET:
+ net =
device->data.net;
+ /* need to find mac address */
+ if (net->ifname == NULL && strlen((char*)net->mac) == 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("interface mac or name must be specified."));
+ return -1;
+ }
+ net =
device->data.net;
+ x = qemuDomainFindNetByName(vmdef, net->mac);
+ if (x < 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("interface mac: %s doesn't exist."),
net->mac);
+ return -1;
+ }
+ virDomainNetRemove(vmdef, x);
+ break;
default:
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
_("Sorry, the device is not suppored for now"));
--
1.7.4.1