Skip to content

Commit

Permalink
[US4264] feat(diskCR): add partition and filesystem info
Browse files Browse the repository at this point in the history
added partition and filesystem info to DiskCR. If partitions are present on
the disk, the partition type and filesystem information will be stored onto
the diskCR. If the whole disk is formatted with a filesystem, that info will
also be included

The change will give the following output when a partitioned disk is described
   ...
       links:
       - /dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:3:0
     partitionDetails:
     - fileSystemType: None
       partitionType: "0x83"
     - fileSystemType: None
       partitionType: "0x8e"
     path: /dev/sdb
   stats:
   ...

If the disk is formatted as a whole with a filesystem
   ...
       links:
       - /dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:5:0
     fileSystem: ext4
     path: /dev/sdb
   stats:
   ...

Signed-off-by: Akhil Mohan <akhil.mohan@mayadata.io>
  • Loading branch information
akhilerm authored and kmova committed Feb 4, 2019
1 parent 1fe7be5 commit f972084
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 37 deletions.
22 changes: 22 additions & 0 deletions cmd/controller/disk.go
Expand Up @@ -18,6 +18,7 @@ package controller

import (
apis "github.com/openebs/node-disk-manager/pkg/apis/openebs.io/v1alpha1"
udev "github.com/openebs/node-disk-manager/pkg/udev"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -45,6 +46,8 @@ type DiskInfo struct {
Compliance string // Compliance is implemented specifications version i.e. SPC-1, SPC-2, etc
DiskType string // DiskType represents the type of disk like Disk, Sparse etc.,
DriveType string // DriveType represents the type of disk like HHD, HDD etc.,
FileSystemInfo string // FileSystemInfo stores the filesystem on the disk. Can be none, xfs, ext4 etc
PartitionData []PartitionInfo // Information of the partitions on the disk

//Stats of disk which keep changing
TotalBytesRead uint64
Expand Down Expand Up @@ -78,6 +81,11 @@ type ProbeIdentifier struct {
SeachestIdentifier string // SeachestIdentifier (devPath) is used to identify disk by seachest.
}

type PartitionInfo struct {
PartitionType string // Partition type like 83, 8e etc.
FileSystem string // Filesystem of partition. can be none, xfs etc.
}

// NewDiskInfo returns a pointer of empty diskInfo struct which will
// be field by different probes each probe will responsible for
// populate some specific fields of DiskInfo struct.
Expand All @@ -98,6 +106,17 @@ func (di *DiskInfo) ToDisk() apis.Disk {
return dr
}

// ToPartition convert the PartitionData struct inside DiskInfo to apis.Partition
// which will be used to include the parition information in the Disk CR
func (di *DiskInfo) ToPartition() []apis.Partition {
partition := make([]apis.Partition, 0)
for _, partitionData := range di.PartitionData {
partition = append(partition, apis.Partition{PartitionType: partitionData.PartitionType,
FileSystemType: partitionData.FileSystem})
}
return partition
}

// getObjectMeta returns ObjectMeta struct which contains labels and Name of resource
// It is used to populate data of Disk struct which is a disk CR.
func (di *DiskInfo) getObjectMeta() metav1.ObjectMeta {
Expand Down Expand Up @@ -140,6 +159,9 @@ func (di *DiskInfo) getDiskSpec() apis.DiskSpec {
diskSpec.Path = di.getPath()
diskSpec.Details = di.getDiskDetails()
diskSpec.Capacity = di.getDiskCapacity()
if di.FileSystemInfo != udev.UDEV_FS_NONE {
diskSpec.FileSystem = di.FileSystemInfo
}
diskSpec.DevLinks = di.getDiskLinks()
return diskSpec
}
Expand Down
25 changes: 24 additions & 1 deletion cmd/probe/eventhandler.go
Expand Up @@ -54,7 +54,29 @@ func (pe *ProbeEvent) addDiskEvent(msg controller.EventMessage) {
}
glog.Info("processed data for ", diskDetails.ProbeIdentifiers.Uuid)
oldDr := pe.Controller.GetExistingResource(diskList, diskDetails.ProbeIdentifiers.Uuid)
pe.Controller.PushDiskResource(oldDr, diskDetails)
// if old DiskCR doesn't exist and parition is found, it is ignored since we don't need info
// of partition if disk as a whole is ignored
if oldDr == nil && len(diskDetails.PartitionData) != 0 {
glog.Info("Skipping partition of already excluded disk ", diskDetails.ProbeIdentifiers.Uuid)
continue
}
// if diskCR is already present, and udev event is generated for partition, append the partition info
// to the diskCR
if oldDr != nil && len(diskDetails.PartitionData) != 0 {
newDrCopy := oldDr.DeepCopy()
glog.Info("Appending partition data to ", diskDetails.ProbeIdentifiers.Uuid)
newDrCopy.Spec.PartitionDetails = append(newDrCopy.Spec.PartitionDetails, diskDetails.ToPartition()...)
pe.Controller.UpdateDisk(*newDrCopy, oldDr)
} else {
pe.Controller.PushDiskResource(oldDr, diskDetails)
}
/// update the list of DiskCRs
diskList, err = pe.Controller.ListDiskResource()
if err != nil {
glog.Error(err)
go pe.initOrErrorEvent()
return
}
}
}

Expand Down Expand Up @@ -87,6 +109,7 @@ func (pe *ProbeEvent) deleteDiskEvent(msg controller.EventMessage) {
// used for initial setup and when any uid mismatch or error occurred.
func (pe *ProbeEvent) initOrErrorEvent() {
udevProbe := newUdevProbe(pe.Controller)
defer udevProbe.free()
err := udevProbe.scan()
if err != nil {
glog.Error(err)
Expand Down
12 changes: 11 additions & 1 deletion cmd/probe/udevprobe.go
Expand Up @@ -139,12 +139,20 @@ func (up *udevProbe) scan() error {
if err != nil {
continue
}
if newUdevice.IsDisk() {
if newUdevice.IsDisk() || newUdevice.IsParitition() {
uuid := newUdevice.GetUid()
disksUid = append(disksUid, uuid)
deviceDetails := &controller.DiskInfo{}
deviceDetails.ProbeIdentifiers.Uuid = uuid
deviceDetails.ProbeIdentifiers.UdevIdentifier = newUdevice.GetSyspath()
if newUdevice.IsParitition() {
partitionData := controller.PartitionInfo{
PartitionType: newUdevice.GetPartitionType(),
FileSystem: newUdevice.GetFileSystemInfo(),
}
deviceDetails.PartitionData = append(deviceDetails.PartitionData, partitionData)
glog.Info("Partition Data for ", uuid, " : ", deviceDetails.PartitionData)
}
diskInfo = append(diskInfo, deviceDetails)
}
newUdevice.UdevDeviceUnref()
Expand All @@ -154,6 +162,7 @@ func (up *udevProbe) scan() error {
Action: libudevwrapper.UDEV_ACTION_ADD,
Devices: diskInfo,
}
glog.Info("Partition Data to channel: ", eventDetails.Devices[3].PartitionData)
udevevent.UdevEventMessageChannel <- eventDetails
return nil
}
Expand All @@ -171,6 +180,7 @@ func (up *udevProbe) FillDiskDetails(d *controller.DiskInfo) {
d.Vendor = udevDiskDetails.Vendor
d.ByIdDevLinks = udevDiskDetails.ByIdDevLinks
d.ByPathDevLinks = udevDiskDetails.ByPathDevLinks
d.FileSystemInfo = udevDiskDetails.FileSystem
}

// listen listens for event message over UdevEventMessages channel
Expand Down
1 change: 1 addition & 0 deletions cmd/probe/udevprobe_test.go
Expand Up @@ -113,6 +113,7 @@ func TestFillDiskDetails(t *testing.T) {
expectedDiskInfo.DiskType = "disk"
expectedDiskInfo.ByIdDevLinks = mockOsDiskDetails.ByIdDevLinks
expectedDiskInfo.ByPathDevLinks = mockOsDiskDetails.ByPathDevLinks
expectedDiskInfo.FileSystemInfo = mockOsDiskDetails.FileSystem
assert.Equal(t, expectedDiskInfo, actualDiskInfo)
}

Expand Down
25 changes: 16 additions & 9 deletions pkg/apis/openebs.io/v1alpha1/types.go
Expand Up @@ -22,26 +22,28 @@ type Disk struct {

// DiskSpec is the specification for the disk stored as CRD
type DiskSpec struct {
Path string `json:"path"` //Path contain devpath (e.g. /dev/sdb)
Capacity DiskCapacity `json:"capacity"` //Capacity
Details DiskDetails `json:"details"` //Details contains static attributes (model, serial ..)
DevLinks []DiskDevLink `json:"devlinks,omitempty"` //DevLinks contains soft links of one disk
Path string `json:"path"` //Path contain devpath (e.g. /dev/sdb)
Capacity DiskCapacity `json:"capacity"` //Capacity
Details DiskDetails `json:"details"` //Details contains static attributes (model, serial ..)
FileSystem string `json:"fileSystem,omitempty"` //Contains the data about filesystem on the disk
PartitionDetails []Partition `json:"partitionDetails,omitempty"` //Details of partitions in the disk (filesystem, partition type)
DevLinks []DiskDevLink `json:"devlinks,omitempty"` //DevLinks contains soft links of one disk
}

type DiskStatus struct {
State string `json:"state"` //current state of the disk (Active/Inactive)
}

type DiskCapacity struct {
Storage uint64 `json:"storage"` // disk size in bytes
PhysicalSectorSize uint32 `json: "physicalSectorSize"` // disk physical-Sector size in bytes
LogicalSectorSize uint32 `json:"logicalSectorSize"` // disk logical-sector size in bytes
Storage uint64 `json:"storage"` // disk size in bytes
PhysicalSectorSize uint32 `json:"physicalSectorSize"` // disk physical-Sector size in bytes
LogicalSectorSize uint32 `json:"logicalSectorSize"` // disk logical-sector size in bytes
}

// DiskDetails contains basic and static info of a disk
type DiskDetails struct {
RotationRate uint16 `json: "rotationRate"` // Disk rotation speed if disk is not SSD
DriveType string `json: "driveType"` // DriveType represents the type of drive like SSD, HDD etc.,
RotationRate uint16 `json:"rotationRate"` // Disk rotation speed if disk is not SSD
DriveType string `json:"driveType"` // DriveType represents the type of drive like SSD, HDD etc.,
Model string `json:"model"` // Model is model of disk
Compliance string `json:"compliance"` // Implemented standards/specifications version such as SPC-1, SPC-2, etc
Serial string `json:"serial"` // Serial is serial no of disk
Expand Down Expand Up @@ -79,3 +81,8 @@ type Temperature struct {
HighestTemperature int16 `json:"highestTemperature"`
LowestTemperature int16 `json:"lowestTemperature"`
}

type Partition struct {
PartitionType string `json:"partitionType"`
FileSystemType string `json:"fileSystemType"`
}
82 changes: 56 additions & 26 deletions pkg/udev/common.go
Expand Up @@ -32,32 +32,36 @@ import (
)

const (
NDMPrefix = "disk-" // NDMPrefix used as disk's uuid prefix
UDEV_SUBSYSTEM = "block" // udev to filter this device type
UDEV_SYSTEM = "disk" // used to filter devices other than disk which udev tracks (eg. CD ROM)
UDEV_PATH = "DEVPATH" // udev attribute to get device path
UDEV_WWN = "ID_WWN" // udev attribute to get device WWN number
UDEV_SERIAL = "ID_SERIAL_SHORT" // udev attribute to get device serial number
UDEV_SERIAL_FULL = "ID_SERIAL" // udev attribute to get - separated vendor, model, serial
UDEV_BUS = "ID_BUS" // udev attribute to get bus name
UDEV_MODEL = "ID_MODEL" // udev attribute to get device model number
UDEV_VENDOR = "ID_VENDOR" // udev attribute to get device vendor details
UDEV_TYPE = "ID_TYPE" // udev attribute to get device type
UDEV_MAJOR = "MAJOR" // udev attribute to get device major no
UDEV_MINOR = "MINOR" // udev attribute to get device minor no
UDEV_UUID = "UDEV_UUID" // ndm attribute to get device uuid
UDEV_SYSPATH = "UDEV_SYSPATH" // udev attribute to get device syspath
UDEV_ACTION = "UDEV_ACTION" // udev attribute to get monitor device action
UDEV_ACTION_ADD = "add" // udev attribute constant for add action
UDEV_ACTION_REMOVE = "remove" // udev attribute constant for remove action
UDEV_DEVTYPE = "DEVTYPE" // udev attribute to get device device type ie - disk or part
UDEV_SOURCE = "udev" // udev source constant
UDEV_SYSPATH_PREFIX = "/sys/dev/block/" // udev syspath prefix
UDEV_DEVNAME = "DEVNAME" // udev attribute contain disk name given by kernel
UDEV_DEVLINKS = "DEVLINKS" // udev attribute contain devlinks of a disk
BY_ID_LINK = "by-id" // by-path devlink contains this string
BY_PATH_LINK = "by-path" // by-path devlink contains this string
LINK_ID_INDEX = 4 // this is used to get link index from dev link
NDMPrefix = "disk-" // NDMPrefix used as disk's uuid prefix
UDEV_SUBSYSTEM = "block" // udev to filter this device type
UDEV_SYSTEM = "disk" // used to filter devices other than disk which udev tracks (eg. CD ROM)
UDEV_PARTITION = "partition" // used to filter out partitions
UDEV_PATH = "DEVPATH" // udev attribute to get device path
UDEV_WWN = "ID_WWN" // udev attribute to get device WWN number
UDEV_SERIAL = "ID_SERIAL_SHORT" // udev attribute to get device serial number
UDEV_SERIAL_FULL = "ID_SERIAL" // udev attribute to get - separated vendor, model, serial
UDEV_BUS = "ID_BUS" // udev attribute to get bus name
UDEV_MODEL = "ID_MODEL" // udev attribute to get device model number
UDEV_VENDOR = "ID_VENDOR" // udev attribute to get device vendor details
UDEV_TYPE = "ID_TYPE" // udev attribute to get device type
UDEV_MAJOR = "MAJOR" // udev attribute to get device major no
UDEV_MINOR = "MINOR" // udev attribute to get device minor no
UDEV_UUID = "UDEV_UUID" // ndm attribute to get device uuid
UDEV_SYSPATH = "UDEV_SYSPATH" // udev attribute to get device syspath
UDEV_ACTION = "UDEV_ACTION" // udev attribute to get monitor device action
UDEV_ACTION_ADD = "add" // udev attribute constant for add action
UDEV_ACTION_REMOVE = "remove" // udev attribute constant for remove action
UDEV_DEVTYPE = "DEVTYPE" // udev attribute to get device device type ie - disk or part
UDEV_SOURCE = "udev" // udev source constant
UDEV_SYSPATH_PREFIX = "/sys/dev/block/" // udev syspath prefix
UDEV_DEVNAME = "DEVNAME" // udev attribute contain disk name given by kernel
UDEV_DEVLINKS = "DEVLINKS" // udev attribute contain devlinks of a disk
BY_ID_LINK = "by-id" // by-path devlink contains this string
BY_PATH_LINK = "by-path" // by-path devlink contains this string
LINK_ID_INDEX = 4 // this is used to get link index from dev link
UDEV_PARTITION_TYPE = "ID_PART_ENTRY_TYPE" // udev attribute to get partition type
UDEV_FS_TYPE = "ID_FS_TYPE" // file system type the partition
UDEV_FS_NONE = "None" // udev constant for no file system
)

// UdevDiskDetails struct contain different attribute of disk.
Expand All @@ -68,6 +72,7 @@ type UdevDiskDetails struct {
Path string // Path is Path of a disk.
ByIdDevLinks []string // ByIdDevLinks contains by-id devlinks
ByPathDevLinks []string // ByPathDevLinks contains by-path devlinks
FileSystem string // FileSystem on the disk
}

// freeCharPtr frees c pointer
Expand All @@ -78,13 +83,18 @@ func freeCharPtr(s *C.char) {
//DiskInfoFromLibudev returns disk attribute extracted using libudev apicalls.
func (device *UdevDevice) DiskInfoFromLibudev() UdevDiskDetails {
devLinks := device.GetDevLinks()
fileSystem := device.GetPropertyValue(UDEV_FS_TYPE)
if len(fileSystem) == 0 {
fileSystem = UDEV_FS_NONE
}
diskDetails := UdevDiskDetails{
Model: device.GetPropertyValue(UDEV_MODEL),
Serial: device.GetPropertyValue(UDEV_SERIAL),
Vendor: device.GetPropertyValue(UDEV_VENDOR),
Path: device.GetPropertyValue(UDEV_DEVNAME),
ByIdDevLinks: devLinks[BY_ID_LINK],
ByPathDevLinks: devLinks[BY_PATH_LINK],
FileSystem: fileSystem,
}
return diskDetails
}
Expand Down Expand Up @@ -124,6 +134,26 @@ func (device *UdevDevice) IsDisk() bool {
return device.GetDevtype() == UDEV_SYSTEM
}

// IsPartition return true if device is a partition
func (device *UdevDevice) IsParitition() bool {
return device.GetDevtype() == UDEV_PARTITION
}

// GetFileSystemInfo returns filesystem type on disk/partition if it exists.
func (device *UdevDevice) GetFileSystemInfo() string {
fileSystem := device.GetPropertyValue(UDEV_FS_TYPE)
if len(fileSystem) == 0 {
fileSystem = UDEV_FS_NONE
}
return fileSystem
}

// GetPartitionType returns the partition type of the partition, like DOS, lvm2 etc
func (device *UdevDevice) GetPartitionType() string {
partitionType := device.GetPropertyValue(UDEV_PARTITION_TYPE)
return partitionType
}

// GetSyspath returns syspath of a disk using syspath we can fell details
// in diskInfo struct using udev probe
func (device *UdevDevice) GetSyspath() string {
Expand Down
1 change: 1 addition & 0 deletions pkg/udev/common_test.go
Expand Up @@ -83,6 +83,7 @@ func TestDiskInfoFromLibudev(t *testing.T) {
Path: diskDetails.DevNode,
ByIdDevLinks: diskDetails.ByIdDevLinks,
ByPathDevLinks: diskDetails.ByPathDevLinks,
FileSystem: diskDetails.FileSystem,
}
assert.Equal(t, expectedDiskDetails, device.DiskInfoFromLibudev())
tests := map[string]struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/udev/mockdata.go
Expand Up @@ -42,6 +42,7 @@ type MockOsDiskDetails struct {
Vendor string
Wwn string
Uid string
FileSystem string
ByIdDevLinks []string
ByPathDevLinks []string
}
Expand Down Expand Up @@ -81,6 +82,7 @@ func MockDiskDetails() (MockOsDiskDetails, error) {
diskDetails.Vendor = device.GetPropertyValue(UDEV_VENDOR)
diskDetails.Wwn = device.GetPropertyValue(UDEV_WWN)
diskDetails.Uid = device.GetUid()
diskDetails.FileSystem = UDEV_FS_NONE
devLinks := device.GetDevLinks()
diskDetails.ByIdDevLinks = devLinks[BY_ID_LINK]
diskDetails.ByPathDevLinks = devLinks[BY_PATH_LINK]
Expand Down

0 comments on commit f972084

Please sign in to comment.