@@ -54,6 +54,7 @@ import (
5454 "github.com/snapcore/snapd/secboot"
5555 "github.com/snapcore/snapd/seed"
5656 "github.com/snapcore/snapd/snap"
57+ "github.com/snapcore/snapd/snap/snapdir"
5758 "github.com/snapcore/snapd/snap/squashfs"
5859 "github.com/snapcore/snapd/sysconfig"
5960 "github.com/snapcore/snapd/timings"
@@ -262,6 +263,18 @@ func readSnapInfo(sysSnaps map[snap.Type]*seed.Snap, snapType snap.Type) (*snap.
262263
263264}
264265
266+ func readComponentInfo (seedComp * seed.Component , mntPt string , snapInfo * snap.Info , csi * snap.ComponentSideInfo ) (* snap.ComponentInfo , error ) {
267+ container := snapdir .New (mntPt )
268+ ci , err := snap .ReadComponentInfoFromContainer (container , snapInfo , csi )
269+ if err != nil {
270+ return nil , err
271+ }
272+ if ci .Revision .Unset () {
273+ ci .Revision = snap .R (- 1 )
274+ }
275+ return ci , nil
276+ }
277+
265278func runFDESetupHook (req * fde.SetupRequest ) ([]byte , error ) {
266279 // TODO: use systemd-run
267280 encoded , err := json .Marshal (req )
@@ -328,25 +341,54 @@ func doInstall(mst *initramfsMountsState, model *asserts.Model, sysSnaps map[sna
328341 return fmt .Errorf ("cannot use gadget: %v" , err )
329342 }
330343
331- // TODO:COMPS take into account kernel-modules components, see
332- // DeviceManager,doSetupRunSystem and other parts of
333- // handlers_install.go.
344+ // Get kernel-modules information to have them ready early on first boot
334345
335- bootDevice := ""
336- kernelSnapInfo := & gadgetInstall.KernelSnapInfo {
337- Name : kernelSnap .SnapName (),
338- MountPoint : kernelMountDir ,
339- Revision : kernelSnap .Revision ,
340- // Should be true always anyway
341- IsCore : ! model .Classic (),
342- }
343- switch model .Base () {
344- case "core20" , "core22" , "core22-desktop" :
345- kernelSnapInfo .NeedsDriversTree = false
346- default :
347- kernelSnapInfo .NeedsDriversTree = true
346+ kernCompsByName := make (map [string ]* snap.Component )
347+ for _ , c := range kernelSnap .Components {
348+ kernCompsByName [c .Name ] = c
348349 }
349350
351+ kernelSeed := sysSnaps [snap .TypeKernel ]
352+ kernCompsMntPts := make (map [string ]string )
353+ compSeedInfos := []gadgetInstall.CompSeedInfo {}
354+ for _ , sc := range kernelSeed .Components {
355+ seedComp := sc
356+ comp , ok := kernCompsByName [seedComp .CompSideInfo .Component .ComponentName ]
357+ if ! ok {
358+ return fmt .Errorf ("component %s in seed but not defined by snap!" ,
359+ seedComp .CompSideInfo .Component .ComponentName )
360+ }
361+ if comp .Type != snap .KernelModulesComponent {
362+ continue
363+ }
364+
365+ // Mount ephemerally the kernel-modules components
366+ mntPt := filepath .Join (filepath .Join (boot .InitramfsRunMntDir , "snap-content" ,
367+ seedComp .CompSideInfo .Component .String ()))
368+ if err := doSystemdMount (seedComp .Path , mntPt , & systemdMountOptions {
369+ ReadOnly : true ,
370+ Private : true ,
371+ Ephemeral : true }); err != nil {
372+ return err
373+ }
374+ kernCompsMntPts [seedComp .CompSideInfo .Component .String ()] = mntPt
375+
376+ compInfo , err := readComponentInfo (& seedComp , mntPt , kernelSnap , & seedComp .CompSideInfo )
377+ if err != nil {
378+ return err
379+ }
380+ compSeedInfos = append (compSeedInfos , gadgetInstall.CompSeedInfo {
381+ CompInfo : compInfo ,
382+ CompSeed : & seedComp ,
383+ })
384+ }
385+
386+ isCore := ! model .Classic ()
387+ kernelSnapInfo , bootKMods := gadgetInstall .KernelBootInfo (
388+ kernelSnap , compSeedInfos , kernelMountDir , kernCompsMntPts ,
389+ isCore , model .NeedsKernelSetup ())
390+
391+ bootDevice := ""
350392 installedSystem , err := gadgetInstallRun (model , gadgetMountDir , kernelSnapInfo , bootDevice , options , installObserver , timings .New (nil ))
351393 if err != nil {
352394 return err
@@ -379,6 +421,7 @@ func doInstall(mst *initramfsMountsState, model *asserts.Model, sysSnaps map[sna
379421 KernelPath : sysSnaps [snap .TypeKernel ].Path ,
380422 UnpackedGadgetDir : gadgetMountDir ,
381423 RecoverySystemLabel : mst .recoverySystem ,
424+ KernelMods : bootKMods ,
382425 }
383426
384427 if err := bootMakeRunnableStandaloneSystem (model , bootWith , trustedInstallObserver ); err != nil {
@@ -429,6 +472,25 @@ func generateMountsModeInstall(mst *initramfsMountsState) error {
429472 }
430473
431474 if installAndRun {
475+ kernSnap := snaps [snap .TypeKernel ]
476+ // seed is cached at this point
477+ theSeed , err := mst .LoadSeed ("" )
478+ if err != nil {
479+ return fmt .Errorf ("internal error: cannot load seed: %v" , err )
480+ }
481+ // Filter by mode, this is relevant only to get the
482+ // kernel-modules components that are used in run mode and
483+ // therefore need to be considered when installing from the
484+ // initramfs to have the modules available early on first boot.
485+ // TODO when running normal install or recover/factory-reset,
486+ // we would need also this if we want the modules to be
487+ // available early.
488+ kernSnap , err = theSeed .ModeSnap (kernSnap .SnapName (), "run" )
489+ if err != nil {
490+ return err
491+ }
492+ snaps [snap .TypeKernel ] = kernSnap
493+
432494 if err := doInstall (mst , model , snaps ); err != nil {
433495 return err
434496 }
0 commit comments