summaryrefslogtreecommitdiff
path: root/guestmetric/guestmetric_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'guestmetric/guestmetric_linux.go')
-rw-r--r--guestmetric/guestmetric_linux.go59
1 files changed, 50 insertions, 9 deletions
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) {