Skip to content

Commit

Permalink
refactor: replace the old v1 mount package with new one
Browse files Browse the repository at this point in the history
Re-design some methods, simplify flows and allow more simple
interactions.

Learn from mistakes and design better methods.

Fixes siderolabs#9471

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Oct 30, 2024
1 parent 0ece13c commit 62ec7ec
Show file tree
Hide file tree
Showing 23 changed files with 407 additions and 1,222 deletions.
62 changes: 30 additions & 32 deletions internal/app/init/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@ import (
"os/signal"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"

"github.com/freddierice/go-losetup/v2"
"github.com/klauspost/cpuid/v2"
"github.com/siderolabs/go-kmsg"
"github.com/siderolabs/go-procfs/procfs"
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/internal/pkg/mount"
"github.com/siderolabs/talos/internal/pkg/mount/switchroot"
"github.com/siderolabs/talos/internal/pkg/mount/v2"
"github.com/siderolabs/talos/internal/pkg/rng"
"github.com/siderolabs/talos/internal/pkg/secureboot"
"github.com/siderolabs/talos/internal/pkg/secureboot/tpm2"
Expand All @@ -38,31 +36,27 @@ func init() {
runtime.MemProfileRate = 0
}

func run() (err error) {
func run() error {
// Mount the pseudo devices.
pseudo, err := mount.PseudoMountPoints()
if err != nil {
return err
}
pseudoMountPoints := mount.Pseudo()

if err = mount.Mount(pseudo); err != nil {
if _, err := pseudoMountPoints.Mount(); err != nil {
return err
}

// Setup logging to /dev/kmsg.
err = kmsg.SetupLogger(nil, "[talos] [initramfs]", nil)
if err != nil {
if err := kmsg.SetupLogger(nil, "[talos] [initramfs]", nil); err != nil {
return err
}

// Seed RNG.
if err = rng.TPMSeed(); err != nil {
if err := rng.TPMSeed(); err != nil {
// not making this fatal error
log.Printf("failed to seed from the TPM: %s", err)
}

// extend PCR 11 with enter-initrd
if err = tpm2.PCRExtend(secureboot.UKIPCR, []byte(secureboot.EnterInitrd)); err != nil {
if err := tpm2.PCRExtend(secureboot.UKIPCR, []byte(secureboot.EnterInitrd)); err != nil {
return fmt.Errorf("failed to extend PCR %d with enter-initrd: %v", secureboot.UKIPCR, err)
}

Expand All @@ -71,24 +65,24 @@ func run() (err error) {
cpuInfo()

// Mount the rootfs.
if err = mountRootFS(); err != nil {
if err := mountRootFS(); err != nil {
return err
}

// Bind mount the lib/firmware if needed.
if err = bindMountFirmware(); err != nil {
if err := bindMountFirmware(); err != nil {
return err
}

// Bind mount /.extra if needed.
if err = bindMountExtra(); err != nil {
if err := bindMountExtra(); err != nil {
return err
}

// Switch into the new rootfs.
log.Println("entering the rootfs")

return switchroot.Switch(constants.NewRoot, pseudo)
return switchroot.Switch(constants.NewRoot, pseudoMountPoints)
}

func recovery() {
Expand Down Expand Up @@ -131,12 +125,14 @@ func mountRootFS() error {

// if no extensions found use plain squashfs mount
if len(extensionsConfig.Layers) == 0 {
squashfs, err := mount.SquashfsMountPoints(constants.NewRoot)
squashfs, err := mount.Squashfs(constants.NewRoot, "/"+constants.RootfsAsset)
if err != nil {
return err
}

return mount.Mount(squashfs)
_, err = squashfs.Mount()

return err
}

// otherwise compose overlay mounts
Expand All @@ -145,9 +141,10 @@ func mountRootFS() error {
image string
}

var layers []layer

squashfs := mount.NewMountPoints()
var (
layers []layer
squashfsPoints mount.Points
)

// going in the inverse order as earlier layers are overlayed on top of the latter ones
for i := len(extensionsConfig.Layers) - 1; i >= 0; i-- {
Expand All @@ -167,29 +164,30 @@ func mountRootFS() error {
overlays := make([]string, 0, len(layers))

for _, layer := range layers {
dev, err := losetup.Attach(layer.image, 0, true)
target := filepath.Join(constants.ExtensionLayers, layer.name)

point, err := mount.Squashfs(target, layer.image)
if err != nil {
return err
}

p := mount.NewMountPoint(dev.Path(), "/"+layer.name, "squashfs", unix.MS_RDONLY|unix.MS_I_VERSION, "", mount.WithPrefix(constants.ExtensionLayers), mount.WithFlags(mount.ReadOnly|mount.Shared))

overlays = append(overlays, p.Target())
squashfs.Set(layer.name, p)
squashfsPoints = append(squashfsPoints, point)
overlays = append(overlays, target)
}

if err := mount.Mount(squashfs); err != nil {
squashfsUnmounter, err := squashfsPoints.Mount()
if err != nil {
return err
}

overlay := mount.NewMountPoints()
overlay.Set(constants.NewRoot, mount.NewMountPoint(strings.Join(overlays, ":"), constants.NewRoot, "", unix.MS_I_VERSION, "", mount.WithFlags(mount.ReadOnly|mount.ReadonlyOverlay|mount.Shared)))
overlayPoint := mount.NewReadonlyOverlay(overlays, constants.NewRoot, mount.WithShared(), mount.WithFlags(unix.MS_I_VERSION))

if err := mount.Mount(overlay); err != nil {
_, err = overlayPoint.Mount()
if err != nil {
return err
}

if err := mount.Unmount(squashfs); err != nil {
if err = squashfsUnmounter(); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion internal/app/machined/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
"github.com/siderolabs/talos/internal/app/maintenance"
"github.com/siderolabs/talos/internal/app/poweroff"
"github.com/siderolabs/talos/internal/app/trustd"
"github.com/siderolabs/talos/internal/pkg/mount"
"github.com/siderolabs/talos/internal/pkg/mount/v2"
"github.com/siderolabs/talos/pkg/httpdefaults"
"github.com/siderolabs/talos/pkg/machinery/api/common"
"github.com/siderolabs/talos/pkg/machinery/api/machine"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
"systemRequirements",
EnforceKSPPRequirements,
SetupSystemDirectory,
MountBPFFS,
MountCgroups,
MountPseudoFilesystems,
SetRLimit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func CreateSystemCgroups(runtime.Sequence, any) (runtime.TaskExecutionFunc, stri
if r.State().Platform().Mode() != runtime.ModeContainer {
// assert that cgroupsv2 is being used when running not in container mode,
// as Talos sets up cgroupsv2 on its own
if cgroups.Mode() != cgroups.Unified && !mount.ForceGGroupsV1() {
if cgroups.Mode() != cgroups.Unified && !mountv2.ForceGGroupsV1() {
return errors.New("cgroupsv2 should be used")
}
}
Expand Down Expand Up @@ -342,45 +342,21 @@ func CreateSystemCgroups(runtime.Sequence, any) (runtime.TaskExecutionFunc, stri
}, "CreateSystemCgroups"
}

// MountBPFFS represents the MountBPFFS task.
func MountBPFFS(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
var mountpoints *mount.Points

mountpoints, err = mount.BPFMountPoints()
if err != nil {
return err
}

return mount.Mount(mountpoints)
}, "mountBPFFS"
}

// MountCgroups represents the MountCgroups task.
func MountCgroups(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
var mountpoints *mount.Points

mountpoints, err = mount.CGroupMountPoints()
if err != nil {
return err
}
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
_, err := mountv2.CGroupMountPoints().Mount()

return mount.Mount(mountpoints)
return err
}, "mountCgroups"
}

// MountPseudoFilesystems represents the MountPseudoFilesystems task.
func MountPseudoFilesystems(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
var mountpoints *mount.Points

mountpoints, err = mount.PseudoSubMountPoints()
if err != nil {
return err
}
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
_, err := mountv2.PseudoSubMountPoints().Mount()

return mount.Mount(mountpoints)
return err
}, "mountPseudoFilesystems"
}

Expand Down Expand Up @@ -722,10 +698,9 @@ func StartDashboard(_ runtime.Sequence, _ any) (runtime.TaskExecutionFunc, strin
// StartUdevd represents the task to start udevd.
func StartUdevd(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
mp := mount.NewMountPoints()
mp.Set("udev-data", mount.NewMountPoint("", constants.UdevDir, "", unix.MS_I_VERSION, "", mount.WithFlags(mount.Overlay|mount.SystemOverlay|mount.Shared)))
mp := mountv2.NewSystemOverlay([]string{constants.UdevDir}, constants.UdevDir, mountv2.WithShared(), mountv2.WithFlags(unix.MS_I_VERSION))

if err = mount.Mount(mp); err != nil {
if _, err = mp.Mount(); err != nil {
return err
}

Expand Down Expand Up @@ -864,14 +839,9 @@ func StopAllServices(runtime.Sequence, any) (runtime.TaskExecutionFunc, string)
// MountOverlayFilesystems represents the MountOverlayFilesystems task.
func MountOverlayFilesystems(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
var mountpoints *mount.Points

mountpoints, err = mount.OverlayMountPoints()
if err != nil {
return err
}
_, err = mountv2.OverlayMountPoints().Mount()

return mount.Mount(mountpoints)
return err
}, "mountOverlayFilesystems"
}

Expand Down Expand Up @@ -1191,14 +1161,7 @@ func existsAndIsFile(p string) (err error) {
// UnmountOverlayFilesystems represents the UnmountOverlayFilesystems task.
func UnmountOverlayFilesystems(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
var mountpoints *mount.Points

mountpoints, err = mount.OverlayMountPoints()
if err != nil {
return err
}

return mount.Unmount(mountpoints)
return mountv2.OverlayMountPoints().Unmount()
}, "unmountOverlayFilesystems"
}

Expand Down Expand Up @@ -1266,7 +1229,7 @@ func UnmountPodMounts(runtime.Sequence, any) (runtime.TaskExecutionFunc, string)
if strings.HasPrefix(mountpoint, constants.EphemeralMountPoint+"/") {
logger.Printf("unmounting %s\n", mountpoint)

if err = mount.SafeUnmount(ctx, logger, mountpoint); err != nil {
if err = mountv2.SafeUnmount(ctx, logger.Printf, mountpoint); err != nil {
if errors.Is(err, syscall.EINVAL) {
log.Printf("ignoring unmount error %s: %v", mountpoint, err)
} else {
Expand Down Expand Up @@ -1315,7 +1278,7 @@ func UnmountSystemDiskBindMounts(runtime.Sequence, any) (runtime.TaskExecutionFu
if strings.HasPrefix(device, devname) && device != devname {
logger.Printf("unmounting %s\n", mountpoint)

if err = mount.SafeUnmount(ctx, logger, mountpoint); err != nil {
if err = mountv2.SafeUnmount(ctx, logger.Printf, mountpoint); err != nil {
if errors.Is(err, syscall.EINVAL) {
log.Printf("ignoring unmount error %s: %v", mountpoint, err)
} else {
Expand Down Expand Up @@ -2257,7 +2220,7 @@ func ForceCleanup(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
logger.Printf("error killing all procs: %s", err)
}

if err := mount.UnmountAll(); err != nil {
if err := mountv2.UnmountAll(); err != nil {
logger.Printf("error unmounting: %s", err)
}

Expand Down
24 changes: 13 additions & 11 deletions internal/app/machined/pkg/system/services/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/siderolabs/talos/internal/app/machined/pkg/system/runner/restart"
"github.com/siderolabs/talos/internal/pkg/capability"
"github.com/siderolabs/talos/internal/pkg/environment"
"github.com/siderolabs/talos/internal/pkg/mount"
"github.com/siderolabs/talos/internal/pkg/mount/v2"
"github.com/siderolabs/talos/pkg/conditions"
"github.com/siderolabs/talos/pkg/machinery/constants"
extservices "github.com/siderolabs/talos/pkg/machinery/extensions/services"
Expand All @@ -39,7 +39,7 @@ import (
type Extension struct {
Spec extservices.Spec

overlay *mount.Point
overlayUnmounter func() error
}

// ID implements the Service interface.
Expand All @@ -50,21 +50,23 @@ func (svc *Extension) ID(r runtime.Runtime) string {
// PreFunc implements the Service interface.
func (svc *Extension) PreFunc(ctx context.Context, r runtime.Runtime) error {
// re-mount service rootfs as overlay rw mount to allow containerd to mount there /dev, /proc, etc.
svc.overlay = mount.NewMountPoint(
"",
filepath.Join(constants.ExtensionServiceRootfsPath, svc.Spec.Name),
"",
0,
"",
mount.WithFlags(mount.Overlay|mount.SystemOverlay),
rootfsPath := filepath.Join(constants.ExtensionServiceRootfsPath, svc.Spec.Name)

overlay := mount.NewSystemOverlay(
[]string{rootfsPath},
rootfsPath,
)

return svc.overlay.Mount()
var err error

svc.overlayUnmounter, err = overlay.Mount()

return err
}

// PostFunc implements the Service interface.
func (svc *Extension) PostFunc(r runtime.Runtime, state events.ServiceState) (err error) {
return svc.overlay.Unmount()
return svc.overlayUnmounter()
}

// Condition implements the Service interface.
Expand Down
14 changes: 0 additions & 14 deletions internal/pkg/mount/bpffs.go

This file was deleted.

Loading

0 comments on commit 62ec7ec

Please sign in to comment.