Skip to content

Commit

Permalink
lxd/instance/drivers/driver_lxc: add support for linux.kernel_modules…
Browse files Browse the repository at this point in the history
….load

See also:
https://discourse.ubuntu.com/t/lxd-container-instance-lazy-modules-loading/42837

Includes documentation changes kindly written by:
Ruth Fuchss <[email protected]>

Signed-off-by: Alexander Mikhalitsyn <[email protected]>
  • Loading branch information
mihalicyn committed Mar 22, 2024
1 parent c1484f0 commit 83098ac
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
7 changes: 6 additions & 1 deletion lxd/instance/drivers/driver_lxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,8 @@ func (d *lxc) startCommon() (string, []func() error, error) {

// Load any required kernel modules
kernelModules := d.expandedConfig["linux.kernel_modules"]
if kernelModules != "" {
kernelModulesLoadPolicy := d.expandedConfig["linux.kernel_modules.load"]
if kernelModulesLoadPolicy != "dynamic" && kernelModules != "" {
for _, module := range strings.Split(kernelModules, ",") {
module = strings.TrimPrefix(module, " ")
err := util.LoadModule(module)
Expand Down Expand Up @@ -4450,6 +4451,10 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
}
}
} else if key == "linux.kernel_modules" && value != "" {
if d.expandedConfig["linux.kernel_modules.load"] == "dynamic" {
continue
}

for _, module := range strings.Split(value, ",") {
module = strings.TrimPrefix(module, " ")
err := util.LoadModule(module)
Expand Down
15 changes: 14 additions & 1 deletion lxd/instance/instancetype/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,13 +559,26 @@ var InstanceConfigKeysContainer = map[string]func(value string) error{

// lxdmeta:generate(entities=instance; group=miscellaneous; key=linux.kernel_modules)
// Specify the kernel modules as a comma-separated list.
//
// The modules are loaded before the instance starts, or they can be loaded by a privileged user if {config:option}`instance-miscellaneous:linux.kernel_modules.load` is set to `dynamic`.
// ---
// type: string
// liveupdate: yes
// condition: container
// shortdesc: Kernel modules to load before starting the instance
// shortdesc: Kernel modules to load or allow loading
"linux.kernel_modules": validate.IsAny,

// lxdmeta:generate(entities=instance; group=miscellaneous; key=linux.kernel_modules.load)
// This option specifies how to load the kernel modules that are specified in {config:option}`instance-miscellaneous:linux.kernel_modules`.
// Possible values are `boot` (load the modules when booting the container) and `dynamic` (intercept the `finit_modules()` syscall and allow a privileged user in the container's user namespace to load the modules).
// ---
// type: string
// defaultdesc: `boot`
// liveupdate: no
// condition: container
// shortdesc: How to load kernel modules
"linux.kernel_modules.load": validate.Optional(validate.IsOneOf("boot", "dynamic")),

// lxdmeta:generate(entities=instance; group=migration; key=migration.incremental.memory)
// Using incremental memory transfer of the instance's memory can reduce downtime.
// ---
Expand Down
1 change: 1 addition & 0 deletions lxd/project/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ func isContainerLowLevelOptionForbidden(key string) bool {
if shared.ValueInSlice(key, []string{
"boot.host_shutdown_timeout",
"linux.kernel_modules",
"linux.kernel_modules.load",
"raw.apparmor",
"raw.idmap",
"raw.lxc",
Expand Down
13 changes: 13 additions & 0 deletions lxd/seccomp/seccomp.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,15 @@ func InstanceNeedsIntercept(s *state.State, c Instance) (bool, error) {
needed = true
}

if config["linux.kernel_modules.load"] == "dynamic" {
err := lxcSupportSeccompNotifyContinue(s)
if err != nil {
return needed, err
}

needed = true
}

return needed, nil
}

Expand Down Expand Up @@ -814,6 +823,10 @@ func seccompGetPolicyContent(s *state.State, c Instance) (string, error) {
policy += seccompNotifySysinfo
}

if config["linux.kernel_modules.load"] == "dynamic" {
policy += seccompNotifyModule
}

if shared.IsTrue(config["security.syscalls.intercept.mount"]) {
policy += seccompNotifyMount
// We block the new mount api for now to simplify mount
Expand Down

0 comments on commit 83098ac

Please sign in to comment.