Skip to content

Commit

Permalink
refactor(pkg, udevevent): decouple udevevent from controller (#609)
Browse files Browse the repository at this point in the history
As per conventions, packages in the pkg directory should be independent
of the overlying applications that use them. The `udevevent` package has
tight coupling with the `controller` and `probe` packages from
ndm_daemonset.

Refactor to make `udevevent` standalone. This includes
moving all application (ndm_daemonset in this case) specific code in
`udevevent` to appropriate cmd packages and providing an API for the
application code to use the functionalities of `udevevent`.

- remove logging from package
- reuse action constants from pkg udev
- add inline comments

Signed-off-by: Aditya Jain <aditya.jainadityajain.jain@gmail.com>
  • Loading branch information
z0marlin authored Aug 5, 2021
1 parent 225bbfd commit 37af3c2
Show file tree
Hide file tree
Showing 8 changed files with 326 additions and 243 deletions.
6 changes: 4 additions & 2 deletions cmd/ndm_daemonset/controller/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package controller
import (
"sort"

"k8s.io/klog"

"github.com/openebs/node-disk-manager/blockdevice"
"github.com/openebs/node-disk-manager/pkg/util"

"k8s.io/klog"
)

// EventMessage struct contains attribute of event message info.
Expand All @@ -33,6 +33,8 @@ type EventMessage struct {
AllBlockDevices bool // If true, ignore Devices list and iterate through all block devices present in the hierarchy cache.
}

var EventMessageChannel = make(chan EventMessage)

// Probe contains name, state and probeinterface
type Probe struct {
Priority int
Expand Down
3 changes: 1 addition & 2 deletions cmd/ndm_daemonset/probe/mountprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/openebs/node-disk-manager/pkg/features"
"github.com/openebs/node-disk-manager/pkg/mount"
"github.com/openebs/node-disk-manager/pkg/mount/libmount"
"github.com/openebs/node-disk-manager/pkg/udevevent"
"github.com/openebs/node-disk-manager/pkg/util"
)

Expand Down Expand Up @@ -86,7 +85,7 @@ func newMountProbeForRegistration(c *controller.Controller) *mountProbe {
return &mountProbe{
Controller: c,
mountsFileName: mount.HostMountsFilePath,
destination: udevevent.UdevEventMessageChannel,
destination: controller.EventMessageChannel,
}
}

Expand Down
100 changes: 93 additions & 7 deletions cmd/ndm_daemonset/probe/udevprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ var udevProbeRegister = func() {
// udevProbe contains require variables for scan , populate diskInfo and push
// resource in etcd
type udevProbe struct {
controller *controller.Controller
udev *libudevwrapper.Udev
udevDevice *libudevwrapper.UdevDevice
udevEnumerate *libudevwrapper.UdevEnumerate
controller *controller.Controller
udev *libudevwrapper.Udev
udevDevice *libudevwrapper.UdevDevice
udevEnumerate *libudevwrapper.UdevEnumerate
udeveventSubscription *udevevent.Subscription
}

// newUdevProbe returns udevProbe struct which helps to setup probe listen and scan
Expand Down Expand Up @@ -118,7 +119,10 @@ func newUdevProbeForFillDiskDetails(sysPath string) (*udevProbe, error) {
// Start setup udev probe listener and make a single scan of system
func (up *udevProbe) Start() {
go up.listen()
go udevevent.Monitor()
up.udeveventSubscription = udevevent.Subscribe(udevevent.EventTypeAdd,
udevevent.EventTypeRemove)
errChan := udevevent.Monitor()
go up.listenUdevEventMonitor(errChan)
probeEvent := newUdevProbe(up.controller)
err := probeEvent.scan()
if err != nil {
Expand Down Expand Up @@ -253,7 +257,7 @@ func (up *udevProbe) scan() error {
Action: libudevwrapper.UDEV_ACTION_ADD,
Devices: diskInfo,
}
udevevent.UdevEventMessageChannel <- eventDetails
controller.EventMessageChannel <- eventDetails
return nil
}

Expand Down Expand Up @@ -336,7 +340,7 @@ func (up *udevProbe) listen() {
}
klog.Info("starting udev probe listener")
for {
msg := <-udevevent.UdevEventMessageChannel
msg := <-controller.EventMessageChannel
switch msg.Action {
case string(AttachEA):
probeEvent.addBlockDeviceEvent(msg)
Expand All @@ -360,3 +364,85 @@ func (up *udevProbe) free() {
up.udevEnumerate.UnrefUdevEnumerate()
}
}

func (up *udevProbe) listenUdevEventMonitor(errChan <-chan error) {
eventChan := up.udeveventSubscription.Events()
for {
select {
case event := <-eventChan:
controller.EventMessageChannel <- processUdevEvent(event)
case err := <-errChan:
klog.Error(err)
}
}
}

func processUdevEvent(event udevevent.UdevEvent) controller.EventMessage {
defer event.UdevDeviceUnref()
diskInfo := make([]*blockdevice.BlockDevice, 0)
uuid := event.GetUid()
path := event.GetPath()
action := event.GetAction()
klog.Infof("processing new event for (%s) action type %s", path, action)
deviceDetails := &blockdevice.BlockDevice{}
// This is the legacy uuid. It will be overwritten in the event handler.
deviceDetails.UUID = uuid
deviceDetails.SysPath = event.GetSyspath()
deviceDetails.DevPath = path

// fields used for UUID. These fields will be filled always. But used only if the
// GPTBasedUUID feature-gate is enabled.
deviceDetails.DeviceAttributes.DeviceType = event.GetPropertyValue(libudevwrapper.UDEV_DEVTYPE)
deviceDetails.DeviceAttributes.WWN = event.GetPropertyValue(libudevwrapper.UDEV_WWN)
deviceDetails.DeviceAttributes.Serial = event.GetPropertyValue(libudevwrapper.UDEV_SERIAL)

// The below 3 fields are used only for legacy uuid generation. But they are filled in here,
// so as to handle upgrade cases from legacy to gpt
deviceDetails.DeviceAttributes.Model = event.GetPropertyValue(libudevwrapper.UDEV_MODEL)
deviceDetails.DeviceAttributes.Vendor = event.GetPropertyValue(libudevwrapper.UDEV_VENDOR)
deviceDetails.DeviceAttributes.IDType = event.GetPropertyValue(libudevwrapper.UDEV_TYPE)

deviceDetails.PartitionInfo.PartitionTableUUID = event.GetPropertyValue(libudevwrapper.UDEV_PARTITION_TABLE_UUID)
deviceDetails.PartitionInfo.PartitionEntryUUID = event.GetPropertyValue(libudevwrapper.UDEV_PARTITION_UUID)
deviceDetails.FSInfo.FileSystemUUID = event.GetPropertyValue(libudevwrapper.UDEV_FS_UUID)

deviceDetails.DMInfo.DMUUID = event.GetPropertyValue(libudevwrapper.UDEV_DM_UUID)

// fields used for dependents. dependents cannot be obtained while
// removing the device since sysfs entry will be absent
if action != udevevent.EventTypeRemove {
sysfsDevice, err := sysfs.NewSysFsDeviceFromDevPath(deviceDetails.DevPath)
if err != nil {
klog.Errorf("could not get sysfs device for %s, err: %v", deviceDetails.DevPath, err)
} else {
dependents, err := sysfsDevice.GetDependents()
// TODO if error occurs need to do a scan from the beginning
if err != nil {
klog.Errorf("could not get dependents for %s, %v", deviceDetails.DevPath, err)
} else {
deviceDetails.DependentDevices = dependents
klog.V(4).Infof("Dependents of %s : %+v", deviceDetails.DevPath, dependents)
}
udevDeviceType := deviceDetails.DeviceAttributes.DeviceType
deviceType, err := sysfsDevice.GetDeviceType(udevDeviceType)
if err != nil {
klog.Errorf("could not get device type for %s, falling back to udev reported type: %s", deviceDetails.DevPath, udevDeviceType)
deviceType = udevDeviceType
}
deviceDetails.DeviceAttributes.DeviceType = deviceType
klog.Infof("Device: %s is of type: %s", deviceDetails.DevPath, deviceDetails.DeviceAttributes.DeviceType)
}
}

diskInfo = append(diskInfo, deviceDetails)
eventMessage := controller.EventMessage{}
switch action {
case udevevent.EventTypeAdd:
eventMessage.Action = string(AttachEA)
case udevevent.EventTypeRemove:
eventMessage.Action = string(DetachEA)
}
eventMessage.Devices = diskInfo

return eventMessage
}
1 change: 1 addition & 0 deletions pkg/udev/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const (
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_ACTION_CHANGE = "change" // udev attribute constant for change 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
Expand Down
105 changes: 0 additions & 105 deletions pkg/udevevent/event.go

This file was deleted.

108 changes: 0 additions & 108 deletions pkg/udevevent/event_test.go

This file was deleted.

Loading

0 comments on commit 37af3c2

Please sign in to comment.