Beispiel #1
0
func (d DriverEFS) Mount(r dkvolume.Request) dkvolume.Response {
	p := filepath.Join(d.Root, r.Name)

	// Check if the directory already exists.
	nfs, err := mount.Mounted(p)
	if err != nil {
		return dkvolume.Response{Err: err.Error()}
	}
	if Exists(p) && nfs {
		log.Printf("Existing: %s", r.Name)
		return dkvolume.Response{Mountpoint: p}
	}

	e := efs.New(&aws.Config{Region: aws.String(d.Region)})

	m, err := GetEFS(e, d.Subnet, r.Name)
	if err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	if err := os.MkdirAll(p, 0755); err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	// Mount the EFS volume to the local filesystem.
	// @todo, Swap this out with an NFS client library.
	if err := Exec("mount", "-t", "nfs4", m+":/", p); err != nil {
		return dkvolume.Response{Err: err.Error()}
	}

	log.Printf("Mounting: %s", r.Name)
	return dkvolume.Response{Mountpoint: p}
}
Beispiel #2
0
// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs.
func TmpfsRoot(l *LinuxFactory) error {
	mounted, err := mount.Mounted(l.Root)
	if err != nil {
		return err
	}
	if !mounted {
		if err := syscall.Mount("tmpfs", l.Root, "tmpfs", 0, ""); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #3
0
func TestFactoryNewTmpfs(t *testing.T) {
	root, rerr := newTestRoot()
	if rerr != nil {
		t.Fatal(rerr)
	}
	defer os.RemoveAll(root)
	factory, err := New(root, Cgroupfs, TmpfsRoot)
	if err != nil {
		t.Fatal(err)
	}
	if factory == nil {
		t.Fatal("factory should not be nil")
	}
	lfactory, ok := factory.(*LinuxFactory)
	if !ok {
		t.Fatal("expected linux factory returned on linux based systems")
	}
	if lfactory.Root != root {
		t.Fatalf("expected factory root to be %q but received %q", root, lfactory.Root)
	}

	if factory.Type() != "libcontainer" {
		t.Fatalf("unexpected factory type: %q, expected %q", factory.Type(), "libcontainer")
	}
	mounted, err := mount.Mounted(lfactory.Root)
	if err != nil {
		t.Fatal(err)
	}
	if !mounted {
		t.Fatalf("Factory Root is not mounted")
	}
	mounts, err := mount.GetMounts()
	if err != nil {
		t.Fatal(err)
	}
	var found bool
	for _, m := range mounts {
		if m.Mountpoint == lfactory.Root {
			if m.Fstype != "tmpfs" {
				t.Fatalf("Fstype of root: %s, expected %s", m.Fstype, "tmpfs")
			}
			if m.Source != "tmpfs" {
				t.Fatalf("Source of root: %s, expected %s", m.Source, "tmpfs")
			}
			found = true
		}
	}
	if !found {
		t.Fatalf("Factory Root is not listed in mounts list")
	}
	defer syscall.Unmount(root, syscall.MNT_DETACH)
}
Beispiel #4
0
func MakePrivate(mountPoint string) error {
	mounted, err := mount.Mounted(mountPoint)
	if err != nil {
		return err
	}

	if !mounted {
		if err := mount.Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil {
			return err
		}
	}

	return mount.ForceMount("", mountPoint, "none", "private")
}
Beispiel #5
0
func MountIfNotMounted(device, target, mType, options string) error {
	mounted, err := mount.Mounted(target)
	if err != nil {
		return err
	}

	if !mounted {
		log.Debug("mount", device, target, mType, options)
		if err := mount.Mount(device, target, mType, options); err != nil {
			return err
		}
	}

	return nil
}
Beispiel #6
0
func Cleanup(d string) {
	log.Println("Running cleanup task")

	// Get a list of all the current running containers.
	mounts, err := GetDockerBinds()
	if err != nil {
		log.Println(err)
		return
	}

	// Go over the list of possible mounts and compare against the Docker running
	// containers list.
	files, _ := ioutil.ReadDir(d + "/")
	for _, f := range files {
		m := f.Name()
		p := filepath.Join(d, m)

		// We only deal with directories.
		if !f.IsDir() {
			continue
		}

		// We only deal with directories which are also mounts.
		nfs, err := mount.Mounted(p)
		if err != nil {
			log.Printf("Cannot determine if mounted %s", m)
			continue
		}
		if !nfs {
			continue
		}

		// Ensure that we are not unmounting filesystems which are still
		// being used by a container in Docker.
		if Contains(mounts, m) {
			continue
		}

		err = Exec("umount", p)
		if err != nil {
			log.Printf("Cleanup failed: %s", m)
			return
		}
		log.Printf("Cleaned: %s", m)
	}
}
Beispiel #7
0
func TestCreateWithOpts(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip()
	}

	rootDir, err := ioutil.TempDir("", "local-volume-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(rootDir)

	r, err := New(rootDir, 0, 0)
	if err != nil {
		t.Fatal(err)
	}

	if _, err := r.Create("test", map[string]string{"invalidopt": "notsupported"}); err == nil {
		t.Fatal("expected invalid opt to cause error")
	}

	vol, err := r.Create("test", map[string]string{"device": "tmpfs", "type": "tmpfs", "o": "size=1m,uid=1000"})
	if err != nil {
		t.Fatal(err)
	}
	v := vol.(*localVolume)

	dir, err := v.Mount("1234")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := v.Unmount("1234"); err != nil {
			t.Fatal(err)
		}
	}()

	mountInfos, err := mount.GetMounts()
	if err != nil {
		t.Fatal(err)
	}

	var found bool
	for _, info := range mountInfos {
		if info.Mountpoint == dir {
			found = true
			if info.Fstype != "tmpfs" {
				t.Fatalf("expected tmpfs mount, got %q", info.Fstype)
			}
			if info.Source != "tmpfs" {
				t.Fatalf("expected tmpfs mount, got %q", info.Source)
			}
			if !strings.Contains(info.VfsOpts, "uid=1000") {
				t.Fatalf("expected mount info to have uid=1000: %q", info.VfsOpts)
			}
			if !strings.Contains(info.VfsOpts, "size=1024k") {
				t.Fatalf("expected mount info to have size=1024k: %q", info.VfsOpts)
			}
			break
		}
	}

	if !found {
		t.Fatal("mount not found")
	}

	if v.active.count != 1 {
		t.Fatalf("Expected active mount count to be 1, got %d", v.active.count)
	}

	// test double mount
	if _, err := v.Mount("1234"); err != nil {
		t.Fatal(err)
	}
	if v.active.count != 2 {
		t.Fatalf("Expected active mount count to be 2, got %d", v.active.count)
	}

	if err := v.Unmount("1234"); err != nil {
		t.Fatal(err)
	}
	if v.active.count != 1 {
		t.Fatalf("Expected active mount count to be 1, got %d", v.active.count)
	}

	mounted, err := mount.Mounted(v.path)
	if err != nil {
		t.Fatal(err)
	}
	if !mounted {
		t.Fatal("expected mount to still be active")
	}

	r, err = New(rootDir, 0, 0)
	if err != nil {
		t.Fatal(err)
	}

	v2, exists := r.volumes["test"]
	if !exists {
		t.Fatal("missing volume on restart")
	}

	if !reflect.DeepEqual(v.opts, v2.opts) {
		t.Fatal("missing volume options on restart")
	}
}
Beispiel #8
0
func (c *defaultChecker) IsMounted(path string) bool {
	m, _ := mount.Mounted(path)
	return m
}
Beispiel #9
0
func (a *Driver) mounted(id string) (bool, error) {
	target := path.Join(a.rootPath(), "mnt", id)
	return mountpk.Mounted(target)
}
Beispiel #10
0
func (a *Driver) mounted(m *data) (bool, error) {
	return mountpk.Mounted(m.path)
}
Beispiel #11
0
// Create a disk, make an ext filesystem on it, set the label, mount it,
// unmount it, then clean up.
func TestCreateFS(t *testing.T) {
	log.SetLevel(log.DebugLevel)

	client := Session(context.Background(), t)
	if client == nil {
		return
	}

	imagestore := client.Datastore.Path(datastore.TestName("diskTest"))

	fm := object.NewFileManager(client.Vim25())

	// create a directory in the datastore
	// eat the error because we dont care if it exists
	fm.MakeDirectory(context.TODO(), imagestore, nil, true)

	// Nuke the image store
	defer func() {
		task, err := fm.DeleteDatastoreFile(context.TODO(), imagestore, nil)
		if err != nil && err.Error() == "can't find the hosting vm" {
			t.Skip("Skipping: test must be run in a VM")
		}
		if !assert.NoError(t, err) {
			return
		}
		_, err = task.WaitForResult(context.TODO(), nil)
		if !assert.NoError(t, err) {
			return
		}
	}()

	op := trace.NewOperation(context.TODO(), "test")

	vdm, err := NewDiskManager(op, client)
	if err != nil && err.Error() == "can't find the hosting vm" {
		t.Skip("Skipping: test must be run in a VM")
	}
	if !assert.NoError(t, err) || !assert.NotNil(t, vdm) {
		return
	}

	diskSize := int64(1 << 10)
	d, err := vdm.CreateAndAttach(op, path.Join(imagestore, "scratch.vmdk"), "", diskSize, os.O_RDWR)
	if !assert.NoError(t, err) {
		return
	}

	// make the filesysetem
	if err = d.Mkfs("foo"); !assert.NoError(t, err) {
		return
	}

	// set the label
	if err = d.SetLabel("foo"); !assert.NoError(t, err) {
		return
	}

	// make a tempdir to mount the fs to
	dir, err := ioutil.TempDir("", "mnt")
	if !assert.NoError(t, err) {
		return
	}
	defer os.RemoveAll(dir)

	// do the mount
	err = d.Mount(dir, nil)
	if !assert.NoError(t, err) {
		return
	}

	// boom
	if mounted, err := mount.Mounted(dir); !assert.NoError(t, err) || !assert.True(t, mounted) {
		return
	}

	//  clean up
	err = d.Unmount()
	if !assert.NoError(t, err) {
		return
	}

	err = vdm.Detach(op, d)
	if !assert.NoError(t, err) {
		return
	}
}
Beispiel #12
0
func (d *driver) Mounted(mountPoint string) (bool, error) {
	return mount.Mounted(mountPoint)
}
Beispiel #13
0
// chroot on linux uses pivot_root instead of chroot
// pivot_root takes a new root and an old root.
// Old root must be a sub-dir of new root, it is where the current rootfs will reside after the call to pivot_root.
// New root is where the new rootfs is set to.
// Old root is removed after the call to pivot_root so it is no longer available under the new root.
// This is similar to how libcontainer sets up a container's rootfs
func chroot(path string) (err error) {
	// if the engine is running in a user namespace we need to use actual chroot
	if rsystem.RunningInUserNS() {
		return realChroot(path)
	}
	if err := syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
		return fmt.Errorf("Error creating mount namespace before pivot: %v", err)
	}

	// make everything in new ns private
	if err := mount.MakeRPrivate("/"); err != nil {
		return err
	}

	if mounted, _ := mount.Mounted(path); !mounted {
		if err := mount.Mount(path, path, "bind", "rbind,rw"); err != nil {
			return realChroot(path)
		}
	}

	// setup oldRoot for pivot_root
	pivotDir, err := ioutil.TempDir(path, ".pivot_root")
	if err != nil {
		return fmt.Errorf("Error setting up pivot dir: %v", err)
	}

	var mounted bool
	defer func() {
		if mounted {
			// make sure pivotDir is not mounted before we try to remove it
			if errCleanup := syscall.Unmount(pivotDir, syscall.MNT_DETACH); errCleanup != nil {
				if err == nil {
					err = errCleanup
				}
				return
			}
		}

		errCleanup := os.Remove(pivotDir)
		// pivotDir doesn't exist if pivot_root failed and chroot+chdir was successful
		// because we already cleaned it up on failed pivot_root
		if errCleanup != nil && !os.IsNotExist(errCleanup) {
			errCleanup = fmt.Errorf("Error cleaning up after pivot: %v", errCleanup)
			if err == nil {
				err = errCleanup
			}
		}
	}()

	if err := syscall.PivotRoot(path, pivotDir); err != nil {
		// If pivot fails, fall back to the normal chroot after cleaning up temp dir
		if err := os.Remove(pivotDir); err != nil {
			return fmt.Errorf("Error cleaning up after failed pivot: %v", err)
		}
		return realChroot(path)
	}
	mounted = true

	// This is the new path for where the old root (prior to the pivot) has been moved to
	// This dir contains the rootfs of the caller, which we need to remove so it is not visible during extraction
	pivotDir = filepath.Join("/", filepath.Base(pivotDir))

	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("Error changing to new root: %v", err)
	}

	// Make the pivotDir (where the old root lives) private so it can be unmounted without propagating to the host
	if err := syscall.Mount("", pivotDir, "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("Error making old root private after pivot: %v", err)
	}

	// Now unmount the old root so it's no longer visible from the new root
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("Error while unmounting old root after pivot: %v", err)
	}
	mounted = false

	return nil
}
Beispiel #14
0
func (t *BaseOperations) Setup(config Config) error {
	c, err := client.NewClient()
	if err != nil {
		return err
	}

	h := etcconf.NewHosts(hostsFile)
	if err = h.Load(); err != nil {
		return err
	}

	// make sure localhost entries are present
	entries := []struct {
		hostname string
		addr     net.IP
	}{
		{"localhost", net.ParseIP("127.0.0.1")},
		{"ip6-localhost", net.ParseIP("::1")},
		{"ip6-loopback", net.ParseIP("::1")},
		{"ip6-localnet", net.ParseIP("fe00::0")},
		{"ip6-mcastprefix", net.ParseIP("ff00::0")},
		{"ip6-allnodes", net.ParseIP("ff02::1")},
		{"ip6-allrouters", net.ParseIP("ff02::2")},
	}

	for _, e := range entries {
		h.SetHost(e.hostname, e.addr)
	}

	if err = h.Save(); err != nil {
		return err
	}

	// start with empty resolv.conf
	os.Remove(resolvFile)

	rc := etcconf.NewResolvConf(resolvFile)

	t.dynEndpoints = make(map[string][]*NetworkEndpoint)
	t.dhcpLoops = make(map[string]chan bool)
	t.dhcpClient = c
	t.hosts = h
	t.resolvConf = rc
	t.config = config

	// support the df command (#1642)
	if err = os.Symlink("/proc/mounts", "/etc/mtab"); err != nil {
		return err
	}

	mounted, err := mount.Mounted(runMountPoint)
	if err != nil {
		return err
	}
	if mounted {
		// unmount /run - https://github.com/vmware/vic/issues/1643
		if err := syscall.Unmount(runMountPoint, syscall.MNT_DETACH); err != nil {
			return fmt.Errorf("unmount %s failed with %q", runMountPoint, err)
		}
	}

	return nil
}