Skip to content

Commit

Permalink
Check if root= is a regular file and if yes create a loopback device
Browse files Browse the repository at this point in the history
... which allows to mount this file.

Such functionality is useful in case if we have a erofs image inside an ISO.

The erofs image cannot be mounted directly, thus we need to represent it as a device file first.

Implements: #232
  • Loading branch information
anatol committed Sep 6, 2023
1 parent 0b8f6f4 commit c46a2e6
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/manpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Device reference has one of the following values:

* `/dev/XXX` path to specific device file, it can be either a path to real device/partition like `/dev/sda1`, `/dev/nvme0n1` or path to dm-mapper virtual device like
`/dev/mapper/root` or `/dev/vg_mesos/lv_mesos_containers`.
* If the path does not start with `/dev/` and represents a regular file then booster will assume it is an image file of the root filesystem (e.g. erofs inside of an ISO). Booster will try to setup a loopback device and then mount it as a root filesystem.
* `UUID=$UUID` or `/dev/disk/by-uuid/$UUID` references device by its filesystem/LUKS UUID. See notes about UUID formatting rules below.
* `LABEL=$LABEL` or `/dev/disk/by-label/$LABEL` references device by its filesystem/LUKS label.
* `PARTUUID=$UUID` or `/dev/disk/by-partuuid/$UUID` references device by GPT partition UUID.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/anatol/tang.go v0.0.0-20220716012326-2fda8b4503da
github.com/anatol/vmtest v0.0.0-20230711210602-87511df0d4bc
github.com/cavaliergopher/cpio v1.0.1
github.com/freddierice/go-losetup/v2 v2.0.1
github.com/google/go-tpm v0.9.0
github.com/google/renameio/v2 v2.0.0
github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d h1:CPqTNIigGweVPT4CYb+OO2E6XyRKFOmvTHwWRLgCAlE=
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d/go.mod h1:QX5ZVULjAfZJux/W62Y91HvCh9hyW6enAwcrrv/sLj0=
github.com/freddierice/go-losetup/v2 v2.0.1 h1:wPDx/Elu9nDV8y/CvIbEDz5Xi5Zo80y4h7MKbi3XaAI=
github.com/freddierice/go-losetup/v2 v2.0.1/go.mod h1:TEyBrvlOelsPEhfWD5rutNXDmUszBXuFnwT1kIQF4J8=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk=
Expand Down
5 changes: 0 additions & 5 deletions init/blkinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ func shell(script string, env ...string) error {
return sh.Run()
}

func fileExists(file string) bool {
_, err := os.Stat(file)
return err == nil
}

func TestBlkInfoFAT(t *testing.T) {
checkFs(t, "fat", "fat", "2a341c62", "FATLBL", 10, "mkfs.vfat -F32 -n $LABEL -i $UUID $OUTPUT", nil)
}
Expand Down
18 changes: 18 additions & 0 deletions init/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"time"
"unsafe"

"github.com/freddierice/go-losetup/v2"
"github.com/yookoala/realpath"
"golang.org/x/sys/unix"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -856,6 +857,23 @@ func boost() error {
}
}

if cmdRoot.format == refPath {
rootFS := cmdRoot.data.(string)
if !strings.HasPrefix(rootFS, "/dev/") && fileExists(rootFS) {
// there is a special case when a root filesystem is a filesystem image rather than a device (e.g. in case of erofs inside of an ISO)
// so if it is just a regular file then we create a loopback device for it and then try to mount
dev, err := losetup.Attach(rootFS, 0, rootRw)
if err != nil {
return err
}
cmdRoot.data = dev.Path()

if err := addBlockDevice(dev.Path(), true, nil); err != nil {
return err
}
}
}

if config.MountTimeout != 0 {
// TODO: cancellable, timeout context?
timeout := waitTimeout(&rootMounted, time.Duration(config.MountTimeout)*time.Second)
Expand Down
5 changes: 5 additions & 0 deletions init/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,8 @@ func unwrapExitError(err error) error {
}
return err
}

func fileExists(file string) bool {
_, err := os.Stat(file)
return err == nil
}

0 comments on commit c46a2e6

Please sign in to comment.