diff --git a/lxd/device/device_utils_unix.go b/lxd/device/device_utils_unix.go index 6bb66cf9a6b5..143be8fec725 100644 --- a/lxd/device/device_utils_unix.go +++ b/lxd/device/device_utils_unix.go @@ -45,6 +45,21 @@ 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) @@ -91,13 +106,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 @@ -176,6 +187,9 @@ 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"] != "" { @@ -183,6 +197,9 @@ func UnixDeviceCreate(s *state.State, idmapSet *idmap.IdmapSet, devicesPath stri 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.