On Mon, May 23, 2011 at 11:09:21AM +0900, KAMEZAWA Hiroyuki wrote: > > Slightly updated against the latest git tree. but didn't update version number. > == > Now, only attach/detatch/update for disks are supporeted for inactive > domains. > This patch allows to modify network interfaces of inactive domains. > Users can modify inactive domains with --persistent flag. > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > > * src/conf/domain_conf.c: > (virDomainNetInsert) : Insert a network device to domain definition. > (virDomainNetIndexByMac) : Returns an index of net device in array. > (virDomainNetRemoveByMac): Remove a NIC of passed MAC address. > > * src/qemu/qemu_driver.c > (qemuDomainAttachDeviceConfig): add codes for NIC. > (qemuDomainDetachDeviceConfig): add codes for NIC. > > Changelog v1->v2: > - fixed virDomainNetInsert > - removed target name check. (It seems I misunderstood something.) > - fixed error check in qemuDomainAttachDeviceConfig > - fixed error message in qemuDomainDetachDeviceConfig > --- > src/conf/domain_conf.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ > src/conf/domain_conf.h | 4 ++++ > src/libvirt_private.syms | 3 +++ > src/qemu/qemu_driver.c | 31 +++++++++++++++++++++++++++++++ > 4 files changed, 83 insertions(+), 0 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 6129bbc..d85c8bc 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -5177,6 +5177,51 @@ int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name) > return 0; > } > > +int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net) > +{ > + if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0) > + return -1; > + def->nets[def->nnets] = net; > + def->nnets++; > + return 0; > +} > + > +int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac) > +{ > + int i; > + > + for (i = 0; i < def->nnets; i++) > + if (!memcmp(def->nets[i]->mac, mac, VIR_MAC_BUFLEN)) > + return i; > + return -1; > +} > + > +static void virDomainNetRemove(virDomainDefPtr def, size_t i) > +{ If i exceeds def->nnets, you may access beyond def->nets, which may corrupt memory. > + 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 */ > + } ignore_value() is provided to ignore a return value. > + } else { > + VIR_FREE(def->nets); > + def->nnets = 0; > + } > +} > + > +int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac) > +{ > + int i = virDomainNetIndexByMac(def, mac); > + > + if (i < 0) > + return -1; > + virDomainNetRemove(def, i); > + return 0; > +} > + > > int virDomainControllerInsert(virDomainDefPtr def, > virDomainControllerDefPtr controller) > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 5fe31d4..f195caa 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1360,6 +1360,10 @@ int virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def); > void virDomainDiskRemove(virDomainDefPtr def, size_t i); > int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name); > > +int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac); > +int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net); Will it be better to add virDomainNetRemove here as a counterpart of virDomainNetInsert? Although no external file uses it. > +int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac); > + > int virDomainControllerInsert(virDomainDefPtr def, > virDomainControllerDefPtr controller); > void virDomainControllerInsertPreAlloced(virDomainDefPtr def, > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 7b6151c..eb55025 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -290,6 +290,9 @@ virDomainLoadAllConfigs; > virDomainMemballoonModelTypeFromString; > virDomainMemballoonModelTypeToString; > virDomainNetDefFree; > +virDomainNetIndexByMac; > +virDomainNetInsert; > +virDomainNetRemoveByMac; > virDomainNetTypeToString; > virDomainObjAssignDef; > virDomainObjCopyPersistentDef; > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 691965d..ef2c5f0 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -4245,6 +4245,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, > virDomainDeviceDefPtr dev) > { > virDomainDiskDefPtr disk; > + virDomainNetDefPtr net; > > switch (dev->type) { > case VIR_DOMAIN_DEVICE_DISK: > @@ -4267,6 +4268,24 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, > return -1; > break; > > + case VIR_DOMAIN_DEVICE_NET: > + net = dev->data.net; > + if (virDomainNetIndexByMac(vmdef, net->mac) >= 0) { > + char macbuf[VIR_MAC_STRING_BUFLEN]; > + > + virFormatMacAddr(net->mac, macbuf); > + qemuReportError(VIR_ERR_INVALID_ARG, > + _("mac %s already exists"), macbuf); > + return -1; > + } > + if (virDomainNetInsert(vmdef, net)) { > + virReportOOMError(); > + return -1; > + } > + dev->data.net = NULL; > + if (qemuDomainAssignPCIAddresses(vmdef) < 0) > + return -1; > + break; > default: > qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > _("persistent attach of device is not supported")); > @@ -4281,6 +4300,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, > virDomainDeviceDefPtr dev) > { > virDomainDiskDefPtr disk; > + virDomainNetDefPtr net; > > switch (dev->type) { > case VIR_DOMAIN_DEVICE_DISK: > @@ -4291,6 +4311,17 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, > return -1; > } > break; > + case VIR_DOMAIN_DEVICE_NET: > + net = dev->data.net; > + if (virDomainNetRemoveByMac(vmdef, net->mac)) { > + char macbuf[VIR_MAC_STRING_BUFLEN]; > + > + virFormatMacAddr(net->mac, macbuf); > + qemuReportError(VIR_ERR_INVALID_ARG, > + _("mac %s doesn't exist."), macbuf); > + return -1; > + } > + break; > default: > qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > _("persistent detach of device is not supported")); > -- > 1.7.4.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list