github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/cmd/ndm_daemonset/filter/devicevalidityfilter.go (about)

     1  /*
     2  Copyright 2020 The 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  package filter
    18  
    19  import (
    20  	"github.com/openebs/node-disk-manager/blockdevice"
    21  	"github.com/openebs/node-disk-manager/cmd/ndm_daemonset/controller"
    22  	"github.com/openebs/node-disk-manager/pkg/util"
    23  
    24  	"k8s.io/klog/v2"
    25  )
    26  
    27  // NOTE: This is an internal filter used by NDM to validate the block devices.
    28  // Devices having invalid values in various fields(Path, Capacity etc) will be
    29  // filtered out.
    30  //
    31  // The filter cannot be configured or disabled by user.
    32  
    33  var (
    34  	deviceValidityFilterName  = "device validity filter" // filter valid devices
    35  	deviceValidityFilterState = defaultEnabled           // filter state
    36  )
    37  
    38  // deviceValidityFilterRegister contains registration process of DeviceValidityFilter
    39  var deviceValidityFilterRegister = func() {
    40  	ctrl := <-controller.ControllerBroadcastChannel
    41  	if ctrl == nil {
    42  		return
    43  	}
    44  
    45  	var fi controller.FilterInterface = newDeviceValidityFilter(ctrl)
    46  	newRegisterFilter := &registerFilter{
    47  		name:       deviceValidityFilterName,
    48  		state:      deviceValidityFilterState,
    49  		fi:         fi,
    50  		controller: ctrl,
    51  	}
    52  	newRegisterFilter.register()
    53  }
    54  
    55  // deviceValidityFilter contains controller and validator functions
    56  type deviceValidityFilter struct {
    57  	controller             *controller.Controller
    58  	excludeValidationFuncs []validationFunc
    59  }
    60  
    61  // validationFunc is a function type for the validations to be performed on the
    62  // block device
    63  type validationFunc func(*blockdevice.BlockDevice) bool
    64  
    65  // newDeviceValidityFilter returns new pointer to a deviceValidityFilter
    66  func newDeviceValidityFilter(ctrl *controller.Controller) *deviceValidityFilter {
    67  	return &deviceValidityFilter{
    68  		controller: ctrl,
    69  	}
    70  }
    71  
    72  // Start sets the validator functions to be used
    73  func (dvf *deviceValidityFilter) Start() {
    74  	dvf.excludeValidationFuncs = make([]validationFunc, 0)
    75  	dvf.excludeValidationFuncs = append(dvf.excludeValidationFuncs,
    76  		isValidDevPath,
    77  		isValidCapacity,
    78  		isValidDMDevice,
    79  		isValidPartition,
    80  	)
    81  }
    82  
    83  // Include returns true because no specific internal validations are done
    84  // for a device.
    85  func (dvf *deviceValidityFilter) Include(blockDevice *blockdevice.BlockDevice) bool {
    86  	return true
    87  }
    88  
    89  // Exclude returns true if all the exclude validation function passes.
    90  // i.e The given block device is a valid entry.
    91  func (dvf *deviceValidityFilter) Exclude(blockDevice *blockdevice.BlockDevice) bool {
    92  	for _, vf := range dvf.excludeValidationFuncs {
    93  		if !vf(blockDevice) {
    94  			return false
    95  		}
    96  	}
    97  	return true
    98  }
    99  
   100  // isValidDevPath checks if the path is not empty
   101  func isValidDevPath(bd *blockdevice.BlockDevice) bool {
   102  	if len(bd.DevPath) == 0 {
   103  		klog.V(4).Infof("device has an invalid dev path")
   104  		return false
   105  	}
   106  	return true
   107  }
   108  
   109  // isValidCapacity checks if the device has a valid capacity
   110  func isValidCapacity(bd *blockdevice.BlockDevice) bool {
   111  	if bd.Capacity.Storage == 0 {
   112  		klog.V(4).Infof("device: %s has invalid capacity", bd.DevPath)
   113  		return false
   114  	}
   115  	return true
   116  }
   117  
   118  // isValidPartition checks if the blockdevice for the partition has a valid partition UUID
   119  func isValidPartition(bd *blockdevice.BlockDevice) bool {
   120  	if bd.DeviceAttributes.DeviceType == blockdevice.BlockDeviceTypePartition &&
   121  		len(bd.PartitionInfo.PartitionEntryUUID) == 0 {
   122  		klog.V(4).Infof("device: %s of device-type partition has invalid partition UUID", bd.DevPath)
   123  		return false
   124  	}
   125  	return true
   126  }
   127  
   128  // isValidDMDevice checks if the blockdevice is a valid dm device
   129  func isValidDMDevice(bd *blockdevice.BlockDevice) bool {
   130  	if util.Contains(blockdevice.DeviceMapperDeviceTypes, bd.DeviceAttributes.DeviceType) &&
   131  		len(bd.DMInfo.DMUUID) == 0 {
   132  		klog.V(4).Infof("device: %s of device mapper type has invalid DM_UUID", bd.DevPath)
   133  		return false
   134  	}
   135  	return true
   136  }