On Thu, Feb 24, 2011 at 01:08:40PM +0900, KAMEZAWA Hiroyuki wrote: > >From b06da6d9b4ee996046af72a81c89b90852372e53 Mon Sep 17 00:00:00 2001 > From: KAMEZAWA Hiroyuki <kamezawa@bluextal.(none)> > Date: Thu, 24 Feb 2011 13:08:54 +0900 > Subject: [PATCH 2/2] libvirt/qemu : support attach/detach-interface --persistent with qemu > > Now, virsh attach/detach-interface have --persistent option for > updating inactive domain but it's only supported in Xen. > > This patch adds support for qemu. > > Changelog v1->v2: > - fixed TABs > - fixed header file, type of a function > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > --- > src/conf/domain_conf.c | 50 ++++++++++++++++++++++++++++++++++++++++ > src/conf/domain_conf.h | 3 ++ > src/libvirt_private.syms | 2 + > src/qemu/qemu_driver.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 112 insertions(+), 0 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index b97c1f0..660573b 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -4924,6 +4924,56 @@ void virDomainDiskRemove(virDomainDefPtr def, size_t i) > } > } > > +int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net) Function duplicated. > +{ > + 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) Function duplicated. > +{ > + 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 virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net) Function duplicated. > +{ > + 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) Function duplicated. > +{ > + 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..396dfbc 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); > > +void virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net); prototype mismatch: int c file this function returns int. > +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 797a670..eef5266 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -245,6 +245,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 e75478a..00a240b 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -4097,6 +4097,22 @@ static int qemuDomainFindDiskByName(virDomainDefPtr vmdef, const char *name) > } > return -1; > } > + > +static int qemuDomainFindNetByName(virDomainDefPtr vmdef, > + const unsigned char *mac, const char *ifname) > +{ > + virDomainNetDefPtr net; > + int i; > + > + for (i = 0; i < vmdef->nnets; i++) { > + net = vmdef->nets[i]; > + if (!strcmp((char*)net->mac, (char*)mac)) > + return i; > + if (ifname && !strcmp((char*)net->ifname, (char*)ifname)) > + return i; > + } > + return -1; > +} > /* > * Attach a device given by XML, the change will be persistent > * and domain XML definition file is updated. > @@ -4105,6 +4121,7 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef, > virDomainDeviceDefPtr newdev) > { > virDomainDiskDefPtr disk; > + virDomainNetDefPtr net; > > /* At first, check device confliction */ > switch(newdev->type) { > @@ -4131,6 +4148,22 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef, > } > newdev->data.disk = NULL; > break; > + case VIR_DOMAIN_DEVICE_NET: > + net = newdev->data.net; > + if (qemuDomainFindNetByName(vmdef, net->mac, net->ifname) >= 0) { > + qemuReportError(VIR_ERR_INVALID_ARG, > + _("target %s already exists."), disk->dst); disk->dst -> net->mac or something else about net device. > + return -1; > + } > + > + if (virDomainNetInsert(vmdef, net)) { > + virReportOOMError(); > + return -1; > + } > + /* always PCI ? */ > + qemuDomainAssignPCIAddresses(vmdef); > + newdev->data.net = NULL; > + break; > default: > qemuReportError(VIR_ERR_INVALID_ARG, "%s", > _("Sorry, the device is not suppored for now")); > @@ -4145,6 +4178,7 @@ static int qemuDomainDetachDevicePersistent(virDomainDefPtr vmdef, > { > int x; > virDomainDiskDefPtr disk; > + virDomainNetDefPtr net; > > switch(device->type) { > case VIR_DOMAIN_DEVICE_DISK: > @@ -4157,6 +4191,29 @@ 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, net->ifname); > + if (x < 0) { > + if (net->ifname) > + qemuReportError(VIR_ERR_INVALID_ARG, > + _("interface mac: %s name: %s doesn't exist."), > + net->mac, net->ifname); > + else > + 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.1 -- Thanks, Hu Tao -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list