github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/cmd/ndm_daemonset/filter/pathfilter.go (about) 1 /* 2 Copyright 2018 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 libudevwrapper "github.com/openebs/node-disk-manager/pkg/udev" 22 23 "strings" 24 25 "github.com/openebs/node-disk-manager/cmd/ndm_daemonset/controller" 26 "github.com/openebs/node-disk-manager/pkg/util" 27 ) 28 29 const ( 30 pathFilterKey = "path-filter" 31 ) 32 33 var ( 34 pathFilterName = "path filter" // filter device paths 35 pathFilterState = defaultEnabled // filter state 36 includePaths = "" 37 excludePaths = "loop" 38 ) 39 40 // pathFilterRegister contains registration process of PathFilter 41 var pathFilterRegister = func() { 42 ctrl := <-controller.ControllerBroadcastChannel 43 if ctrl == nil { 44 return 45 } 46 if ctrl.NDMConfig != nil { 47 for _, filterConfig := range ctrl.NDMConfig.FilterConfigs { 48 if filterConfig.Key == pathFilterKey { 49 pathFilterName = filterConfig.Name 50 pathFilterState = util.CheckTruthy(filterConfig.State) 51 includePaths = filterConfig.Include 52 excludePaths = filterConfig.Exclude 53 break 54 } 55 } 56 } 57 var fi controller.FilterInterface = newPathFilter(ctrl) 58 newRegisterFilter := ®isterFilter{ 59 name: pathFilterName, 60 state: pathFilterState, 61 fi: fi, 62 controller: ctrl, 63 } 64 newRegisterFilter.register() 65 } 66 67 // pathFilter contains controller and include and exclude keywords 68 type pathFilter struct { 69 controller *controller.Controller 70 excludePaths []string 71 includePaths []string 72 } 73 74 // newPathFilter returns new pointer PathFilter 75 func newPathFilter(ctrl *controller.Controller) *pathFilter { 76 return &pathFilter{ 77 controller: ctrl, 78 } 79 } 80 81 // Start sets include and exclude path keywords list 82 func (pf *pathFilter) Start() { 83 pf.includePaths = make([]string, 0) 84 pf.excludePaths = make([]string, 0) 85 if includePaths != "" { 86 pf.includePaths = strings.Split(includePaths, ",") 87 } 88 if excludePaths != "" { 89 pf.excludePaths = strings.Split(excludePaths, ",") 90 } 91 } 92 93 // Include returns true if the disk path matches with given list 94 // of keywords 95 func (pf *pathFilter) Include(blockDevice *blockdevice.BlockDevice) bool { 96 if len(pf.includePaths) == 0 { 97 return true 98 } 99 if util.Contains(blockdevice.DeviceMapperDeviceTypes, 100 blockDevice.DeviceAttributes.DeviceType) { 101 if util.MatchIgnoredCase(pf.includePaths, blockDevice.DMInfo.DevMapperPath) { 102 return true 103 } 104 } 105 if util.MatchIgnoredCase(pf.includePaths, blockDevice.DevPath) { 106 return true 107 } 108 for _, link := range blockDevice.DevLinks { 109 if link.Kind == libudevwrapper.SYMLINK { 110 for _, symlink := range link.Links { 111 if util.Contains(pf.includePaths, symlink) { 112 return true 113 } 114 } 115 } 116 } 117 return false 118 } 119 120 // Exclude returns true if the disk path does not match any given 121 // keywords 122 func (pf *pathFilter) Exclude(blockDevice *blockdevice.BlockDevice) bool { 123 if len(pf.excludePaths) == 0 { 124 return true 125 } 126 // for DM devices, need to check both the devpath and device mapper path 127 if util.Contains(blockdevice.DeviceMapperDeviceTypes, 128 blockDevice.DeviceAttributes.DeviceType) { 129 if util.MatchIgnoredCase(pf.excludePaths, blockDevice.DMInfo.DevMapperPath) { 130 return false 131 } 132 } 133 if util.MatchIgnoredCase(pf.excludePaths, blockDevice.DevPath) { 134 return false 135 } 136 for _, link := range blockDevice.DevLinks { 137 if link.Kind == libudevwrapper.SYMLINK { 138 for _, symlink := range link.Links { 139 if util.Contains(pf.excludePaths, symlink) { 140 return false 141 } 142 } 143 } 144 } 145 return true 146 }