summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Xie <xiewei.fire@gmail.com>2018-03-22 14:50:11 +0800
committerCheng Zhang <cheng.zhang@citrix.com>2018-03-22 14:50:11 +0800
commit1ea5634256b9a30dde3f86bfce08e4269899b884 (patch)
tree28f83ce6566c1f2881e4daa4c97b5f6617ed1182
parent6219ce6418c7a9bae6ceb11c73a17314a984b7c7 (diff)
downloadvyos-xe-guest-utilities-1ea5634256b9a30dde3f86bfce08e4269899b884.tar.gz
vyos-xe-guest-utilities-1ea5634256b9a30dde3f86bfce08e4269899b884.zip
Add SRIOV VF Supportv7.10.0
* CP-26664: Add SRIOV VF IP collection (#49) - Add support for xenstore-ls Signed-off-by: Wei Xie <wei.xie@citrix.com> * CP-25986: Add xenstore-list command Signed-off-by: Deli Zhang <Deli.Zhang@citrix.com> * CP-27273: Enhance the printing format of guest_utilities.xs_list for HCL using. (#51) Signed-off-by: Wei Xie <wei.xie@citrix.com>
-rw-r--r--Makefile1
-rw-r--r--guestmetric/guestmetric_linux.go59
-rw-r--r--xenstore/xenstore.go20
-rw-r--r--xenstoreclient/xenstore.go24
4 files changed, 95 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index b4e455e..7060ff6 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ $(DISTDIR)/$(PACKAGE)_$(VERSION)-$(RELEASE)_$(ARCH).tgz: $(OBJECTS)
ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-write ; \
ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-exists ; \
ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-rm ; \
+ ln -sf /usr/bin/xenstore $(STAGEDIR)/usr/bin/xenstore-list ; \
install -d $(STAGEDIR)/etc/udev/rules.d/ ; \
install -m 644 $(SOURCEDIR)/xen-vcpu-hotplug.rules $(STAGEDIR)/etc/udev/rules.d/z10_xen-vcpu-hotplug.rules ; \
cd $(STAGEDIR) ; \
diff --git a/guestmetric/guestmetric_linux.go b/guestmetric/guestmetric_linux.go
index dd75c09..e61ccca 100644
--- a/guestmetric/guestmetric_linux.go
+++ b/guestmetric/guestmetric_linux.go
@@ -119,9 +119,9 @@ func enumNetworkAddresses(iface string) (GuestMetric, error) {
return d, nil
}
-func getVifId(iface string) (string, error) {
- filePath := fmt.Sprintf("/sys/class/net/%s/device/nodename", iface)
- strLine, err := readSysfs(filePath)
+func getPlainVifId(path string) (string, error) {
+ nodenamePath := fmt.Sprintf("%s/device/nodename", path)
+ strLine, err := readSysfs(nodenamePath)
if err != nil {
return "", err
}
@@ -131,12 +131,53 @@ func getVifId(iface string) (string, error) {
vifId = matched[1]
}
if vifId == "" {
- return "", fmt.Errorf("Not found string like \"device/vif/[id]\" in file %s", filePath)
+ return "", fmt.Errorf("Not found string like \"device/vif/[id]\" in file %s", nodenamePath)
} else {
return vifId, nil
}
}
+func (c *Collector) getSriovVifId(path string) (string, error) {
+ sriovDevicePath := "xenserver/device/net-sriov-vf"
+ macAddress, err := readSysfs(path + "/address")
+ if err != nil {
+ return "", err
+ }
+ subPaths, err := c.Client.List(sriovDevicePath)
+ if err != nil {
+ return "", err
+ }
+ for _, subPath := range subPaths {
+ iterMac, err := c.Client.Read(fmt.Sprintf("%s/%s/mac", sriovDevicePath, subPath))
+ if err != nil {
+ continue
+ }
+ if iterMac == macAddress {
+ return subPath, nil
+ }
+ }
+ return "", fmt.Errorf("Cannot find a MAC address to map with %s", path)
+}
+
+// return vif_xenstore_prefix * vif_id * error where
+// `vif_xenstore_prefix` could be either `attr/vif` for plain VIF or
+// `xenserver/attr/net-sriov-vf` for SR-IOV VIF
+func (c *Collector) getTargetXenstorePath(path string) (string, string, error) {
+ plainVifPrefix := "attr/vif"
+ sriovVifPrefix := "xenserver/attr/net-sriov-vf"
+ // try to get `vif_id` from nodename interface, only a plain VIF have the nodename interface.
+ vifId, err1 := getPlainVifId(path)
+ if vifId != "" {
+ return plainVifPrefix, vifId, nil
+ }
+ // not a plain VIF, it could possible be an SR-IOV VIF, try to get vif_id from MAC address mapping
+ vifId, err2 := c.getSriovVifId(path)
+ if vifId != "" {
+ return sriovVifPrefix, vifId, nil
+ }
+ return "", "", fmt.Errorf("Failed to get VIF ID, errors: %s | %s", err1.Error(), err2.Error())
+}
+
func (c *Collector) CollectNetworkAddr() (GuestMetric, error) {
current := make(GuestMetric, 0)
@@ -149,20 +190,20 @@ func (c *Collector) CollectNetworkAddr() (GuestMetric, error) {
}
paths = append(paths, prefixPaths...)
}
-
for _, path := range paths {
- iface := filepath.Base(path)
- vifId, err := getVifId(iface)
+ // a path is going to be like "/sys/class/net/eth0"
+ prefix, vifId, err := c.getTargetXenstorePath(path)
if err != nil {
continue
}
+ iface := filepath.Base(path)
if addrs, err := enumNetworkAddresses(iface); err == nil {
for tag, addr := range addrs {
- current[fmt.Sprintf("vif/%s/%s", vifId, tag)] = addr
+ current[fmt.Sprintf("%s/%s/%s", prefix, vifId, tag)] = addr
}
}
}
- return prefixKeys("attr/", current), nil
+ return current, nil
}
func readSysfs(filename string) (string, error) {
diff --git a/xenstore/xenstore.go b/xenstore/xenstore.go
index c6fe1a5..912de25 100644
--- a/xenstore/xenstore.go
+++ b/xenstore/xenstore.go
@@ -46,6 +46,24 @@ func xs_read(script_name string, args []string) {
}
}
+func xs_list(script_name string, args []string) {
+ if len(args) == 0 || args[0] == "-h" {
+ die("Usage: %s key [ key ... ]", script_name)
+ }
+
+ xs := new_xs()
+ for _, key := range args[:] {
+ result, err := xs.List(key)
+ if err != nil {
+ die("%s error: %v", script_name, err)
+ }
+
+ for _, subPath := range result {
+ fmt.Println(subPath)
+ }
+ }
+}
+
func xs_write(script_name string, args []string) {
if len(args) == 0 || args[0] == "-h" || len(args)%2 != 0 {
die("Usage: %s key value [ key value ... ]", script_name)
@@ -111,6 +129,8 @@ func main() {
switch operation {
case "read":
xs_read(script_name, args)
+ case "list":
+ xs_list(script_name, args)
case "write":
xs_write(script_name, args)
case "rm":
diff --git a/xenstoreclient/xenstore.go b/xenstoreclient/xenstore.go
index 5112c40..571481a 100644
--- a/xenstoreclient/xenstore.go
+++ b/xenstoreclient/xenstore.go
@@ -63,6 +63,7 @@ type XenStoreClient interface {
Close() error
DO(packet *Packet) (*Packet, error)
Read(path string) (string, error)
+ List(path string) ([]string, error)
Mkdir(path string) error
Rm(path string) error
Write(path string, value string) error
@@ -281,6 +282,25 @@ func (xs *XenStore) Read(path string) (string, error) {
return string(resp.Value), nil
}
+func (xs *XenStore) List(path string) ([]string, error) {
+ v := []byte(path + "\x00")
+ req := &Packet{
+ OpCode: XS_DIRECTORY,
+ Req: 0,
+ TxID: xs.tx,
+ Length: uint32(len(v)),
+ Value: v,
+ }
+ resp, err := xs.DO(req)
+ if err != nil {
+ return []string{}, err
+ }
+ subItems := strings.Split(
+ string(bytes.Trim(resp.Value, "\x00")), "\x00")
+
+ return subItems, nil
+}
+
func (xs *XenStore) Mkdir(path string) error {
v := []byte(path + "\x00")
req := &Packet{
@@ -507,6 +527,10 @@ func (xs *CachedXenStore) Read(path string) (string, error) {
return xs.xs.Read(path)
}
+func (xs *CachedXenStore) List(path string) ([]string, error) {
+ return xs.xs.List(path)
+}
+
func (xs *CachedXenStore) Mkdir(path string) error {
return xs.xs.Mkdir(path)
}