Deal nicely with already mounted errors

Signed-off-by: Itxaka <itxaka@spectrocloud.com>
This commit is contained in:
Itxaka
2023-02-09 12:35:45 +01:00
parent 645d0a428a
commit aee2bbde84
4 changed files with 38 additions and 22 deletions

View File

@@ -1,8 +1,12 @@
package constants
import "errors"
const PersistentStateTarget = "/usr/local/.state"
func DefaultRWPaths() []string {
// Default RW_PATHS to mount if there are none defined
return []string{"/etc", "/root", "/home", "/opt", "/srv", "/usr/local", "/var"}
}
var ErrAlreadyMounted = errors.New("already mounted")

View File

@@ -27,21 +27,15 @@ func baseOverlay(overlay Overlay) (mountOperation, error) {
switch t {
case "tmpfs":
tmpMount := mount.Mount{Type: "tmpfs", Source: "tmpfs", Options: []string{fmt.Sprintf("size=%s", dat[1])}}
err := mount.All([]mount.Mount{tmpMount}, overlay.Base)
tmpFstab := internalUtils.MountToFstab(tmpMount)
// TODO: Fix this
// Currently stores it wrongly the the fstab as `tmpfs tmpfs:20% tmpfs size=20% 0 0`
// Correct format should be `tmpfs /run/overlay tmpfs defaults,size=20% 0 0`
tmpFstab.File = internalUtils.CleanSysrootForFstab(overlay.Base)
return mountOperation{
MountOption: tmpMount,
FstabEntry: *tmpFstab,
Target: overlay.Base,
}, err
}, nil
case "block":
blockMount := mount.Mount{Type: "auto", Source: dat[1]}
err := mount.All([]mount.Mount{blockMount}, overlay.Base)
tmpFstab := internalUtils.MountToFstab(blockMount)
// TODO: Check if this is properly written to fstab, currently have no examples
tmpFstab.File = internalUtils.CleanSysrootForFstab(overlay.Base)
@@ -51,7 +45,7 @@ func baseOverlay(overlay Overlay) (mountOperation, error) {
MountOption: blockMount,
FstabEntry: *tmpFstab,
Target: overlay.Base,
}, err
}, nil
default:
return mountOperation{}, fmt.Errorf("invalid overlay backing base type")
}

View File

@@ -2,6 +2,7 @@ package mount
import (
"context"
"errors"
"fmt"
"github.com/kairos-io/immucore/internal/constants"
"os"
@@ -132,11 +133,16 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du
}
err = op.run()
if err != nil {
if err == nil {
s.fstabs = append(s.fstabs, tmpFstab)
}
// only continue the loop if it's an error and not an already mounted error
if err != nil && !errors.Is(err, constants.ErrAlreadyMounted) {
continue
}
s.fstabs = append(s.fstabs, tmpFstab)
return nil
case <-c.Done():
e := fmt.Errorf("context canceled")
@@ -328,7 +334,12 @@ func (s *State) Register(g *herd.Graph) error {
return err
}
s.fstabs = append(s.fstabs, &op.FstabEntry)
return op.run()
err = op.run()
// Don't return error if it's an already mounted error
if err != nil && errors.Is(err, constants.ErrAlreadyMounted) {
return nil
}
return err
},
),
)
@@ -347,17 +358,21 @@ func (s *State) Register(g *herd.Graph) error {
mountRootCondition,
herd.WithCallback(
func(ctx context.Context) error {
var err error
var err *multierror.Error
for _, p := range s.OverlayDirs {
op, err := mountWithBaseOverlay(p, s.Rootdir, "/run/overlay")
if err != nil {
return err
}
s.fstabs = append(s.fstabs, &op.FstabEntry)
err = multierror.Append(err, op.run())
err2 := op.run()
// Append to errors only if it's not an already mounted error
if err2 != nil && !errors.Is(err2, constants.ErrAlreadyMounted) {
err = multierror.Append(err, err2)
}
}
return err
return err.ErrorOrNil()
},
),
)
@@ -416,13 +431,15 @@ func (s *State) Register(g *herd.Graph) error {
}
op := mountBind(p, s.Rootdir, s.StateDir)
err2 := op.run()
if err2 != nil {
log.Logger.Err(err2).Send()
err = multierror.Append(err, err2)
} else {
if err2 == nil {
// Only append to fstabs if there was no error, otherwise we will try to mount it after switch_root
s.fstabs = append(s.fstabs, &op.FstabEntry)
}
// Append to errors only if it's not an already mounted error
if err2 != nil && !errors.Is(err2, constants.ErrAlreadyMounted) {
log.Logger.Err(err2).Send()
err = multierror.Append(err, err2)
}
}
log.Logger.Err(err.ErrorOrNil()).Send()
return err.ErrorOrNil()

View File

@@ -3,6 +3,7 @@ package mount
import (
"github.com/containerd/containerd/mount"
"github.com/deniswernert/go-fstab"
"github.com/kairos-io/immucore/internal/constants"
"github.com/moby/sys/mountinfo"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
@@ -20,19 +21,19 @@ func (m mountOperation) run() error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger()
if m.PrepareCallback != nil {
if err := m.PrepareCallback(); err != nil {
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("executing mount callback")
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Msg("executing mount callback")
return err
}
}
//TODO: not only check if mounted but also if the type,options and source are the same?
mounted, err := mountinfo.Mounted(m.Target)
if err != nil {
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("checking mount status")
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Msg("checking mount status")
return err
}
if mounted {
log.Logger.Debug().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("Already mounted")
return nil
log.Logger.Debug().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Msg("Already mounted")
return constants.ErrAlreadyMounted
}
return mount.All([]mount.Mount{m.MountOption}, m.Target)
}