github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/udev/monitor.go (about) 1 /* 2 Copyright 2018 OpenEBS Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // +build linux,cgo 18 19 package udev 20 21 /* 22 #cgo LDFLAGS: -ludev 23 #include <libudev.h> 24 */ 25 import "C" 26 27 import ( 28 "errors" 29 ) 30 31 // UdevMonitor wraps a libudev monitor device object 32 type UdevMonitor struct { 33 umptr *C.struct_udev_monitor 34 } 35 36 // newUdevMonitor is a helper function and returns a pointer to a new monitor device. 37 // The argument ptr is a pointer to the underlying C udev_device_monitor structure. 38 // The function returns nil if the pointer passed is NULL. 39 func newUdeviceMonitor(ptr *C.struct_udev_monitor) (*UdevMonitor, error) { 40 // If passed a NULL pointer, return nil 41 if ptr == nil { 42 return nil, errors.New("unable to create Udevenumerate object for for null struct struct_udev_monitor") 43 } 44 // Create a new monitor device object 45 um := &UdevMonitor{ 46 umptr: ptr, 47 } 48 // Return the monitor device object 49 return um, nil 50 } 51 52 // AddSubsystemFilter adds subsystem filter in UdevMonitor struct. 53 // This filter is efficiently executed inside kernel, and libudev 54 // subscribers will usually not be woken up for devices which do not match. 55 func (um *UdevMonitor) AddSubsystemFilter(key string) error { 56 subsystem := C.CString(key) 57 defer freeCharPtr(subsystem) 58 ret := C.udev_monitor_filter_add_match_subsystem_devtype(um.umptr, subsystem, nil) 59 if ret < 0 { 60 return errors.New("unable to apply filter") 61 } 62 return nil 63 } 64 65 // EnableReceiving binds udev_monitor socket to event source. 66 func (um *UdevMonitor) EnableReceiving() error { 67 ret := C.udev_monitor_enable_receiving(um.umptr) 68 if ret < 0 { 69 return errors.New("unable to enable receiving udev") 70 } 71 return nil 72 } 73 74 // GetFd retrieves socket file descriptor associated with monitor. 75 func (um *UdevMonitor) GetFd() (int, error) { 76 ret := int(C.udev_monitor_get_fd(um.umptr)) 77 if ret < 0 { 78 return ret, errors.New("unable to get fd from monitor") 79 } 80 return ret, nil 81 } 82 83 // ReceiveDevice receives data from udev monitor socket, allocate a 84 // new udev device, fill in received data, and return Udevice struct. 85 func (um *UdevMonitor) ReceiveDevice() (*UdevDevice, error) { 86 return newUdevDevice(C.udev_monitor_receive_device(um.umptr)) 87 } 88 89 // UdevMonitorUnref frees udev monitor structure. 90 func (um *UdevMonitor) UdevMonitorUnref() { 91 C.udev_monitor_unref(um.umptr) 92 }