[lxc-devel] [distrobuilder/master] chroot: Don't bind-mount /dev
monstermunchkin on Github
lxc-bot at linuxcontainers.org
Tue Mar 3 10:58:38 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 527 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200303/8f8e55e5/attachment.bin>
-------------- next part --------------
From 3affb6bb9aa8020eaabc7d3a4746bb3b59d3297a Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Tue, 3 Mar 2020 11:28:33 +0100
Subject: [PATCH] chroot: Don't bind-mount /dev
Instead of bind-mounting /dev, it now creates necessary /dev files using
mknod. When creating VMs, it bind-mounts the loop device and its
partitions as well.
Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
distrobuilder/main_lxd.go | 16 +++++++++++++
distrobuilder/vm.go | 4 ++++
shared/chroot.go | 48 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go
index 2fa2648..0bd314f 100644
--- a/distrobuilder/main_lxd.go
+++ b/distrobuilder/main_lxd.go
@@ -9,6 +9,7 @@ import (
lxd "github.com/lxc/lxd/shared"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "golang.org/x/sys/unix"
"github.com/lxc/distrobuilder/generators"
"github.com/lxc/distrobuilder/image"
@@ -269,6 +270,21 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
rootfsDir = vmDir
mounts = []shared.ChrootMount{
+ {
+ Source: vm.getLoopDev(),
+ Target: filepath.Join("/", "dev", filepath.Base(vm.getLoopDev())),
+ Flags: unix.MS_BIND,
+ },
+ {
+ Source: vm.getRootfsDevFile(),
+ Target: filepath.Join("/", "dev", filepath.Base(vm.getRootfsDevFile())),
+ Flags: unix.MS_BIND,
+ },
+ {
+ Source: vm.getUEFIDevFile(),
+ Target: filepath.Join("/", "dev", filepath.Base(vm.getUEFIDevFile())),
+ Flags: unix.MS_BIND,
+ },
{
Source: vm.getUEFIDevFile(),
Target: "/boot/efi",
diff --git a/distrobuilder/vm.go b/distrobuilder/vm.go
index 1bcda60..f6ba300 100644
--- a/distrobuilder/vm.go
+++ b/distrobuilder/vm.go
@@ -38,6 +38,10 @@ func newVM(imageFile, rootfsDir, fs string, size uint64) (*vm, error) {
return &vm{imageFile: imageFile, rootfsDir: rootfsDir, rootFS: fs, size: size}, nil
}
+func (v *vm) getLoopDev() string {
+ return v.loopDevice
+}
+
func (v *vm) getRootfsDevFile() string {
if v.loopDevice == "" {
return ""
diff --git a/shared/chroot.go b/shared/chroot.go
index 13b215b..73282b8 100644
--- a/shared/chroot.go
+++ b/shared/chroot.go
@@ -174,7 +174,6 @@ func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() err
mounts := []ChrootMount{
{"none", "/proc", "proc", 0, "", true},
{"none", "/sys", "sysfs", 0, "", true},
- {"/dev", "/dev", "", unix.MS_BIND | unix.MS_REC, "", true},
{"none", "/run", "tmpfs", 0, "", true},
{"none", "/tmp", "tmpfs", 0, "", true},
{"/etc/resolv.conf", "/etc/resolv.conf", "", unix.MS_BIND, "", false},
@@ -219,6 +218,12 @@ func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() err
return nil, err
}
+ // Populate /dev directory instead of bind mounting it from the host
+ err = populateDev()
+ if err != nil {
+ return nil, errors.Wrap(err, "Failed to populate /dev")
+ }
+
var env Environment
if envs.ClearDefaults {
@@ -329,3 +334,44 @@ exit 101
return exitFunc, nil
}
+
+func populateDev() error {
+ devs := []struct {
+ Path string
+ Major uint32
+ Minor uint32
+ Mode uint32
+ }{
+ {"/dev/console", 5, 1, unix.S_IFCHR | 0640},
+ {"/dev/full", 1, 7, unix.S_IFCHR | 0666},
+ {"/dev/null", 1, 3, unix.S_IFCHR | 0666},
+ {"/dev/random", 1, 8, unix.S_IFCHR | 0666},
+ {"/dev/tty", 5, 0, unix.S_IFCHR | 0666},
+ {"/dev/urandom", 1, 9, unix.S_IFCHR | 0666},
+ {"/dev/zero", 1, 5, unix.S_IFCHR | 0666},
+ }
+
+ for _, d := range devs {
+ if lxd.PathExists(d.Path) {
+ continue
+ }
+
+ dev := unix.Mkdev(d.Major, d.Minor)
+
+ err := unix.Mknod(d.Path, d.Mode, int(dev))
+ if err != nil {
+ return errors.Wrapf(err, "Failed to create %q", d.Path)
+ }
+ }
+
+ if lxd.PathExists("/dev/fd") {
+ return nil
+ }
+
+ err := os.Symlink("/proc/self/fd", "/dev/fd")
+ if err != nil {
+ return errors.Wrapf(err, "Failed to link %q -> %q", "/dev/fd", "/proc/self/fd")
+ }
+
+ return nil
+}
More information about the lxc-devel
mailing list