On Mon, 21 Mar 2011 16:48:23 +0800 Wen Congyang <wency@xxxxxxxxxxxxxx> wrote: > At 03/16/2011 02:46 PM, KAMEZAWA Hiroyuki Write: > >>From d69f7c07571c8adfc7720aab77aa1f103eb6e95b Mon Sep 17 00:00:00 2001 > > From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > > Date: Wed, 16 Mar 2011 15:39:14 +0900 > > Subject: [PATCHv5 3/3] libvirt/qemu - support support persistent modification of qemu interfaces. > > > > support changes of interfaces by VIR_DOMAIN_DEVICE_MODIFY_CONFIG > > for qemu. > > > > Changelog v4->v5 > > - fixed mac handling. > > - moved some functions to domain_conf.c > > - clean up. > > > > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > > --- > > src/conf/domain_conf.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ > > src/conf/domain_conf.h | 5 ++++ > > src/libvirt_private.syms | 4 +++ > > src/qemu/qemu_driver.c | 38 +++++++++++++++++++++++++++++++ > > 4 files changed, 103 insertions(+), 0 deletions(-) > > > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > > index 1d39481..9e4dea6 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -4952,6 +4952,62 @@ int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name) > > return 0; > > } > > > > +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; > > +} > > + > > +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; > > +} > > + > > +int virDomainNetIndexByIfname(virDomainDefPtr def, const char*name) > > +{ > > + int i; > > + > > + for (i = 0; i < def->nnets; i++) { > > + if (def->nets[i]->ifname && STREQ(def->nets[i]->ifname, name)) > > + return i; > > + } > > + return -1; > > +} > > + > > +static 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 virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac) > > +{ > > + int i; > > + > > + 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 320ca13..d5154f6 100644 > > --- a/src/conf/domain_conf.h > > +++ b/src/conf/domain_conf.h > > @@ -1271,6 +1271,11 @@ int virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def); > > void virDomainDiskRemove(virDomainDefPtr def, size_t i); > > int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name); > > > > +int virDomainNetIndexByIfname(virDomainDefPtr def, const char *ifname); > > +int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac); > > +int virDomainNetInsert(virDomainDefPtr dev, virDomainNetDefPtr net); > > +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 1761dfb..cdc63db 100644 > > --- a/src/libvirt_private.syms > > +++ b/src/libvirt_private.syms > > @@ -277,6 +277,10 @@ virDomainMemballoonModelTypeFromString; > > virDomainMemballoonModelTypeToString; > > virDomainNetDefFree; > > virDomainNetTypeToString; > > +virDomainNetIndexByIfname; > > +virDomainNetIndexByMac; > > +virDomainNetInsert; > > +virDomainNetRemoveByMac; > > virDomainObjAssignDef; > > virDomainObjSetDefTransient; > > virDomainObjGetPersistentDef; > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > > index d6d7ad0..45b1bf0 100644 > > --- a/src/qemu/qemu_driver.c > > +++ b/src/qemu/qemu_driver.c > > @@ -4138,6 +4138,7 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef, > > virDomainDeviceDefPtr newdev) > > { > > virDomainDiskDefPtr disk; > > + virDomainNetDefPtr net; > > > > switch(newdev->type) { > > case VIR_DOMAIN_DEVICE_DISK: > > @@ -4158,6 +4159,31 @@ static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef, > > return -1; > > newdev->data.disk = NULL; > > break; > > + case VIR_DOMAIN_DEVICE_NET: > > + net = newdev->data.net; > > + /* check mac */ > > + if (virDomainNetIndexByMac(vmdef, net->mac) >= 0) { > > + char macbuf[VIR_MAC_STRING_BUFLEN]; > > + > > + virFormatMacAddr(net->mac, macbuf); > > + qemuReportError(VIR_ERR_INVALID_ARG, > > + _("target mac %s already exists."), macbuf); > > + return -1; > > + } > > + /* Sanity check : test ifname confliction. */ > > + if (net->ifname && virDomainNetIndexByIfname(vmdef, net->ifname) >= 0) { > > + qemuReportError(VIR_ERR_INVALID_ARG, > > + _("target NIC %s already exists."), net->ifname); > > + return -1; > > + } > > + if (virDomainNetInsert(vmdef, net)) { > > + virReportOOMError(); > > + return -1; > > + } > > + if (qemuDomainAssignPCIAddresses(vmdef) < 0) > > + return -1; > > When qemuDomainAssignPCIAddresses() failed, we should remove net from vmdef, > otherwise, it will cause libvirtd crashed. > This vmdef will be just freed after this. Do I need care ? Thanks, -Kame -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list