The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6206

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 1d4cb2778c2c602ceadd81308e99e2ec7836450b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Thu, 12 Sep 2019 07:22:57 +0100
Subject: [PATCH 1/3] api: Add resources_disk_sata extension
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 doc/api-extensions.md | 9 +++++++++
 shared/version/api.go | 1 +
 2 files changed, 10 insertions(+)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 98f0a39a83..a94285efce 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -829,3 +829,12 @@ This introduces the concept of instances, of which 
currently the only type is "c
 
 ## image\_types
 This introduces support for a new Type field on images, indicating what type 
of images they are.
+
+## resources\_disk\_sata
+Extends the disk resource API struct to include:
+ - Proper detection of sata devices (type)
+ - Device path
+ - Drive RPM
+ - Block size
+ - Firmware version
+ - Model revision
diff --git a/shared/version/api.go b/shared/version/api.go
index 48aa25a7d7..d6d182821d 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -166,6 +166,7 @@ var APIExtensions = []string{
        "daemon_storage",
        "instances",
        "image_types",
+       "resources_disk_sata",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From fb546cd88bfde200e685958e5140c758130d26ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Thu, 12 Sep 2019 07:23:47 +0100
Subject: [PATCH 2/3] shared/api: Extend ResourcesStorageDisk
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 shared/api/resource.go | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/shared/api/resource.go b/shared/api/resource.go
index 6590398848..8b0be0220f 100644
--- a/shared/api/resource.go
+++ b/shared/api/resource.go
@@ -223,6 +223,14 @@ type ResourcesStorageDisk struct {
        WWN       string `json:"wwn,omitempty" yaml:"wwn,omitempty"`
        NUMANode  uint64 `json:"numa_node" yaml:"numa_node"`
 
+       // API extension: resources_disk_sata
+       DevicePath      string `json:"device_path" yaml:"device_path"`
+       BlockSize       uint64 `json:"block_size" yaml:"block_size"`
+       FirmwareVersion string `json:"firmware_version,omitempty" 
yaml:"firmware_version,omitempty"`
+       RPM             uint64 `json:"rpm" yaml:"rpm"`
+       ModelRevision   string `json:"model_revision,omitempty" 
yaml:"model_revision,omitempty"`
+       Serial          string `json:"serial,omitempty" yaml:"serial,omitempty"`
+
        Partitions []ResourcesStorageDiskPartition `json:"partitions" 
yaml:"partitions"`
 }
 

From 35a2690a1e64b5a94dcaddd98dcd5f094fbd690d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Fri, 13 Sep 2019 02:21:56 +0200
Subject: [PATCH 3/3] lxd/resources: Add extra storage fields
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/resources/storage.go | 125 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/lxd/resources/storage.go b/lxd/resources/storage.go
index ffd5d0fa4b..0a0fe6a1ad 100644
--- a/lxd/resources/storage.go
+++ b/lxd/resources/storage.go
@@ -1,17 +1,104 @@
 package resources
 
 import (
+       "bufio"
+       "fmt"
        "io/ioutil"
+       "os"
        "path/filepath"
+       "strconv"
        "strings"
 
        "github.com/pkg/errors"
+       "golang.org/x/sys/unix"
 
        "github.com/lxc/lxd/shared/api"
 )
 
+var devDiskByPath = "/dev/disk/by-path"
+var runUdevData = "/run/udev/data"
 var sysClassBlock = "/sys/class/block"
 
+func storageAddDriveInfo(devicePath string, disk *api.ResourcesStorageDisk) 
error {
+       // Attempt to open the device path
+       f, err := os.Open(devicePath)
+       if err != nil {
+               if !os.IsPermission(err) && !os.IsNotExist(err) {
+                       return err
+               }
+       } else {
+               defer f.Close()
+               fd := int(f.Fd())
+
+               // Retrieve the block size
+               res, err := unix.IoctlGetInt(fd, unix.BLKPBSZGET)
+               if err != nil {
+                       return err
+               }
+
+               disk.BlockSize = uint64(res)
+       }
+
+       // Retrieve udev information
+       udevInfo := filepath.Join(runUdevData, fmt.Sprintf("b%s", disk.Device))
+       if sysfsExists(udevInfo) {
+               // Get the udev information
+               f, err := os.Open(udevInfo)
+               if err != nil {
+                       return errors.Wrapf(err, "Failed to open \"%s\"", 
udevInfo)
+               }
+               defer f.Close()
+
+               udevInfo := bufio.NewScanner(f)
+               for udevInfo.Scan() {
+                       line := strings.TrimSpace(udevInfo.Text())
+
+                       if !strings.HasPrefix(line, "E:") {
+                               continue
+                       }
+
+                       fields := strings.SplitN(line, "=", 2)
+                       if len(fields) != 2 {
+                               continue
+                       }
+
+                       key := strings.TrimSpace(fields[0])
+                       value := strings.TrimSpace(fields[1])
+
+                       // Finer grained disk type
+                       if key == "E:ID_ATA_SATA" && value == "1" {
+                               disk.Type = "sata"
+                       }
+
+                       if key == "E:ID_USB_DRIVER" && value == "usb-storage" {
+                               disk.Type = "usb"
+                       }
+
+                       // Model revision number
+                       if key == "E:ID_REVISION" && disk.ModelRevision == "" {
+                               disk.ModelRevision = value
+                       }
+
+                       // Serial number
+                       if key == "E:ID_SERIAL_SHORT" && disk.Serial == "" {
+                               disk.Serial = value
+                       }
+
+                       // Rotation per minute
+                       if key == "E:ID_ATA_ROTATION_RATE_RPM" && disk.RPM == 0 
{
+                               valueUint, err := strconv.ParseUint(value, 10, 
64)
+                               if err != nil {
+                                       return errors.Wrap(err, "Failed to 
parse RPM value")
+                               }
+
+                               disk.RPM = valueUint
+                       }
+               }
+       }
+
+       return nil
+}
+
 // GetStorage returns a filled api.ResourcesStorage struct ready for use by LXD
 func GetStorage() (*api.ResourcesStorage, error) {
        storage := api.ResourcesStorage{}
@@ -39,6 +126,16 @@ func GetStorage() (*api.ResourcesStorage, error) {
                        disk := api.ResourcesStorageDisk{}
                        disk.ID = entryName
 
+                       // Firmware revision
+                       if sysfsExists(filepath.Join(devicePath, 
"firmware_rev")) {
+                               firmwareRevision, err := 
ioutil.ReadFile(filepath.Join(devicePath, "firmware_rev"))
+                               if err != nil {
+                                       return nil, errors.Wrapf(err, "Failed 
to read \"%s\"", filepath.Join(devicePath, "firmware_rev"))
+                               }
+
+                               disk.FirmwareVersion = 
strings.TrimSpace(string(firmwareRevision))
+                       }
+
                        // Device node
                        diskDev, err := 
ioutil.ReadFile(filepath.Join(entryPath, "dev"))
                        if err != nil {
@@ -158,6 +255,34 @@ func GetStorage() (*api.ResourcesStorage, error) {
                                disk.Partitions = append(disk.Partitions, 
partition)
                        }
 
+                       // Try to find the udev device path
+                       if sysfsExists(devDiskByPath) {
+                               links, err := ioutil.ReadDir(devDiskByPath)
+                               if err != nil {
+                                       return nil, errors.Wrapf(err, "Failed 
to list the links in \"%s\"", devDiskByPath)
+                               }
+
+                               for _, link := range links {
+                                       linkName := link.Name()
+                                       linkPath := 
filepath.Join(devDiskByPath, linkName)
+
+                                       linkTarget, err := 
filepath.EvalSymlinks(linkPath)
+                                       if err != nil {
+                                               return nil, errors.Wrapf(err, 
"Failed to track down \"%s\"", linkPath)
+                                       }
+
+                                       if linkTarget == filepath.Join("/dev", 
entryName) {
+                                               disk.DevicePath = linkName
+                                       }
+                               }
+                       }
+
+                       // Pull direct disk information
+                       err = storageAddDriveInfo(filepath.Join("/dev", 
entryName), &disk)
+                       if err != nil {
+                               return nil, errors.Wrapf(err, "Failed to 
retrieve disk information from \"%s\"", filepath.Join("/dev", entryName))
+                       }
+
                        // Add to list
                        storage.Disks = append(storage.Disks, disk)
                }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to