Skip to content

many: make kernel-modules components available on initramfs installation#14810

Merged
alfonsosanchezbeato merged 15 commits intocanonical:masterfrom
alfonsosanchezbeato:include-kern-mod-comps-on-initramfs-install
Jan 28, 2025
Merged

many: make kernel-modules components available on initramfs installation#14810
alfonsosanchezbeato merged 15 commits intocanonical:masterfrom
alfonsosanchezbeato:include-kern-mod-comps-on-initramfs-install

Conversation

@alfonsosanchezbeato
Copy link
Member

@alfonsosanchezbeato alfonsosanchezbeato commented Dec 5, 2024

Make sure that modules shipped in kernel-modules components are available on early boot when the system is installed from the initramfs. This is a follow-up from #14744.

This requires some changes in core-initrd and in snapd-generator, so I am opening as draft for the moment. In fact the pre-requisites are needed for having a working drivers tree at all on first boot after initramfs driven installation.

Depends on

@codecov
Copy link

codecov bot commented Dec 5, 2024

Codecov Report

Attention: Patch coverage is 65.80311% with 66 lines in your changes missing coverage. Please review.

Please upload report for BASE (master@953a5d8). Learn more about missing BASE report.
Report is 37 commits behind head on master.

Files with missing lines Patch % Lines
cmd/snap-bootstrap/cmd_initramfs_mounts.go 66.32% 22 Missing and 11 partials ⚠️
overlord/install/install.go 0.00% 31 Missing ⚠️
overlord/devicestate/handlers_install.go 95.00% 0 Missing and 1 partial ⚠️
overlord/snapstate/snapstate.go 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             master   #14810   +/-   ##
=========================================
  Coverage          ?   78.24%           
=========================================
  Files             ?     1159           
  Lines             ?   153925           
  Branches          ?        0           
=========================================
  Hits              ?   120443           
  Misses            ?    26068           
  Partials          ?     7414           
Flag Coverage Δ
unittests 78.24% <65.80%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alfonsosanchezbeato alfonsosanchezbeato added the Run nested The PR also runs tests inluded in nested suite label Dec 5, 2024
@alfonsosanchezbeato alfonsosanchezbeato force-pushed the include-kern-mod-comps-on-initramfs-install branch from 2b388eb to 66cc66b Compare January 15, 2025 20:51
@github-actions
Copy link

github-actions bot commented Jan 15, 2025

Tue Jan 28 13:39:30 UTC 2025
The following results are from: https://github.com/canonical/snapd/actions/runs/13000525487

Failures:

Preparing:

  • openstack:debian-12-64:tests/completion/

Executing:

  • google-nested:ubuntu-24.04-64:tests/nested/manual/kernel-modules-components:encrypted
  • google-nested:ubuntu-24.04-64:tests/nested/manual/remodel-min-size
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-pre-download:restart
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-pre-download:ignore
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-pre-download:close_mid_restart
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh:regular
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh:parallel
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-gating
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-pre-download:close
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-backoff
  • openstack:opensuse-tumbleweed-64:tests/main/snap-refresh-hold
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-gating-from-snap
  • openstack:opensuse-tumbleweed-64:tests/main/auto-refresh-retry
  • openstack:opensuse-tumbleweed-64:tests/main/refresh-app-awareness-notify

Restoring:

  • openstack:debian-12-64:tests/completion/
  • openstack:debian-12-64:tests/main/refresh:strict_fake
  • openstack:debian-12-64:tests/main/
  • openstack:opensuse-tumbleweed-64:tests/main/refresh-app-awareness-notify

@alfonsosanchezbeato alfonsosanchezbeato force-pushed the include-kern-mod-comps-on-initramfs-install branch 2 times, most recently from 6bcd667 to 652d0f3 Compare January 17, 2025 17:24
@alfonsosanchezbeato alfonsosanchezbeato marked this pull request as ready for review January 17, 2025 17:24
@alfonsosanchezbeato
Copy link
Member Author

This is ready for review now, the core24 dependency is merged and the others are unnecessary as what they did is done now by snap-bootstrap.

@alfonsosanchezbeato alfonsosanchezbeato force-pushed the include-kern-mod-comps-on-initramfs-install branch from 652d0f3 to 77f8567 Compare January 17, 2025 18:40
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple of code org question/comments

Copy link
Member Author

@alfonsosanchezbeato alfonsosanchezbeato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pedronis thanks, comments addressed now

Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, one small thing

)

// BuildKernelBootInfo constructs a KernelBootInfo.
func BuildKernelBootInfo(kernInfo *snap.Info, compSeedInfos []CompSeedInfo, kernMntPoint string, mntPtForComps map[string]string, isCore, needsDriversTree bool) KernelBootInfo {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: should the two bools become an Options struct ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm +1 on that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Copy link
Member

@Meulengracht Meulengracht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall nice, some comments

if err != nil {
return nil, err
}
if ci.Revision.Unset() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what cases are the revision unset? And why does it need to be set to x1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When reading from the seed, if the component is unasserted. Note that this is the same that was being done for snaps in readSnapInfo. I've added comments to clarify.

continue
}

// Mount ephemerally the kernel-modules components
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment explains what we are doing here, which is farily obvious from the code, maybe a comment about why they are mounted ephemerally would make more sense

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, added more information

}

installedSystem, err := gadgetInstallRun(model, gadgetMountDir, kernelSnapInfo, bootDevice, options, installObserver, timings.New(nil))
preseed := false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this should be defined before preseedSeed, ok := currentSeed.(seed.PreseedCapable) instead, it doesn't need to be defined here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved

}

currentSeed, err := mst.LoadSeed(mst.recoverySystem)
if preseed {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment about why different behavior is required for this case would be nice

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

}
}

// Create drivers tree mount units
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not very helpful either - i think a comment about the expected behaviour in this case and how it's consumed would be much more helpful

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tweaked a bit

return nil
}

// NeedsKernelDriversTree tells if we need a kernel drivers tree for this model.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// NeedsKernelDriversTree tells if we need a kernel drivers tree for this model.
// NeedsKernelDriversTree returns true if we need a kernel drivers tree for this model.

ReadOnly: true,
Private: true,
Ephemeral: true}); err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a test in this error case to ensure the unmounts are called correctly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test now


// CompSeedInfo contains information for a component from the seed and
// from its metadata.
type CompSeedInfo struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nitpick but for me, when it comes to exported structures that are part of an API it feels more appropriate to spell it out ComponentSeedInfo instead of shorting it, which is what you might do for the variable name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Comment on lines 88 to 89
CompInfo *snap.ComponentInfo
CompSeed *seed.Component
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would read even nicer when used? Anyway, nitpicks here, feel free to ignore

Suggested change
CompInfo *snap.ComponentInfo
CompSeed *seed.Component
Info *snap.ComponentInfo
Seed *seed.Component

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

)

// BuildKernelBootInfo constructs a KernelBootInfo.
func BuildKernelBootInfo(kernInfo *snap.Info, compSeedInfos []CompSeedInfo, kernMntPoint string, mntPtForComps map[string]string, isCore, needsDriversTree bool) KernelBootInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm +1 on that

Copy link
Member Author

@alfonsosanchezbeato alfonsosanchezbeato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Meulengracht thanks, I've addressed your comments now

if err != nil {
return nil, err
}
if ci.Revision.Unset() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When reading from the seed, if the component is unasserted. Note that this is the same that was being done for snaps in readSnapInfo. I've added comments to clarify.

continue
}

// Mount ephemerally the kernel-modules components
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, added more information

ReadOnly: true,
Private: true,
Ephemeral: true}); err != nil {
return err
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test now

}

installedSystem, err := gadgetInstallRun(model, gadgetMountDir, kernelSnapInfo, bootDevice, options, installObserver, timings.New(nil))
preseed := false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved

}

currentSeed, err := mst.LoadSeed(mst.recoverySystem)
if preseed {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

}
}

// Create drivers tree mount units
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tweaked a bit


// CompSeedInfo contains information for a component from the seed and
// from its metadata.
type CompSeedInfo struct {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Comment on lines 88 to 89
CompInfo *snap.ComponentInfo
CompSeed *seed.Component
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

)

// BuildKernelBootInfo constructs a KernelBootInfo.
func BuildKernelBootInfo(kernInfo *snap.Info, compSeedInfos []CompSeedInfo, kernMntPoint string, mntPtForComps map[string]string, isCore, needsDriversTree bool) KernelBootInfo {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

@alfonsosanchezbeato alfonsosanchezbeato force-pushed the include-kern-mod-comps-on-initramfs-install branch from b24de36 to 73ccbf2 Compare January 24, 2025 15:46
Introduce NESTED_COMP_KERNEL_MODULE_NAME and
NESTED_KERNEL_MODULES_COMP env vars. If present, a kernel-modules
component containing the specified kernel module will be created and
will be added when building the nested test image.
Create the drivers tree mounts when installing UC from the initramfs.
Run the prepare-kernel-modules-components task when creating the
pre-seed tarball. This was not happening as pre-seeding stops the run
of snap install tasks right before running hooks, and this task is run
after them. To workaround this, add a
prepare-kernel-modules-components task that runs before hooks, only
for preseeding.
It will be part of the preseed tarball.
@alfonsosanchezbeato alfonsosanchezbeato force-pushed the include-kern-mod-comps-on-initramfs-install branch from 73ccbf2 to ac13f3c Compare January 24, 2025 20:06
@alfonsosanchezbeato alfonsosanchezbeato merged commit b803966 into canonical:master Jan 28, 2025
64 of 67 checks passed
kubiko added a commit to kubiko/snapd that referenced this pull request Feb 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Run nested The PR also runs tests inluded in nested suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants