[libvirt] [PATCH v2 0/2] add pci-bridge support

Now, it's impossible to arrange devices into multi-pci-bus, for example: <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x1' slot='0x02' function='0x0'/> </video> libvirt will complain about "bus != 0", fortunately, qemu supports pci-to-pci bridge, if we want to use multi-pci-bus, we can define 2 pci bridge controllers, then attach 1 to the other as a subordinate pci-bus, so, 2 pci-buses appear. for example: <controller type='pci-bridge' index='0'/> <controller type='pci-bridge' index='1'> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' bridge='0'/> </controller> <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x01' slot='0x02' function='0x0' bridge='1'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' bridge='0'/> </video> src/conf/device_conf.c | 11 ++++++++++- src/conf/device_conf.h | 1 + src/conf/domain_conf.c | 5 ++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 5 files changed, 36 insertions(+), 7 deletions(-)

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; + } + 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

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 -- Doug Goldstein

在 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
-- regards! li guang

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 -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

在 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
-- regards! li guang

在 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
-- regards! li guang

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 -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

在 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
-- regards! li guang

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 -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Signed-off-by: liguang <lig.fnst@cn.fujitsu.com> --- src/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 1 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 04a9512..0da32e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -966,10 +966,15 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev) { char *addr; - if (dev->addr.pci.domain != 0 || - dev->addr.pci.bus != 0) { + if (dev->addr.pci.domain != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI domain 0 and bus 0 are available")); + _("Only PCI domain 0 is available")); + return NULL; + } + if (dev->addr.pci.bridge < 0 && dev->addr.pci.bus != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI bus 0 is available " + "without pci-bridge support")); return NULL; } @@ -1768,7 +1773,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, _("Only PCI device addresses with domain=0 are supported")); return -1; } - if (info->addr.pci.bus != 0) { + if (info->addr.pci.bus != 0 && info->addr.pci.bridge < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only PCI device addresses with bus=0 are supported")); return -1; @@ -1801,7 +1806,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, * When QEMU grows support for > 1 PCI domain, then pci.0 change * to pciNN.0 where NN is the domain number */ - if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) + if (info->addr.pci.bridge >= 0) + virBufferAsprintf(buf, ",bus=pci.%d", info->addr.pci.bus); + else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) virBufferAsprintf(buf, ",bus=pci.0"); else virBufferAsprintf(buf, ",bus=pci"); @@ -3064,6 +3071,12 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, int model; switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE: + virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d", def->idx+1); + virBufferAsprintf(&buf, ",id=pci.%d", def->idx); + if (def->idx == 0) + goto out; + break; case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: model = def->model; if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0) @@ -3137,6 +3150,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0) goto error; +out: if (virBufferError(&buf)) { virReportOOMError(); goto error; @@ -5033,6 +5047,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* We don't add an explicit IDE or FD controller because the * provided PIIX4 device already includes one. It isn't possible to * remove the PIIX4. */ + VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE, VIR_DOMAIN_CONTROLLER_TYPE_USB, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, VIR_DOMAIN_CONTROLLER_TYPE_SATA, -- 1.7.2.5

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/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 04a9512..0da32e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -966,10 +966,15 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev) { char *addr;
- if (dev->addr.pci.domain != 0 || - dev->addr.pci.bus != 0) { + if (dev->addr.pci.domain != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI domain 0 and bus 0 are available")); + _("Only PCI domain 0 is available")); + return NULL; + } + if (dev->addr.pci.bridge < 0 && dev->addr.pci.bus != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI bus 0 is available " + "without pci-bridge support")); return NULL; }
@@ -1768,7 +1773,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, _("Only PCI device addresses with domain=0 are supported")); return -1; } - if (info->addr.pci.bus != 0) { + if (info->addr.pci.bus != 0 && info->addr.pci.bridge < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only PCI device addresses with bus=0 are supported"));
Above you added the qualifier "without pci-bridge support" to the error message. Probably worth being consistent and adding it here as well.
return -1; @@ -1801,7 +1806,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, * When QEMU grows support for > 1 PCI domain, then pci.0 change * to pciNN.0 where NN is the domain number */ - if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) + if (info->addr.pci.bridge >= 0) + virBufferAsprintf(buf, ",bus=pci.%d", info->addr.pci.bus); + else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) virBufferAsprintf(buf, ",bus=pci.0"); else virBufferAsprintf(buf, ",bus=pci"); @@ -3064,6 +3071,12 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, int model;
switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE: + virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d", def->idx+1); + virBufferAsprintf(&buf, ",id=pci.%d", def->idx); + if (def->idx == 0) + goto out; + break; case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: model = def->model; if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0) @@ -3137,6 +3150,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0) goto error;
+out: if (virBufferError(&buf)) { virReportOOMError(); goto error; @@ -5033,6 +5047,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* We don't add an explicit IDE or FD controller because the * provided PIIX4 device already includes one. It isn't possible to * remove the PIIX4. */ + VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE, VIR_DOMAIN_CONTROLLER_TYPE_USB, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, VIR_DOMAIN_CONTROLLER_TYPE_SATA, -- 1.7.2.5
-- Doug Goldstein

在 2013-01-07一的 22:42 -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/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 04a9512..0da32e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -966,10 +966,15 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev) { char *addr;
- if (dev->addr.pci.domain != 0 || - dev->addr.pci.bus != 0) { + if (dev->addr.pci.domain != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI domain 0 and bus 0 are available")); + _("Only PCI domain 0 is available")); + return NULL; + } + if (dev->addr.pci.bridge < 0 && dev->addr.pci.bus != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI bus 0 is available " + "without pci-bridge support")); return NULL; }
@@ -1768,7 +1773,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, _("Only PCI device addresses with domain=0 are supported")); return -1; } - if (info->addr.pci.bus != 0) { + if (info->addr.pci.bus != 0 && info->addr.pci.bridge < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only PCI device addresses with bus=0 are supported"));
Above you added the qualifier "without pci-bridge support" to the error message. Probably worth being consistent and adding it here as well.
OK, will fix.
return -1; @@ -1801,7 +1806,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, * When QEMU grows support for > 1 PCI domain, then pci.0 change * to pciNN.0 where NN is the domain number */ - if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) + if (info->addr.pci.bridge >= 0) + virBufferAsprintf(buf, ",bus=pci.%d", info->addr.pci.bus); + else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) virBufferAsprintf(buf, ",bus=pci.0"); else virBufferAsprintf(buf, ",bus=pci"); @@ -3064,6 +3071,12 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, int model;
switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE: + virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d", def->idx+1); + virBufferAsprintf(&buf, ",id=pci.%d", def->idx); + if (def->idx == 0) + goto out; + break; case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: model = def->model; if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0) @@ -3137,6 +3150,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0) goto error;
+out: if (virBufferError(&buf)) { virReportOOMError(); goto error; @@ -5033,6 +5047,7 @@ qemuBuildCommandLine(virConnectPtr conn, /* We don't add an explicit IDE or FD controller because the * provided PIIX4 device already includes one. It isn't possible to * remove the PIIX4. */ + VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE, VIR_DOMAIN_CONTROLLER_TYPE_USB, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, VIR_DOMAIN_CONTROLLER_TYPE_SATA, -- 1.7.2.5
-- regards! li guang

On Mon, Jan 7, 2013 at 7:58 PM, liguang <lig.fnst@cn.fujitsu.com> wrote:
Now, it's impossible to arrange devices into multi-pci-bus, for example: <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x1' slot='0x02' function='0x0'/> </video> libvirt will complain about "bus != 0", fortunately, qemu supports pci-to-pci bridge, if we want to use multi-pci-bus, we can define 2 pci bridge controllers, then attach 1 to the other as a subordinate pci-bus, so, 2 pci-buses appear. for example: <controller type='pci-bridge' index='0'/> <controller type='pci-bridge' index='1'> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' bridge='0'/> </controller> <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x01' slot='0x02' function='0x0' bridge='1'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' bridge='0'/> </video>
src/conf/device_conf.c | 11 ++++++++++- src/conf/device_conf.h | 1 + src/conf/domain_conf.c | 5 ++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 5 files changed, 36 insertions(+), 7 deletions(-)
I had a few comments to the specific patches. I think you're missing one part to the whole series which should probably be 1/3 in the patch series. Adding a QEMU_CAP for PCI Bridge support and specifically probing it or adding it where it was supported. Since we're modifying the QEMU command line arguments this series probably needs to add some test cases as well. -- Doug Goldstein

在 2013-01-07一的 22:44 -0600,Doug Goldstein写道:
On Mon, Jan 7, 2013 at 7:58 PM, liguang <lig.fnst@cn.fujitsu.com> wrote:
Now, it's impossible to arrange devices into multi-pci-bus, for example: <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x1' slot='0x02' function='0x0'/> </video> libvirt will complain about "bus != 0", fortunately, qemu supports pci-to-pci bridge, if we want to use multi-pci-bus, we can define 2 pci bridge controllers, then attach 1 to the other as a subordinate pci-bus, so, 2 pci-buses appear. for example: <controller type='pci-bridge' index='0'/> <controller type='pci-bridge' index='1'> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' bridge='0'/> </controller> <sound model='ac97'> <address type='pci' domain='0x0000' bus='0x01' slot='0x02' function='0x0' bridge='1'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' bridge='0'/> </video>
src/conf/device_conf.c | 11 ++++++++++- src/conf/device_conf.h | 1 + src/conf/domain_conf.c | 5 ++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 25 ++++++++++++++++++++----- 5 files changed, 36 insertions(+), 7 deletions(-)
I had a few comments to the specific patches. I think you're missing one part to the whole series which should probably be 1/3 in the patch series. Adding a QEMU_CAP for PCI Bridge support and specifically probing it or adding it where it was supported. Since we're modifying the QEMU command line arguments this series probably needs to add some test cases as well.
OK, thanks! -- regards! li guang
participants (4)
-
Daniel P. Berrange
-
Doug Goldstein
-
li guang
-
liguang