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  }