Message ID | ee6795bd0367efbc3d99718a578b8e755a75f512.1552492022.git.crobinso@redhat.com |
---|---|
State | Accepted |
Commit | d79a2c079ca8c275bd40a198e0c937dfc7a63027 |
Headers | show |
Series | conf: partial net model enum conversion | expand |
On 3/13/19 4:51 PM, Cole Robinson wrote: > This adds a network model enum. The virDomainNetDef property > is named 'model' like most other devices. > > When the XML parser or a driver calls NetSetModelString, if > the passed string is in the enum, we will set net->model, > otherwise we copy the string into net->modelstr > > Add a single example for the 'netfront' xen model, and wire > that up, just to verify it's all working > > Signed-off-by: Cole Robinson <crobinso@redhat.com> > --- > src/conf/domain_conf.c | 55 +++++++++++++++++++++++++++----------- > src/conf/domain_conf.h | 10 +++++++ > src/libvirt_private.syms | 2 ++ > src/libxl/libxl_conf.c | 4 +-- > src/qemu/qemu_hotplug.c | 8 ++++++ > src/xenconfig/xen_common.c | 16 +++++------ > src/xenconfig/xen_sxpr.c | 15 ++++++----- > 7 files changed, 78 insertions(+), 32 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index fe1945b644..571f2eea39 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -472,6 +472,11 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, > "udp", > ); > > +VIR_ENUM_IMPL(virDomainNetModel, VIR_DOMAIN_NET_MODEL_LAST, This is supposed to be on a separate line now ;-) > + "unknown", > + "netfront", > +); > + > VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, > "default", > "qemu", > @@ -2228,6 +2233,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) > return; > > VIR_FREE(def->modelstr); > + def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; > > switch (def->type) { > case VIR_DOMAIN_NET_TYPE_VHOSTUSER: > @@ -11483,20 +11489,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, > goto error; > } > > - /* NIC model (see -net nic,model=?). We only check that it looks > - * reasonable, not that it is a supported NIC type. FWIW kvm > - * supports these types as of April 2008: > - * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio > - * QEMU PPC64 supports spapr-vlan > - */ > - if (model != NULL) { > - if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { > - virReportError(VIR_ERR_INVALID_ARG, "%s", > - _("Model name contains invalid characters")); > - goto error; > - } > - VIR_STEAL_PTR(def->modelstr, model); > - } > + if (model != NULL && > + virDomainNetSetModelString(def, model) < 0) > + goto error; > > switch (def->type) { > case VIR_DOMAIN_NET_TYPE_NETWORK: > @@ -21739,6 +21734,14 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src, > return false; > } > > + if (src->model != dst->model) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("Target network card model %s does not match source %s"), > + virDomainNetModelTypeToString(dst->model), > + virDomainNetModelTypeToString(src->model)); > + return false; > + } > + > if (src->mtu != dst->mtu) { > virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > _("Target network card MTU %d does not match source %d"), > @@ -29379,6 +29382,8 @@ virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface) > const char * > virDomainNetGetModelString(const virDomainNetDef *net) > { > + if (net->model) > + return virDomainNetModelTypeToString(net->model); > return net->modelstr; > } > > @@ -29386,13 +29391,31 @@ int > virDomainNetSetModelString(virDomainNetDefPtr net, > const char *model) > { > - return VIR_STRDUP(net->modelstr, model); > + VIR_FREE(net->modelstr); > + if ((net->model = virDomainNetModelTypeFromString(model)) >= 0) > + return 0; > + > + net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; > + if (!model) > + return 0; Is this a safe thing to do? I mean virEnumFromString() (which is called by any TypeFromString() in the end) doesn't handle NULL gracefully. You'll need to swap some lines and probably have a temp variable to store virDomainNetModelTypeFromString() retval, ... > + > + if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("Model name contains invalid characters")); > + return -1; > + } > + > + if (VIR_STRDUP(net->modelstr, model) < 0) > + return -1; > + return 0; Or simply 'return VIR_STRDUP();' > } > Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 4/16/19 11:27 AM, Michal Privoznik wrote: > On 3/13/19 4:51 PM, Cole Robinson wrote: >> This adds a network model enum. The virDomainNetDef property >> is named 'model' like most other devices. >> >> When the XML parser or a driver calls NetSetModelString, if >> the passed string is in the enum, we will set net->model, >> otherwise we copy the string into net->modelstr >> >> Add a single example for the 'netfront' xen model, and wire >> that up, just to verify it's all working >> >> Signed-off-by: Cole Robinson <crobinso@redhat.com> >> --- >> src/conf/domain_conf.c | 55 +++++++++++++++++++++++++++----------- >> src/conf/domain_conf.h | 10 +++++++ >> src/libvirt_private.syms | 2 ++ >> src/libxl/libxl_conf.c | 4 +-- >> src/qemu/qemu_hotplug.c | 8 ++++++ >> src/xenconfig/xen_common.c | 16 +++++------ >> src/xenconfig/xen_sxpr.c | 15 ++++++----- >> 7 files changed, 78 insertions(+), 32 deletions(-) >> >> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >> index fe1945b644..571f2eea39 100644 >> --- a/src/conf/domain_conf.c >> +++ b/src/conf/domain_conf.c >> @@ -472,6 +472,11 @@ VIR_ENUM_IMPL(virDomainNet, >> VIR_DOMAIN_NET_TYPE_LAST, >> "udp", >> ); >> +VIR_ENUM_IMPL(virDomainNetModel, VIR_DOMAIN_NET_MODEL_LAST, > > This is supposed to be on a separate line now ;-) > >> + "unknown", >> + "netfront", >> +); >> + >> VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, >> "default", >> "qemu", >> @@ -2228,6 +2233,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) >> return; >> VIR_FREE(def->modelstr); >> + def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >> switch (def->type) { >> case VIR_DOMAIN_NET_TYPE_VHOSTUSER: >> @@ -11483,20 +11489,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr >> xmlopt, >> goto error; >> } >> - /* NIC model (see -net nic,model=?). We only check that it looks >> - * reasonable, not that it is a supported NIC type. FWIW kvm >> - * supports these types as of April 2008: >> - * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio >> - * QEMU PPC64 supports spapr-vlan >> - */ >> - if (model != NULL) { >> - if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { >> - virReportError(VIR_ERR_INVALID_ARG, "%s", >> - _("Model name contains invalid characters")); >> - goto error; >> - } >> - VIR_STEAL_PTR(def->modelstr, model); >> - } >> + if (model != NULL && >> + virDomainNetSetModelString(def, model) < 0) >> + goto error; >> switch (def->type) { >> case VIR_DOMAIN_NET_TYPE_NETWORK: >> @@ -21739,6 +21734,14 @@ >> virDomainNetDefCheckABIStability(virDomainNetDefPtr src, >> return false; >> } >> + if (src->model != dst->model) { >> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >> + _("Target network card model %s does not match >> source %s"), >> + virDomainNetModelTypeToString(dst->model), >> + virDomainNetModelTypeToString(src->model)); >> + return false; >> + } >> + >> if (src->mtu != dst->mtu) { >> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >> _("Target network card MTU %d does not match >> source %d"), >> @@ -29379,6 +29382,8 @@ >> virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface) >> const char * >> virDomainNetGetModelString(const virDomainNetDef *net) >> { >> + if (net->model) >> + return virDomainNetModelTypeToString(net->model); >> return net->modelstr; >> } >> @@ -29386,13 +29391,31 @@ int >> virDomainNetSetModelString(virDomainNetDefPtr net, >> const char *model) >> { >> - return VIR_STRDUP(net->modelstr, model); >> + VIR_FREE(net->modelstr); >> + if ((net->model = virDomainNetModelTypeFromString(model)) >= 0) >> + return 0; >> + >> + net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >> + if (!model) >> + return 0; > > Is this a safe thing to do? I mean virEnumFromString() (which is called > by any TypeFromString() in the end) doesn't handle NULL gracefully. > You'll need to swap some lines and probably have a temp variable to > store virDomainNetModelTypeFromString() retval, ... > Not completely sure I follow, but I think you mean: this function looks like it should operate as virEnumFromString does, meaning return -1 on NULL value. But consider that this is a hybrid enum (net->model) and string (net->modelstr) approach, in which modelstr=NULL is a valid case, so I'm not sure it should be an error. Later patches change the code here a bit so the end result looks different and the NULL check happens earlier, but still returns 0. It doesn't look like any code is depending on passing NULL there but it's still arguably a valid case. We are essentially trying to hide the ->modelstr detail from API users. So not really sure whether to change it or not I will push the series as is (with the other fixes included) but I'll send additional patches here if I misunderstood. Thanks for the reviews - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 4/16/19 7:40 PM, Cole Robinson wrote: > On 4/16/19 11:27 AM, Michal Privoznik wrote: >> On 3/13/19 4:51 PM, Cole Robinson wrote: >>> This adds a network model enum. The virDomainNetDef property >>> is named 'model' like most other devices. >>> >>> When the XML parser or a driver calls NetSetModelString, if >>> the passed string is in the enum, we will set net->model, >>> otherwise we copy the string into net->modelstr >>> >>> Add a single example for the 'netfront' xen model, and wire >>> that up, just to verify it's all working >>> >>> Signed-off-by: Cole Robinson <crobinso@redhat.com> >>> --- >>> src/conf/domain_conf.c | 55 +++++++++++++++++++++++++++----------- >>> src/conf/domain_conf.h | 10 +++++++ >>> src/libvirt_private.syms | 2 ++ >>> src/libxl/libxl_conf.c | 4 +-- >>> src/qemu/qemu_hotplug.c | 8 ++++++ >>> src/xenconfig/xen_common.c | 16 +++++------ >>> src/xenconfig/xen_sxpr.c | 15 ++++++----- >>> 7 files changed, 78 insertions(+), 32 deletions(-) >>> >>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >>> index fe1945b644..571f2eea39 100644 >>> --- a/src/conf/domain_conf.c >>> +++ b/src/conf/domain_conf.c >>> @@ -472,6 +472,11 @@ VIR_ENUM_IMPL(virDomainNet, >>> VIR_DOMAIN_NET_TYPE_LAST, >>> "udp", >>> ); >>> +VIR_ENUM_IMPL(virDomainNetModel, VIR_DOMAIN_NET_MODEL_LAST, >> >> This is supposed to be on a separate line now ;-) >> >>> + "unknown", >>> + "netfront", >>> +); >>> + >>> VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, >>> "default", >>> "qemu", >>> @@ -2228,6 +2233,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) >>> return; >>> VIR_FREE(def->modelstr); >>> + def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >>> switch (def->type) { >>> case VIR_DOMAIN_NET_TYPE_VHOSTUSER: >>> @@ -11483,20 +11489,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr >>> xmlopt, >>> goto error; >>> } >>> - /* NIC model (see -net nic,model=?). We only check that it looks >>> - * reasonable, not that it is a supported NIC type. FWIW kvm >>> - * supports these types as of April 2008: >>> - * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio >>> - * QEMU PPC64 supports spapr-vlan >>> - */ >>> - if (model != NULL) { >>> - if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { >>> - virReportError(VIR_ERR_INVALID_ARG, "%s", >>> - _("Model name contains invalid characters")); >>> - goto error; >>> - } >>> - VIR_STEAL_PTR(def->modelstr, model); >>> - } >>> + if (model != NULL && >>> + virDomainNetSetModelString(def, model) < 0) >>> + goto error; >>> switch (def->type) { >>> case VIR_DOMAIN_NET_TYPE_NETWORK: >>> @@ -21739,6 +21734,14 @@ >>> virDomainNetDefCheckABIStability(virDomainNetDefPtr src, >>> return false; >>> } >>> + if (src->model != dst->model) { >>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >>> + _("Target network card model %s does not match >>> source %s"), >>> + virDomainNetModelTypeToString(dst->model), >>> + virDomainNetModelTypeToString(src->model)); >>> + return false; >>> + } >>> + >>> if (src->mtu != dst->mtu) { >>> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >>> _("Target network card MTU %d does not match >>> source %d"), >>> @@ -29379,6 +29382,8 @@ >>> virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface) >>> const char * >>> virDomainNetGetModelString(const virDomainNetDef *net) >>> { >>> + if (net->model) >>> + return virDomainNetModelTypeToString(net->model); >>> return net->modelstr; >>> } >>> @@ -29386,13 +29391,31 @@ int >>> virDomainNetSetModelString(virDomainNetDefPtr net, >>> const char *model) >>> { >>> - return VIR_STRDUP(net->modelstr, model); >>> + VIR_FREE(net->modelstr); >>> + if ((net->model = virDomainNetModelTypeFromString(model)) >= 0) >>> + return 0; >>> + >>> + net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >>> + if (!model) >>> + return 0; >> >> Is this a safe thing to do? I mean virEnumFromString() (which is called >> by any TypeFromString() in the end) doesn't handle NULL gracefully. >> You'll need to swap some lines and probably have a temp variable to >> store virDomainNetModelTypeFromString() retval, ... >> > > Not completely sure I follow, but I think you mean: this function looks > like it should operate as virEnumFromString does, meaning return -1 on > NULL value. But consider that this is a hybrid enum (net->model) and > string (net->modelstr) approach, in which modelstr=NULL is a valid case, > so I'm not sure it should be an error. I know this is a hybrid, but calling virDomainNetSetModelString(net, NULL) will lead to instant crash. Because model(=NULL) is passed to virDomainNetModeTypeFromString() which dereferences it, and only after that there's the check if (!model). True, in 08/11 you're fixing this so not big of a deal, but if somebody wants to cherry-pick this one they also need to back port 08/11. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 4/17/19 3:33 AM, Michal Privoznik wrote: > On 4/16/19 7:40 PM, Cole Robinson wrote: >> On 4/16/19 11:27 AM, Michal Privoznik wrote: >>> On 3/13/19 4:51 PM, Cole Robinson wrote: >>>> This adds a network model enum. The virDomainNetDef property >>>> is named 'model' like most other devices. >>>> >>>> When the XML parser or a driver calls NetSetModelString, if >>>> the passed string is in the enum, we will set net->model, >>>> otherwise we copy the string into net->modelstr >>>> >>>> Add a single example for the 'netfront' xen model, and wire >>>> that up, just to verify it's all working >>>> >>>> Signed-off-by: Cole Robinson <crobinso@redhat.com> >>>> --- >>>> src/conf/domain_conf.c | 55 >>>> +++++++++++++++++++++++++++----------- >>>> src/conf/domain_conf.h | 10 +++++++ >>>> src/libvirt_private.syms | 2 ++ >>>> src/libxl/libxl_conf.c | 4 +-- >>>> src/qemu/qemu_hotplug.c | 8 ++++++ >>>> src/xenconfig/xen_common.c | 16 +++++------ >>>> src/xenconfig/xen_sxpr.c | 15 ++++++----- >>>> 7 files changed, 78 insertions(+), 32 deletions(-) >>>> >>>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >>>> index fe1945b644..571f2eea39 100644 >>>> --- a/src/conf/domain_conf.c >>>> +++ b/src/conf/domain_conf.c >>>> @@ -472,6 +472,11 @@ VIR_ENUM_IMPL(virDomainNet, >>>> VIR_DOMAIN_NET_TYPE_LAST, >>>> "udp", >>>> ); >>>> +VIR_ENUM_IMPL(virDomainNetModel, VIR_DOMAIN_NET_MODEL_LAST, >>> >>> This is supposed to be on a separate line now ;-) >>> >>>> + "unknown", >>>> + "netfront", >>>> +); >>>> + >>>> VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, >>>> "default", >>>> "qemu", >>>> @@ -2228,6 +2233,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) >>>> return; >>>> VIR_FREE(def->modelstr); >>>> + def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >>>> switch (def->type) { >>>> case VIR_DOMAIN_NET_TYPE_VHOSTUSER: >>>> @@ -11483,20 +11489,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr >>>> xmlopt, >>>> goto error; >>>> } >>>> - /* NIC model (see -net nic,model=?). We only check that it >>>> looks >>>> - * reasonable, not that it is a supported NIC type. FWIW kvm >>>> - * supports these types as of April 2008: >>>> - * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio >>>> - * QEMU PPC64 supports spapr-vlan >>>> - */ >>>> - if (model != NULL) { >>>> - if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { >>>> - virReportError(VIR_ERR_INVALID_ARG, "%s", >>>> - _("Model name contains invalid >>>> characters")); >>>> - goto error; >>>> - } >>>> - VIR_STEAL_PTR(def->modelstr, model); >>>> - } >>>> + if (model != NULL && >>>> + virDomainNetSetModelString(def, model) < 0) >>>> + goto error; >>>> switch (def->type) { >>>> case VIR_DOMAIN_NET_TYPE_NETWORK: >>>> @@ -21739,6 +21734,14 @@ >>>> virDomainNetDefCheckABIStability(virDomainNetDefPtr src, >>>> return false; >>>> } >>>> + if (src->model != dst->model) { >>>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >>>> + _("Target network card model %s does not match >>>> source %s"), >>>> + virDomainNetModelTypeToString(dst->model), >>>> + virDomainNetModelTypeToString(src->model)); >>>> + return false; >>>> + } >>>> + >>>> if (src->mtu != dst->mtu) { >>>> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, >>>> _("Target network card MTU %d does not match >>>> source %d"), >>>> @@ -29379,6 +29382,8 @@ >>>> virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface) >>>> const char * >>>> virDomainNetGetModelString(const virDomainNetDef *net) >>>> { >>>> + if (net->model) >>>> + return virDomainNetModelTypeToString(net->model); >>>> return net->modelstr; >>>> } >>>> @@ -29386,13 +29391,31 @@ int >>>> virDomainNetSetModelString(virDomainNetDefPtr net, >>>> const char *model) >>>> { >>>> - return VIR_STRDUP(net->modelstr, model); >>>> + VIR_FREE(net->modelstr); >>>> + if ((net->model = virDomainNetModelTypeFromString(model)) >= 0) >>>> + return 0; >>>> + >>>> + net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; >>>> + if (!model) >>>> + return 0; >>> >>> Is this a safe thing to do? I mean virEnumFromString() (which is called >>> by any TypeFromString() in the end) doesn't handle NULL gracefully. >>> You'll need to swap some lines and probably have a temp variable to >>> store virDomainNetModelTypeFromString() retval, ... >>> >> >> Not completely sure I follow, but I think you mean: this function looks >> like it should operate as virEnumFromString does, meaning return -1 on >> NULL value. But consider that this is a hybrid enum (net->model) and >> string (net->modelstr) approach, in which modelstr=NULL is a valid case, >> so I'm not sure it should be an error. > > I know this is a hybrid, but calling virDomainNetSetModelString(net, > NULL) will lead to instant crash. Because model(=NULL) is passed to > virDomainNetModeTypeFromString() which dereferences it, and only after > that there's the check if (!model). True, in 08/11 you're fixing this so > not big of a deal, but if somebody wants to cherry-pick this one they > also need to back port 08/11. virDomainNetModeTypeFromString is just virEnumFromString which doesn't deference NULL int virEnumFromString(const char * const *types, unsigned int ntypes, const char *type) { size_t i; if (!type) return -1; - Cole -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 4/17/19 5:58 PM, Cole Robinson wrote: > <snip/> > virDomainNetModeTypeFromString is just virEnumFromString which doesn't > deference NULL > > int > > virEnumFromString(const char * const *types, > > unsigned int ntypes, > > const char *type) > > { > > size_t i; > > if (!type) > > return -1; > Ah, I somehow missed that. Yep, your code was right from the beginning. Sorry for the noise. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fe1945b644..571f2eea39 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -472,6 +472,11 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, "udp", ); +VIR_ENUM_IMPL(virDomainNetModel, VIR_DOMAIN_NET_MODEL_LAST, + "unknown", + "netfront", +); + VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, "default", "qemu", @@ -2228,6 +2233,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) return; VIR_FREE(def->modelstr); + def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; switch (def->type) { case VIR_DOMAIN_NET_TYPE_VHOSTUSER: @@ -11483,20 +11489,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } - /* NIC model (see -net nic,model=?). We only check that it looks - * reasonable, not that it is a supported NIC type. FWIW kvm - * supports these types as of April 2008: - * i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio - * QEMU PPC64 supports spapr-vlan - */ - if (model != NULL) { - if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Model name contains invalid characters")); - goto error; - } - VIR_STEAL_PTR(def->modelstr, model); - } + if (model != NULL && + virDomainNetSetModelString(def, model) < 0) + goto error; switch (def->type) { case VIR_DOMAIN_NET_TYPE_NETWORK: @@ -21739,6 +21734,14 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src, return false; } + if (src->model != dst->model) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target network card model %s does not match source %s"), + virDomainNetModelTypeToString(dst->model), + virDomainNetModelTypeToString(src->model)); + return false; + } + if (src->mtu != dst->mtu) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target network card MTU %d does not match source %d"), @@ -29379,6 +29382,8 @@ virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface) const char * virDomainNetGetModelString(const virDomainNetDef *net) { + if (net->model) + return virDomainNetModelTypeToString(net->model); return net->modelstr; } @@ -29386,13 +29391,31 @@ int virDomainNetSetModelString(virDomainNetDefPtr net, const char *model) { - return VIR_STRDUP(net->modelstr, model); + VIR_FREE(net->modelstr); + if ((net->model = virDomainNetModelTypeFromString(model)) >= 0) + return 0; + + net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN; + if (!model) + return 0; + + if (strspn(model, NET_MODEL_CHARS) < strlen(model)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Model name contains invalid characters")); + return -1; + } + + if (VIR_STRDUP(net->modelstr, model) < 0) + return -1; + return 0; } int virDomainNetStreqModelString(const virDomainNetDef *net, const char *model) { + if (net->model) + return net->model == virDomainNetModelTypeFromString(model); return STREQ_NULLABLE(net->modelstr, model); } @@ -29400,6 +29423,8 @@ int virDomainNetStrcaseeqModelString(const virDomainNetDef *net, const char *model) { + if (net->model) + return STRCASEEQ(virDomainNetModelTypeToString(net->model), model); return net->modelstr && STRCASEEQ(net->modelstr, model); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a0d443ee1b..92d54b0348 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -960,6 +960,14 @@ typedef enum { VIR_DOMAIN_NET_TYPE_LAST } virDomainNetType; +/* network model types */ +typedef enum { + VIR_DOMAIN_NET_MODEL_UNKNOWN, + VIR_DOMAIN_NET_MODEL_NETFRONT, + + VIR_DOMAIN_NET_MODEL_LAST +} virDomainNetModelType; + /* the backend driver used for virtio interfaces */ typedef enum { VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT, /* prefer kernel, fall back to user */ @@ -1021,6 +1029,7 @@ struct _virDomainNetDef { virDomainNetType type; virMacAddr mac; bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */ + int model; /* virDomainNetModelType */ char *modelstr; union { struct { @@ -3536,6 +3545,7 @@ VIR_ENUM_DECL(virDomainNet); VIR_ENUM_DECL(virDomainNetBackend); VIR_ENUM_DECL(virDomainNetVirtioTxMode); VIR_ENUM_DECL(virDomainNetInterfaceLinkState); +VIR_ENUM_DECL(virDomainNetModel); VIR_ENUM_DECL(virDomainChrDevice); VIR_ENUM_DECL(virDomainChrChannelTarget); VIR_ENUM_DECL(virDomainChrConsoleTarget); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a01f158946..3a0699d724 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -477,6 +477,8 @@ virDomainNetGetActualVlan; virDomainNetGetModelString; virDomainNetInsert; virDomainNetIsVirtioModel; +virDomainNetModelTypeFromString; +virDomainNetModelTypeToString; virDomainNetNotifyActualDevice; virDomainNetReleaseActualDevice; virDomainNetRemove; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 9236820bfe..007ef9c372 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1269,7 +1269,7 @@ libxlMakeNic(virDomainDefPtr def, if (virDomainNetGetModelString(l_nic)) { if ((def->os.type == VIR_DOMAIN_OSTYPE_XEN || def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) && - !virDomainNetStreqModelString(l_nic, "netfront")) { + l_nic->model != VIR_DOMAIN_NET_MODEL_NETFRONT) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only model 'netfront' is supported for " "Xen PV(H) domains")); @@ -1277,7 +1277,7 @@ libxlMakeNic(virDomainDefPtr def, } if (VIR_STRDUP(x_nic->model, virDomainNetGetModelString(l_nic)) < 0) goto cleanup; - if (virDomainNetStreqModelString(l_nic, "netfront")) + if (l_nic->model == VIR_DOMAIN_NET_MODEL_NETFRONT) x_nic->nictype = LIBXL_NIC_TYPE_VIF; else x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 872d8e2a6f..7bd3a8a408 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3701,6 +3701,14 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, goto cleanup; } + if (olddev->model != newdev->model) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("cannot modify network device model from %s to %s"), + virDomainNetModelTypeToString(olddev->model), + virDomainNetModelTypeToString(newdev->model)); + goto cleanup; + } + if (virDomainNetIsVirtioModel(olddev) && (olddev->driver.virtio.name != newdev->driver.virtio.name || olddev->driver.virtio.txmode != newdev->driver.virtio.txmode || diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c index 170378fab5..69a6f53507 100644 --- a/src/xenconfig/xen_common.c +++ b/src/xenconfig/xen_common.c @@ -1068,13 +1068,13 @@ xenParseVif(char *entry, const char *vif_typename) VIR_STRDUP(net->script, script) < 0) goto cleanup; - if (model[0] && - virDomainNetSetModelString(net, model) < 0) - goto cleanup; - - if (!model[0] && type[0] && STREQ(type, vif_typename) && - virDomainNetSetModelString(net, "netfront") < 0) - goto cleanup; + if (model[0]) { + if (virDomainNetSetModelString(net, model) < 0) + goto cleanup; + } else { + if (type[0] && STREQ(type, vif_typename)) + net->model = VIR_DOMAIN_NET_MODEL_NETFRONT; + } if (vifname[0] && VIR_STRDUP(net->ifname, vifname) < 0) @@ -1427,7 +1427,7 @@ xenFormatNet(virConnectPtr conn, virBufferAsprintf(&buf, ",model=%s", virDomainNetGetModelString(net)); } else { - if (virDomainNetStreqModelString(net, "netfront")) + if (net->model == VIR_DOMAIN_NET_MODEL_NETFRONT) virBufferAsprintf(&buf, ",type=%s", vif_typename); else virBufferAsprintf(&buf, ",model=%s", diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c index 224c874b90..0bff94ead5 100644 --- a/src/xenconfig/xen_sxpr.c +++ b/src/xenconfig/xen_sxpr.c @@ -642,12 +642,13 @@ xenParseSxprNets(virDomainDefPtr def, } } - if (virDomainNetSetModelString(net, model) < 0) - goto cleanup; - - if (!model && type && STREQ(type, "netfront") && - virDomainNetSetModelString(net, "netfront") < 0) - goto cleanup; + if (model) { + if (virDomainNetSetModelString(net, model) < 0) + goto cleanup; + } else { + if (type && STREQ(type, "netfront")) + net->model = VIR_DOMAIN_NET_MODEL_NETFRONT; + } tmp = sexpr_node(node, "device/vif/rate"); if (tmp) { @@ -1934,7 +1935,7 @@ xenFormatSxprNet(virConnectPtr conn, virBufferEscapeSexpr(buf, "(model '%s')", virDomainNetGetModelString(def)); } else { - if (virDomainNetStreqModelString(def, "netfront")) + if (def->model == VIR_DOMAIN_NET_MODEL_NETFRONT) virBufferAddLit(buf, "(type netfront)"); else virBufferEscapeSexpr(buf, "(model '%s')",
This adds a network model enum. The virDomainNetDef property is named 'model' like most other devices. When the XML parser or a driver calls NetSetModelString, if the passed string is in the enum, we will set net->model, otherwise we copy the string into net->modelstr Add a single example for the 'netfront' xen model, and wire that up, just to verify it's all working Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/conf/domain_conf.c | 55 +++++++++++++++++++++++++++----------- src/conf/domain_conf.h | 10 +++++++ src/libvirt_private.syms | 2 ++ src/libxl/libxl_conf.c | 4 +-- src/qemu/qemu_hotplug.c | 8 ++++++ src/xenconfig/xen_common.c | 16 +++++------ src/xenconfig/xen_sxpr.c | 15 ++++++----- 7 files changed, 78 insertions(+), 32 deletions(-) -- 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list