Skip to content

Commit

Permalink
lxd/device: Add unixDeviceOwnership function and change default own…
Browse files Browse the repository at this point in the history
…ership behaviour

This commit adds a function `unixDeviceOwnership()` which returns device
ownership (gid and uid). The new default ownership behaviour for unix
devices is to use the host's ownership rule when no gid or uid is
specified in the device config. If the ownership can't be identified,
root (0) ownership is used.

Signed-off-by: Kadin Sayani <[email protected]>
  • Loading branch information
kadinsayani committed Nov 12, 2024
1 parent d90b89a commit 4c9ee63
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions lxd/device/device_utils_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ func unixDeviceAttributes(path string) (dType string, major uint32, minor uint32
return dType, major, minor, nil
}

// unixDeviceOwnership returns the ownership (gid and uid) for a device.
func unixDeviceOwnership(path string) (gid uint32, uid uint32, err error) {
stat := unix.Stat_t{}
err = unix.Stat(path, &stat)
if err != nil {
return 0, 0, err
}

gid = stat.Gid
uid = stat.Uid

return gid, uid, nil
}

// unixDeviceModeOct converts a string unix octal mode to an int.
func unixDeviceModeOct(strmode string) (int, error) {
i, err := strconv.ParseInt(strmode, 8, 32)
Expand Down Expand Up @@ -91,13 +105,9 @@ func unixDeviceDestPath(m deviceConfig.Device) string {
return destPath
}

// UnixDeviceCreate creates a UNIX device (either block or char). If the supplied device config map
// contains a major and minor number for the device, then a stat is avoided, otherwise this info
// retrieved from the origin device. Similarly, if a mode is supplied in the device config map or
// defaultMode is set as true, then the device is created with the supplied or default mode (0660)
// respectively, otherwise the origin device's mode is used. If the device config doesn't contain a
// type field then it defaults to created a unix-char device. The ownership of the created device
// defaults to root (0) but can be specified with the uid and gid fields in the device config map.
// UnixDeviceCreate creates a UNIX device (either block or char).
// If the supplied device config map contains a major and minor number for the device, then a stat is avoided, otherwise this info retrieved from the origin device. Similarly, if a mode is supplied in the device config map or defaultMode is set as true, then the device is created with the supplied or default mode (0660)respectively, otherwise the origin device's mode is used.
// If the device config doesn't contain a type field then it defaults to created a unix-char device. The ownership of the created device defaults to the host's ownership but can be specified with the uid and gid fields in the device config map. If the host ownership can't be identified, root (0) ownership is applied to the device.
// It returns a UnixDevice containing information about the device created.
func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath string, prefix string, m deviceConfig.Device, defaultMode bool) (*UnixDevice, error) {
var err error
Expand Down Expand Up @@ -176,13 +186,19 @@ func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath stri
if err != nil {
return nil, fmt.Errorf("Invalid uid %s in device %s", m["uid"], srcPath)
}
} else {
_, uid, _ := unixDeviceOwnership(srcPath)
d.UID = int(uid)
}

if m["gid"] != "" {
d.GID, err = strconv.Atoi(m["gid"])
if err != nil {
return nil, fmt.Errorf("Invalid gid %s in device %s", m["gid"], srcPath)
}
} else {
gid, _, _ := unixDeviceOwnership(srcPath)
d.GID = int(gid)
}

// Create the devices directory if missing.
Expand Down

0 comments on commit 4c9ee63

Please sign in to comment.