github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/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 "strings" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/snap" 27 ) 28 29 // Specification assists in collecting kernel modules associated with an interface. 30 // 31 // Unlike the Backend itself (which is stateless and non-persistent) this type 32 // holds internal state that is used by the kmod backend during the interface 33 // setup process. 34 type Specification struct { 35 modules map[string]bool 36 } 37 38 // AddModule adds a kernel module, trimming spaces and ignoring duplicated modules. 39 func (spec *Specification) AddModule(module string) error { 40 m := strings.TrimSpace(module) 41 if m == "" { 42 return nil 43 } 44 if spec.modules == nil { 45 spec.modules = make(map[string]bool) 46 } 47 spec.modules[m] = true 48 return nil 49 } 50 51 // Modules returns a copy of the kernel module names added. 52 func (spec *Specification) Modules() map[string]bool { 53 result := make(map[string]bool, len(spec.modules)) 54 for k, v := range spec.modules { 55 result[k] = v 56 } 57 return result 58 } 59 60 // Implementation of methods required by interfaces.Specification 61 62 // AddConnectedPlug records kmod-specific side-effects of having a connected plug. 63 func (spec *Specification) AddConnectedPlug(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 64 type definer interface { 65 KModConnectedPlug(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 66 } 67 if iface, ok := iface.(definer); ok { 68 return iface.KModConnectedPlug(spec, plug, slot) 69 } 70 return nil 71 } 72 73 // AddConnectedSlot records mount-specific side-effects of having a connected slot. 74 func (spec *Specification) AddConnectedSlot(iface interfaces.Interface, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 75 type definer interface { 76 KModConnectedSlot(spec *Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error 77 } 78 if iface, ok := iface.(definer); ok { 79 return iface.KModConnectedSlot(spec, plug, slot) 80 } 81 return nil 82 } 83 84 // AddPermanentPlug records mount-specific side-effects of having a plug. 85 func (spec *Specification) AddPermanentPlug(iface interfaces.Interface, plug *snap.PlugInfo) error { 86 type definer interface { 87 KModPermanentPlug(spec *Specification, plug *snap.PlugInfo) error 88 } 89 if iface, ok := iface.(definer); ok { 90 return iface.KModPermanentPlug(spec, plug) 91 } 92 return nil 93 } 94 95 // AddPermanentSlot records mount-specific side-effects of having a slot. 96 func (spec *Specification) AddPermanentSlot(iface interfaces.Interface, slot *snap.SlotInfo) error { 97 type definer interface { 98 KModPermanentSlot(spec *Specification, slot *snap.SlotInfo) error 99 } 100 if iface, ok := iface.(definer); ok { 101 return iface.KModPermanentSlot(spec, slot) 102 } 103 return nil 104 }