@@ -20,9 +20,34 @@ type diskInfoCache struct {
2020 values map [string ]string
2121}
2222
23+ func getHostPath (envVar , fallback string ) string {
24+ if path := os .Getenv (envVar ); path != "" {
25+ return path
26+ }
27+ if root := os .Getenv ("HOST_ROOT" ); root != "" {
28+ return filepath .Join (root , fallback )
29+ }
30+ if prefix := os .Getenv ("HOST_MOUNT_PREFIX" ); prefix != "" {
31+ return filepath .Join (prefix , fallback )
32+ }
33+ return filepath .Join ("/" , fallback )
34+ }
35+
36+ func getDevPath () string {
37+ return getHostPath ("HOST_DEV" , "dev" )
38+ }
39+
40+ func getRunPath () string {
41+ return getHostPath ("HOST_RUN" , "run" )
42+ }
43+
44+ func getSysPath () string {
45+ return getHostPath ("HOST_SYS" , "sys" )
46+ }
47+
2348func (d * DiskIO ) diskInfo (devName string ) (map [string ]string , error ) {
2449 // Check if the device exists
25- path := "/dev/" + devName
50+ path := filepath . Join ( getDevPath (), devName )
2651 var stat unix.Stat_t
2752 if err := unix .Stat (path , & stat ); err != nil {
2853 return nil , fmt .Errorf ("error reading %s: %w" , path , err )
@@ -43,10 +68,10 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
4368 } else {
4469 major := unix .Major (uint64 (stat .Rdev )) //nolint:unconvert // Conversion needed for some architectures
4570 minor := unix .Minor (uint64 (stat .Rdev )) //nolint:unconvert // Conversion needed for some architectures
46- udevDataPath = fmt . Sprintf ( "/run/ udev/ data/ b%d:%d" , major , minor )
71+ udevDataPath = filepath . Join ( getRunPath (), " udev" , " data" , fmt . Sprintf ( " b%d:%d" , major , minor ) )
4772 if _ , err := os .Stat (udevDataPath ); err != nil {
4873 // This path failed, try the fallback .udev style (non-systemd)
49- udevDataPath = "/dev/ .udev/db/ block:" + devName
74+ udevDataPath = filepath . Join ( getDevPath (), " .udev" , "db" , " block:"+ devName )
5075 if _ , err := os .Stat (udevDataPath ); err != nil {
5176 // Giving up, cannot retrieve disk info
5277 return nil , fmt .Errorf ("error reading %s: %w" , udevDataPath , err )
@@ -66,7 +91,7 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
6691 // This allows us to also "poison" it during test scenarios
6792 sysBlockPath = ic .sysBlockPath
6893 } else {
69- sysBlockPath = "/sys/ class/ block/" + devName
94+ sysBlockPath = filepath . Join ( getSysPath (), " class" , " block" , devName )
7095 }
7196
7297 devInfo , err := readDevData (sysBlockPath )
@@ -81,6 +106,7 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
81106 d .infoCache [devName ] = diskInfoCache {
82107 modifiedAt : stat .Mtim .Nano (),
83108 udevDataPath : udevDataPath ,
109+ sysBlockPath : sysBlockPath ,
84110 values : info ,
85111 }
86112
@@ -158,7 +184,11 @@ func readDevData(path string) (map[string]string, error) {
158184 // Find the DEVPATH property
159185 if devlnk , err := filepath .EvalSymlinks (filepath .Join (path , "device" )); err == nil {
160186 devlnk = filepath .Join (devlnk , filepath .Base (path ))
187+ devlnk = strings .TrimPrefix (devlnk , getSysPath ())
161188 devlnk = strings .TrimPrefix (devlnk , "/sys" )
189+ if ! strings .HasPrefix (devlnk , "/" ) {
190+ devlnk = "/" + devlnk
191+ }
162192 info ["DEVPATH" ] = devlnk
163193 }
164194
@@ -173,8 +203,14 @@ func resolveName(name string) string {
173203 if ! errors .Is (err , fs .ErrNotExist ) {
174204 return name
175205 }
176- // Try to prepend "/dev"
177- resolved , err = filepath .EvalSymlinks ("/dev/" + name )
206+ // Try to resolve relative to the host device path.
207+ switch {
208+ case strings .HasPrefix (name , "/dev/" ):
209+ name = strings .TrimPrefix (name , "/dev/" )
210+ case strings .HasPrefix (name , "/" ):
211+ name = strings .TrimPrefix (name , "/" )
212+ }
213+ resolved , err = filepath .EvalSymlinks (filepath .Join (getDevPath (), name ))
178214 if err != nil {
179215 return name
180216 }
@@ -183,7 +219,7 @@ func resolveName(name string) string {
183219}
184220
185221func getDeviceWWID (name string ) string {
186- path := fmt . Sprintf ( "/sys/ block/%s/wwid " , filepath .Base (name ))
222+ path := filepath . Join ( getSysPath (), " block" , filepath .Base (name ), "wwid" )
187223 buf , err := os .ReadFile (path )
188224 if err != nil {
189225 return ""
0 commit comments