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  }