Patchwork [libvirt,v2,1/2] add pci-bridge controller type

login
register
mail settings
Submitter liguang
Date Jan. 8, 2013, 1:58 a.m.
Message ID <1357610330-10835-2-git-send-email-lig.fnst@cn.fujitsu.com>
Download mbox | patch
Permalink /patch/210280/
State New
Headers show

Comments

liguang - Jan. 8, 2013, 1:58 a.m.
Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
---
 src/conf/device_conf.c |   12 +++++++++++-
 src/conf/device_conf.h |    1 +
 src/conf/domain_conf.c |    5 ++++-
 src/conf/domain_conf.h |    1 +
 4 files changed, 17 insertions(+), 2 deletions(-)
Doug Goldstein - Jan. 8, 2013, 4:38 a.m.
On Mon, Jan 7, 2013 at 7:58 PM, liguang <lig.fnst@cn.fujitsu.com> wrote:
> Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> ---
>  src/conf/device_conf.c |   12 +++++++++++-
>  src/conf/device_conf.h |    1 +
>  src/conf/domain_conf.c |    5 ++++-
>  src/conf/domain_conf.h |    1 +
>  4 files changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> index 7b97f45..1c06ed0 100644
> --- a/src/conf/device_conf.c
> +++ b/src/conf/device_conf.c
> @@ -51,16 +51,18 @@ int
>  virDevicePCIAddressParseXML(xmlNodePtr node,
>                              virDevicePCIAddressPtr addr)
>  {
> -    char *domain, *slot, *bus, *function, *multi;
> +    char *domain, *slot, *bus, *function, *multi, *bridge;
>      int ret = -1;
>
>      memset(addr, 0, sizeof(*addr));
> +    addr->bridge = -1;
>
>      domain   = virXMLPropString(node, "domain");
>      bus      = virXMLPropString(node, "bus");
>      slot     = virXMLPropString(node, "slot");
>      function = virXMLPropString(node, "function");
>      multi    = virXMLPropString(node, "multifunction");
> +    bridge   = virXMLPropString(node, "bridge");
>
>      if (domain &&
>          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
>          goto cleanup;
>
>      }
> +
> +    if (bridge &&
> +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("pci-bridge number must be >= 0 "));
> +        goto cleanup;
> +    }

This check isn't correct for the error message. The check is saying
that we weren't able to parse out the value specified (look at the
checks earlier in the function). The subsequent checks (where this
code is added) checks for the validity of the values and use
VIR_ERR_CONFIG_UNSUPPORTED.

You're also failing to free bridge in the cleanup section.

> +
>      if (!virDevicePCIAddressIsValid(addr)) {
>          virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>                         _("Insufficient specification for PCI address"));
> diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
> index 5318738..7ac3461 100644
> --- a/src/conf/device_conf.h
> +++ b/src/conf/device_conf.h
> @@ -48,6 +48,7 @@ struct _virDevicePCIAddress {
>      unsigned int slot;
>      unsigned int function;
>      int          multi;  /* enum virDomainDeviceAddressPciMulti */
> +    int          bridge; /* for pci-bridge */
>  };
>
>  int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr);
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 6a7646e..8ebe77d 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -264,7 +264,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
>                "sata",
>                "virtio-serial",
>                "ccid",
> -              "usb")
> +              "usb",
> +              "pci-bridge")
>
>  VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
>                "auto",
> @@ -4479,6 +4480,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
>          goto error;
>
>      switch (def->type) {
> +    case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE:
> +        break;
>      case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: {
>          char *ports = virXMLPropString(node, "ports");
>          if (ports) {
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 5062e07..56e5a40 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -652,6 +652,7 @@ enum virDomainControllerType {
>      VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
>      VIR_DOMAIN_CONTROLLER_TYPE_CCID,
>      VIR_DOMAIN_CONTROLLER_TYPE_USB,
> +    VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE,
>
>      VIR_DOMAIN_CONTROLLER_TYPE_LAST
>  };
> --
> 1.7.2.5
>
>

Looks like:

int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)

Needs to be updated as well part of this series to allow bus to not be
0 anymore.

This change also needs an update to the XML schemas in
docs/schemas/basictypes.rng
liguang - Jan. 8, 2013, 5:26 a.m.
在 2013-01-07一的 22:38 -0600,Doug Goldstein写道:
> On Mon, Jan 7, 2013 at 7:58 PM, liguang <lig.fnst@cn.fujitsu.com> wrote:
> > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > ---
> >  src/conf/device_conf.c |   12 +++++++++++-
> >  src/conf/device_conf.h |    1 +
> >  src/conf/domain_conf.c |    5 ++++-
> >  src/conf/domain_conf.h |    1 +
> >  4 files changed, 17 insertions(+), 2 deletions(-)
> >
> > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > index 7b97f45..1c06ed0 100644
> > --- a/src/conf/device_conf.c
> > +++ b/src/conf/device_conf.c
> > @@ -51,16 +51,18 @@ int
> >  virDevicePCIAddressParseXML(xmlNodePtr node,
> >                              virDevicePCIAddressPtr addr)
> >  {
> > -    char *domain, *slot, *bus, *function, *multi;
> > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> >      int ret = -1;
> >
> >      memset(addr, 0, sizeof(*addr));
> > +    addr->bridge = -1;
> >
> >      domain   = virXMLPropString(node, "domain");
> >      bus      = virXMLPropString(node, "bus");
> >      slot     = virXMLPropString(node, "slot");
> >      function = virXMLPropString(node, "function");
> >      multi    = virXMLPropString(node, "multifunction");
> > +    bridge   = virXMLPropString(node, "bridge");
> >
> >      if (domain &&
> >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> >          goto cleanup;
> >
> >      }
> > +
> > +    if (bridge &&
> > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > +                       _("pci-bridge number must be >= 0 "));
> > +        goto cleanup;
> > +    }
> 
> This check isn't correct for the error message. The check is saying
> that we weren't able to parse out the value specified (look at the
> checks earlier in the function). The subsequent checks (where this
> code is added) checks for the validity of the values and use
> VIR_ERR_CONFIG_UNSUPPORTED.
> 

No

> You're also failing to free bridge in the cleanup section.

Yes, will fix.

> 
> > +
> >      if (!virDevicePCIAddressIsValid(addr)) {
> >          virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> >                         _("Insufficient specification for PCI address"));
> > diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
> > index 5318738..7ac3461 100644
> > --- a/src/conf/device_conf.h
> > +++ b/src/conf/device_conf.h
> > @@ -48,6 +48,7 @@ struct _virDevicePCIAddress {
> >      unsigned int slot;
> >      unsigned int function;
> >      int          multi;  /* enum virDomainDeviceAddressPciMulti */
> > +    int          bridge; /* for pci-bridge */
> >  };
> >
> >  int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr);
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 6a7646e..8ebe77d 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -264,7 +264,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
> >                "sata",
> >                "virtio-serial",
> >                "ccid",
> > -              "usb")
> > +              "usb",
> > +              "pci-bridge")
> >
> >  VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
> >                "auto",
> > @@ -4479,6 +4480,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
> >          goto error;
> >
> >      switch (def->type) {
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE:
> > +        break;
> >      case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: {
> >          char *ports = virXMLPropString(node, "ports");
> >          if (ports) {
> > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> > index 5062e07..56e5a40 100644
> > --- a/src/conf/domain_conf.h
> > +++ b/src/conf/domain_conf.h
> > @@ -652,6 +652,7 @@ enum virDomainControllerType {
> >      VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
> >      VIR_DOMAIN_CONTROLLER_TYPE_CCID,
> >      VIR_DOMAIN_CONTROLLER_TYPE_USB,
> > +    VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE,
> >
> >      VIR_DOMAIN_CONTROLLER_TYPE_LAST
> >  };
> > --
> > 1.7.2.5
> >
> >
> 
> Looks like:
> 
> int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)
> 
> Needs to be updated as well part of this series to allow bus to not be
> 0 anymore.
> 
> This change also needs an update to the XML schemas in
> docs/schemas/basictypes.rng
>
Daniel P. Berrange - Jan. 8, 2013, 8:04 a.m.
On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> ---
>  src/conf/device_conf.c |   12 +++++++++++-
>  src/conf/device_conf.h |    1 +
>  src/conf/domain_conf.c |    5 ++++-
>  src/conf/domain_conf.h |    1 +
>  4 files changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> index 7b97f45..1c06ed0 100644
> --- a/src/conf/device_conf.c
> +++ b/src/conf/device_conf.c
> @@ -51,16 +51,18 @@ int
>  virDevicePCIAddressParseXML(xmlNodePtr node,
>                              virDevicePCIAddressPtr addr)
>  {
> -    char *domain, *slot, *bus, *function, *multi;
> +    char *domain, *slot, *bus, *function, *multi, *bridge;
>      int ret = -1;
>  
>      memset(addr, 0, sizeof(*addr));
> +    addr->bridge = -1;
>  
>      domain   = virXMLPropString(node, "domain");
>      bus      = virXMLPropString(node, "bus");
>      slot     = virXMLPropString(node, "slot");
>      function = virXMLPropString(node, "function");
>      multi    = virXMLPropString(node, "multifunction");
> +    bridge   = virXMLPropString(node, "bridge");
>  
>      if (domain &&
>          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
>          goto cleanup;
>  
>      }
> +
> +    if (bridge &&
> +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("pci-bridge number must be >= 0 "));
> +        goto cleanup;
> +    }

This is bogus - there's no need for a new 'bridge' attribute - we
have 'bus' which is sufficient.


Daniel
liguang - Jan. 8, 2013, 8:37 a.m.
在 2013-01-08二的 08:04 +0000,Daniel P. Berrange写道:
> On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > ---
> >  src/conf/device_conf.c |   12 +++++++++++-
> >  src/conf/device_conf.h |    1 +
> >  src/conf/domain_conf.c |    5 ++++-
> >  src/conf/domain_conf.h |    1 +
> >  4 files changed, 17 insertions(+), 2 deletions(-)
> > 
> > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > index 7b97f45..1c06ed0 100644
> > --- a/src/conf/device_conf.c
> > +++ b/src/conf/device_conf.c
> > @@ -51,16 +51,18 @@ int
> >  virDevicePCIAddressParseXML(xmlNodePtr node,
> >                              virDevicePCIAddressPtr addr)
> >  {
> > -    char *domain, *slot, *bus, *function, *multi;
> > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> >      int ret = -1;
> >  
> >      memset(addr, 0, sizeof(*addr));
> > +    addr->bridge = -1;
> >  
> >      domain   = virXMLPropString(node, "domain");
> >      bus      = virXMLPropString(node, "bus");
> >      slot     = virXMLPropString(node, "slot");
> >      function = virXMLPropString(node, "function");
> >      multi    = virXMLPropString(node, "multifunction");
> > +    bridge   = virXMLPropString(node, "bridge");
> >  
> >      if (domain &&
> >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> >          goto cleanup;
> >  
> >      }
> > +
> > +    if (bridge &&
> > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > +                       _("pci-bridge number must be >= 0 "));
> > +        goto cleanup;
> > +    }
> 
> This is bogus - there's no need for a new 'bridge' attribute - we
> have 'bus' which is sufficient.

Oh, yes, this version 'bridge' is unnecessary.

In former version, I want to discriminate if a pci device want to
sitting on default bus pci.0 or pci-bridge0, so bring in 'bridge'.

Thanks!

> 
> 
> Daniel
liguang - Jan. 8, 2013, 8:47 a.m.
在 2013-01-08二的 16:37 +0800,li guang写道:
> 在 2013-01-08二的 08:04 +0000,Daniel P. Berrange写道:
> > On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> > > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > > ---
> > >  src/conf/device_conf.c |   12 +++++++++++-
> > >  src/conf/device_conf.h |    1 +
> > >  src/conf/domain_conf.c |    5 ++++-
> > >  src/conf/domain_conf.h |    1 +
> > >  4 files changed, 17 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > > index 7b97f45..1c06ed0 100644
> > > --- a/src/conf/device_conf.c
> > > +++ b/src/conf/device_conf.c
> > > @@ -51,16 +51,18 @@ int
> > >  virDevicePCIAddressParseXML(xmlNodePtr node,
> > >                              virDevicePCIAddressPtr addr)
> > >  {
> > > -    char *domain, *slot, *bus, *function, *multi;
> > > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> > >      int ret = -1;
> > >  
> > >      memset(addr, 0, sizeof(*addr));
> > > +    addr->bridge = -1;
> > >  
> > >      domain   = virXMLPropString(node, "domain");
> > >      bus      = virXMLPropString(node, "bus");
> > >      slot     = virXMLPropString(node, "slot");
> > >      function = virXMLPropString(node, "function");
> > >      multi    = virXMLPropString(node, "multifunction");
> > > +    bridge   = virXMLPropString(node, "bridge");
> > >  
> > >      if (domain &&
> > >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> > >          goto cleanup;
> > >  
> > >      }
> > > +
> > > +    if (bridge &&
> > > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > +                       _("pci-bridge number must be >= 0 "));
> > > +        goto cleanup;
> > > +    }
> > 
> > This is bogus - there's no need for a new 'bridge' attribute - we
> > have 'bus' which is sufficient.
> 
> Oh, yes, this version 'bridge' is unnecessary.
> 
> In former version, I want to discriminate if a pci device want to
> sitting on default bus pci.0 or pci-bridge0, so bring in 'bridge'.
> 
> Thanks!

but, without 'bridge', can't know if user want or don't want pci-bridge,
and the check for 'bus != 0' will be removed, then if user happened to 
define a pci device greater than 0, qemu will complain about this,
so it's inconvenient for this case.

> 
> > 
> > 
> > Daniel
>
Daniel P. Berrange - Jan. 8, 2013, 8:51 a.m.
On Tue, Jan 08, 2013 at 04:47:40PM +0800, li guang wrote:
> 在 2013-01-08二的 16:37 +0800,li guang写道:
> > 在 2013-01-08二的 08:04 +0000,Daniel P. Berrange写道:
> > > On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> > > > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > > > ---
> > > >  src/conf/device_conf.c |   12 +++++++++++-
> > > >  src/conf/device_conf.h |    1 +
> > > >  src/conf/domain_conf.c |    5 ++++-
> > > >  src/conf/domain_conf.h |    1 +
> > > >  4 files changed, 17 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > > > index 7b97f45..1c06ed0 100644
> > > > --- a/src/conf/device_conf.c
> > > > +++ b/src/conf/device_conf.c
> > > > @@ -51,16 +51,18 @@ int
> > > >  virDevicePCIAddressParseXML(xmlNodePtr node,
> > > >                              virDevicePCIAddressPtr addr)
> > > >  {
> > > > -    char *domain, *slot, *bus, *function, *multi;
> > > > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> > > >      int ret = -1;
> > > >  
> > > >      memset(addr, 0, sizeof(*addr));
> > > > +    addr->bridge = -1;
> > > >  
> > > >      domain   = virXMLPropString(node, "domain");
> > > >      bus      = virXMLPropString(node, "bus");
> > > >      slot     = virXMLPropString(node, "slot");
> > > >      function = virXMLPropString(node, "function");
> > > >      multi    = virXMLPropString(node, "multifunction");
> > > > +    bridge   = virXMLPropString(node, "bridge");
> > > >  
> > > >      if (domain &&
> > > >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > > > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> > > >          goto cleanup;
> > > >  
> > > >      }
> > > > +
> > > > +    if (bridge &&
> > > > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > > > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > > +                       _("pci-bridge number must be >= 0 "));
> > > > +        goto cleanup;
> > > > +    }
> > > 
> > > This is bogus - there's no need for a new 'bridge' attribute - we
> > > have 'bus' which is sufficient.
> > 
> > Oh, yes, this version 'bridge' is unnecessary.
> > 
> > In former version, I want to discriminate if a pci device want to
> > sitting on default bus pci.0 or pci-bridge0, so bring in 'bridge'.
> > 
> > Thanks!
> 
> but, without 'bridge', can't know if user want or don't want pci-bridge,
> and the check for 'bus != 0' will be removed, then if user happened to 
> define a pci device greater than 0, qemu will complain about this,
> so it's inconvenient for this case.

The check for 'bus != 0' was only added because we didn't have any
support for bridges. Once we have bridge support, then that check
can be changed. If bus != 0, then check to see if there's a matching
bridge device, otherwise raise an error.

Daniel
liguang - Jan. 8, 2013, 8:55 a.m.
在 2013-01-08二的 08:51 +0000,Daniel P. Berrange写道:
> On Tue, Jan 08, 2013 at 04:47:40PM +0800, li guang wrote:
> > 在 2013-01-08二的 16:37 +0800,li guang写道:
> > > 在 2013-01-08二的 08:04 +0000,Daniel P. Berrange写道:
> > > > On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> > > > > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > > > > ---
> > > > >  src/conf/device_conf.c |   12 +++++++++++-
> > > > >  src/conf/device_conf.h |    1 +
> > > > >  src/conf/domain_conf.c |    5 ++++-
> > > > >  src/conf/domain_conf.h |    1 +
> > > > >  4 files changed, 17 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > > > > index 7b97f45..1c06ed0 100644
> > > > > --- a/src/conf/device_conf.c
> > > > > +++ b/src/conf/device_conf.c
> > > > > @@ -51,16 +51,18 @@ int
> > > > >  virDevicePCIAddressParseXML(xmlNodePtr node,
> > > > >                              virDevicePCIAddressPtr addr)
> > > > >  {
> > > > > -    char *domain, *slot, *bus, *function, *multi;
> > > > > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> > > > >      int ret = -1;
> > > > >  
> > > > >      memset(addr, 0, sizeof(*addr));
> > > > > +    addr->bridge = -1;
> > > > >  
> > > > >      domain   = virXMLPropString(node, "domain");
> > > > >      bus      = virXMLPropString(node, "bus");
> > > > >      slot     = virXMLPropString(node, "slot");
> > > > >      function = virXMLPropString(node, "function");
> > > > >      multi    = virXMLPropString(node, "multifunction");
> > > > > +    bridge   = virXMLPropString(node, "bridge");
> > > > >  
> > > > >      if (domain &&
> > > > >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > > > > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> > > > >          goto cleanup;
> > > > >  
> > > > >      }
> > > > > +
> > > > > +    if (bridge &&
> > > > > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > > > > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > > > +                       _("pci-bridge number must be >= 0 "));
> > > > > +        goto cleanup;
> > > > > +    }
> > > > 
> > > > This is bogus - there's no need for a new 'bridge' attribute - we
> > > > have 'bus' which is sufficient.
> > > 
> > > Oh, yes, this version 'bridge' is unnecessary.
> > > 
> > > In former version, I want to discriminate if a pci device want to
> > > sitting on default bus pci.0 or pci-bridge0, so bring in 'bridge'.
> > > 
> > > Thanks!
> > 
> > but, without 'bridge', can't know if user want or don't want pci-bridge,
> > and the check for 'bus != 0' will be removed, then if user happened to 
> > define a pci device greater than 0, qemu will complain about this,
> > so it's inconvenient for this case.
> 
> The check for 'bus != 0' was only added because we didn't have any
> support for bridges. Once we have bridge support, then that check
> can be changed. If bus != 0, then check to see if there's a matching
> bridge device, otherwise raise an error.

OK for me, though it seems much more changes will be involved
than with 'bridge' condition.

> 
> Daniel
Daniel P. Berrange - Jan. 8, 2013, 8:59 a.m.
On Tue, Jan 08, 2013 at 04:55:28PM +0800, li guang wrote:
> 在 2013-01-08二的 08:51 +0000,Daniel P. Berrange写道:
> > On Tue, Jan 08, 2013 at 04:47:40PM +0800, li guang wrote:
> > > 在 2013-01-08二的 16:37 +0800,li guang写道:
> > > > 在 2013-01-08二的 08:04 +0000,Daniel P. Berrange写道:
> > > > > On Tue, Jan 08, 2013 at 09:58:49AM +0800, liguang wrote:
> > > > > > Signed-off-by: liguang <lig.fnst@cn.fujitsu.com>
> > > > > > ---
> > > > > >  src/conf/device_conf.c |   12 +++++++++++-
> > > > > >  src/conf/device_conf.h |    1 +
> > > > > >  src/conf/domain_conf.c |    5 ++++-
> > > > > >  src/conf/domain_conf.h |    1 +
> > > > > >  4 files changed, 17 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> > > > > > index 7b97f45..1c06ed0 100644
> > > > > > --- a/src/conf/device_conf.c
> > > > > > +++ b/src/conf/device_conf.c
> > > > > > @@ -51,16 +51,18 @@ int
> > > > > >  virDevicePCIAddressParseXML(xmlNodePtr node,
> > > > > >                              virDevicePCIAddressPtr addr)
> > > > > >  {
> > > > > > -    char *domain, *slot, *bus, *function, *multi;
> > > > > > +    char *domain, *slot, *bus, *function, *multi, *bridge;
> > > > > >      int ret = -1;
> > > > > >  
> > > > > >      memset(addr, 0, sizeof(*addr));
> > > > > > +    addr->bridge = -1;
> > > > > >  
> > > > > >      domain   = virXMLPropString(node, "domain");
> > > > > >      bus      = virXMLPropString(node, "bus");
> > > > > >      slot     = virXMLPropString(node, "slot");
> > > > > >      function = virXMLPropString(node, "function");
> > > > > >      multi    = virXMLPropString(node, "multifunction");
> > > > > > +    bridge   = virXMLPropString(node, "bridge");
> > > > > >  
> > > > > >      if (domain &&
> > > > > >          virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
> > > > > > @@ -98,6 +100,14 @@ virDevicePCIAddressParseXML(xmlNodePtr node,
> > > > > >          goto cleanup;
> > > > > >  
> > > > > >      }
> > > > > > +
> > > > > > +    if (bridge &&
> > > > > > +        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
> > > > > > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > > > > +                       _("pci-bridge number must be >= 0 "));
> > > > > > +        goto cleanup;
> > > > > > +    }
> > > > > 
> > > > > This is bogus - there's no need for a new 'bridge' attribute - we
> > > > > have 'bus' which is sufficient.
> > > > 
> > > > Oh, yes, this version 'bridge' is unnecessary.
> > > > 
> > > > In former version, I want to discriminate if a pci device want to
> > > > sitting on default bus pci.0 or pci-bridge0, so bring in 'bridge'.
> > > > 
> > > > Thanks!
> > > 
> > > but, without 'bridge', can't know if user want or don't want pci-bridge,
> > > and the check for 'bus != 0' will be removed, then if user happened to 
> > > define a pci device greater than 0, qemu will complain about this,
> > > so it's inconvenient for this case.
> > 
> > The check for 'bus != 0' was only added because we didn't have any
> > support for bridges. Once we have bridge support, then that check
> > can be changed. If bus != 0, then check to see if there's a matching
> > bridge device, otherwise raise an error.
> 
> OK for me, though it seems much more changes will be involved
> than with 'bridge' condition.

The point is that the 'bridge' attribute is redundant information in
the XML that you're forcing the admin to specify to avoid doing more
coding work in libvirt. That's not optimizing for the right person.

Daniel

Patch

diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
index 7b97f45..1c06ed0 100644
--- a/src/conf/device_conf.c
+++ b/src/conf/device_conf.c
@@ -51,16 +51,18 @@  int
 virDevicePCIAddressParseXML(xmlNodePtr node,
                             virDevicePCIAddressPtr addr)
 {
-    char *domain, *slot, *bus, *function, *multi;
+    char *domain, *slot, *bus, *function, *multi, *bridge;
     int ret = -1;
 
     memset(addr, 0, sizeof(*addr));
+    addr->bridge = -1;
 
     domain   = virXMLPropString(node, "domain");
     bus      = virXMLPropString(node, "bus");
     slot     = virXMLPropString(node, "slot");
     function = virXMLPropString(node, "function");
     multi    = virXMLPropString(node, "multifunction");
+    bridge   = virXMLPropString(node, "bridge");
 
     if (domain &&
         virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
@@ -98,6 +100,14 @@  virDevicePCIAddressParseXML(xmlNodePtr node,
         goto cleanup;
 
     }
+
+    if (bridge &&
+        virStrToLong_i(bridge, NULL, 0, &addr->bridge) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("pci-bridge number must be >= 0 "));
+        goto cleanup;
+    }
+
     if (!virDevicePCIAddressIsValid(addr)) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Insufficient specification for PCI address"));
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index 5318738..7ac3461 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -48,6 +48,7 @@  struct _virDevicePCIAddress {
     unsigned int slot;
     unsigned int function;
     int          multi;  /* enum virDomainDeviceAddressPciMulti */
+    int          bridge; /* for pci-bridge */
 };
 
 int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6a7646e..8ebe77d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -264,7 +264,8 @@  VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
               "sata",
               "virtio-serial",
               "ccid",
-              "usb")
+              "usb",
+              "pci-bridge")
 
 VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
               "auto",
@@ -4479,6 +4480,8 @@  virDomainControllerDefParseXML(xmlNodePtr node,
         goto error;
 
     switch (def->type) {
+    case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE:
+        break;
     case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: {
         char *ports = virXMLPropString(node, "ports");
         if (ports) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5062e07..56e5a40 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -652,6 +652,7 @@  enum virDomainControllerType {
     VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
     VIR_DOMAIN_CONTROLLER_TYPE_CCID,
     VIR_DOMAIN_CONTROLLER_TYPE_USB,
+    VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE,
 
     VIR_DOMAIN_CONTROLLER_TYPE_LAST
 };