gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/kmod/spec.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package kmod 21 22 import ( 23 "sort" 24 "strings" 25 26 "gitee.com/mysnapcore/mysnapd/interfaces" 27 "gitee.com/mysnapcore/mysnapd/snap" 28 ) 29 30 // Specification assists in collecting kernel modules associated with an interface. 31 // 32 // Unlike the Backend itself (which is stateless and non-persistent) this type 33 // holds internal state that is used by the kmod backend during the interface 34 // setup process. 35 type Specification struct { 36 modules map[string]bool 37 38 moduleOptions map[string]string 39 disallowedModules map[string]bool 40 } 41 42 // AddModule adds a kernel module, trimming spaces and ignoring duplicated modules. 43 func (spec *Specification) AddModule(module string) error { 44 m := strings.TrimSpace(module) 45 if m == "" { 46 return nil 47 } 48 if spec.modules == nil { 49 spec.modules = make(map[string]bool) 50 } 51 spec.modules[m] = true 52 return nil 53 } 54 55 // Modules returns a copy of the kernel module names added. 56 func (spec *Specification) Modules() map[string]bool { 57 result := make(map[string]bool, len(spec.modules)) 58 for k, v := range spec.modules { 59 result[k] = v 60 } 61 return result 62 } 63 64 // SetModuleOptions specifies which options to use when loading the given kernel module. 65 func (spec *Specification) SetModuleOptions(module, options string) error { 66 if spec.moduleOptions == nil { 67 spec.moduleOptions = make(map[string]string) 68 } 69 spec.moduleOptions[module] = options 70 return nil 71 } 72 73 // moduleOptions returns the load options for each kernel module 74 func (spec *Specification) ModuleOptions() map[string]string { 75 return spec.moduleOptions 76 } 77 78 // DisallowModule adds a kernel module to the list of disallowed modules. 79 func (spec *Specification) DisallowModule(module string) error { 80 m := strings.TrimSpace(module) 81 if m == "" { 82 return nil 83 } 84 if spec.disallowedModules == nil { 85 spec.disallowedModules = make(map[string]bool) 86 } 87 spec.disallowedModules[m] = true 88 return nil 89 } 90 91 // DisallowedModules returns the list of disallowed modules. 92 func (spec *Specification) DisallowedModules() []string { 93 result := make([]string, 0, len(spec.disallowedModules)) 94 for k, v := range spec.disallowedModules { 95 if v { 96 result = append(result, k) 97 } 98 } 99 sort.Strings(result) 100 return result 101 } 102 103 // Implementation of methods required by interfaces.Specification 104 105 // AddConnectedPlug records kmod-specific side-effects of having a connected plug. 106 func (spec *Specification) AddConnectedPlug(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 107 type definer interface { 108 KModConnectedPlug(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 109 } 110 if iface, ok := iface.(definer); ok { 111 return iface.KModConnectedPlug(spec, plug, slot) 112 } 113 return nil 114 } 115 116 // AddConnectedSlot records mount-specific side-effects of having a connected slot. 117 func (spec *Specification) AddConnectedSlot(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 118 type definer interface { 119 KModConnectedSlot(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 120 } 121 if iface, ok := iface.(definer); ok { 122 return iface.KModConnectedSlot(spec, plug, slot) 123 } 124 return nil 125 } 126 127 // AddPermanentPlug records mount-specific side-effects of having a plug. 128 func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error { 129 type definer interface { 130 KModPermanentPlug(spec *Specification, plug *snap.PlugInfo) error 131 } 132 if iface, ok := iface.(definer); ok { 133 return iface.KModPermanentPlug(spec, plug) 134 } 135 return nil 136 } 137 138 // AddPermanentSlot records mount-specific side-effects of having a slot. 139 func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error { 140 type definer interface { 141 KModPermanentSlot(spec *Specification, slot *snap.SlotInfo) error 142 } 143 if iface, ok := iface.(definer); ok { 144 return iface.KModPermanentSlot(spec, slot) 145 } 146 return nil 147 }