1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-28 13:48:49 +08:00

Merge pull request #532 from jsoriano/serial-number-without-udevadm

Read disk model and serial from udev data or sysfs on Linux
This commit is contained in:
Lomanic 2018-06-05 09:51:35 +02:00 committed by GitHub
commit bc5d02c9ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,10 +3,11 @@
package disk package disk
import ( import (
"bufio"
"bytes"
"context" "context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
@ -385,27 +386,34 @@ func GetDiskSerialNumber(name string) string {
} }
func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
n := fmt.Sprintf("--name=%s", name) var stat unix.Stat_t
udevadm, err := exec.LookPath("/sbin/udevadm") err := unix.Stat(name, &stat)
if err != nil { if err != nil {
return "" return ""
} }
major := unix.Major(stat.Rdev)
minor := unix.Minor(stat.Rdev)
out, err := invoke.CommandWithContext(ctx, udevadm, "info", "--query=property", n) // Try to get the serial from udev data
udevDataPath := fmt.Sprintf("/run/udev/data/b%d:%d", major, minor)
// does not return error, just an empty string if udevdata, err := ioutil.ReadFile(udevDataPath); err == nil {
if err != nil { scanner := bufio.NewScanner(bytes.NewReader(udevdata))
return "" for scanner.Scan() {
} values := strings.Split(scanner.Text(), "=")
lines := strings.Split(string(out), "\n") if len(values) == 2 && values[0] == "E:ID_SERIAL" {
for _, line := range lines {
values := strings.Split(line, "=")
if len(values) < 2 || values[0] != "ID_SERIAL" {
// only get ID_SERIAL, not ID_SERIAL_SHORT
continue
}
return values[1] return values[1]
} }
}
}
// Try to get the serial from sysfs, look at the disk device (minor 0) directly
// because if it is a partition it is not going to contain any device information
devicePath := fmt.Sprintf("/sys/dev/block/%d:0/device", major)
model, _ := ioutil.ReadFile(filepath.Join(devicePath, "model"))
serial, _ := ioutil.ReadFile(filepath.Join(devicePath, "serial"))
if len(model) > 0 && len(serial) > 0 {
return fmt.Sprintf("%s_%s", string(model), string(serial))
}
return "" return ""
} }