Example #1
0
// Mount maps an RBD image and mount it on /mnt/ceph/<datastore>/<volume> directory
// FIXME: Figure out how to use rbd locks
func (cv *CephVolume) Mount(fstype string) error {
	cd := cv.driver
	// Directory to mount the volume
	dataStoreDir := filepath.Join(cd.mountBase, cv.PoolName)
	volumeDir := filepath.Join(dataStoreDir, cv.VolumeName)

	devName, err := cv.mapImage()
	if err != nil {
		return err
	}

	// Create directory to mount
	if err := os.MkdirAll(cd.mountBase, 0700); err != nil && !os.IsExist(err) {
		return fmt.Errorf("error creating %q directory: %v", cd.mountBase, err)
	}

	if err := os.MkdirAll(dataStoreDir, 0700); err != nil && !os.IsExist(err) {
		return fmt.Errorf("error creating %q directory: %v", dataStoreDir)
	}

	if err := os.MkdirAll(volumeDir, 0777); err != nil && !os.IsExist(err) {
		return fmt.Errorf("error creating %q directory: %v", volumeDir)
	}

	// Mount the RBD
	if err := unix.Mount(devName, volumeDir, fstype, 0, ""); err != nil && err != unix.EBUSY {
		return fmt.Errorf("Failed to mount RBD dev %q: %v", devName, err.Error())
	}

	return nil
}
func bindMountFile(src, dst string) error {
	// mount point has to be an existing file
	f, err := os.Create(dst)
	if err != nil {
		return err
	}
	f.Close()

	return unix.Mount(src, dst, "none", unix.MS_BIND, "")
}
Example #3
0
// Mount a volume. Returns the rbd device and mounted filesystem path.
// If you pass in the params what filesystem to use as `filesystem`, it will
// prefer that to `ext4` which is the default.
func (c *Driver) Mount(do storage.DriverOptions) (*storage.Mount, error) {
	intName, err := c.internalName(do.Volume.Name)
	if err != nil {
		return nil, err
	}

	poolName := do.Volume.Params["pool"]

	volumePath, err := c.mkMountPath(poolName, intName)
	if err != nil {
		return nil, err
	}

	devName, err := c.mapImage(do)
	if err != nil {
		return nil, err
	}

	// Create directory to mount
	if err := os.MkdirAll(c.mountpath, 0700); err != nil && !os.IsExist(err) {
		return nil, errored.Errorf("error creating %q directory: %v", c.mountpath, err)
	}

	if err := os.MkdirAll(volumePath, 0700); err != nil && !os.IsExist(err) {
		return nil, errored.Errorf("error creating %q directory: %v", volumePath, err)
	}

	// Obtain the major and minor node information about the device we're mounting.
	// This is critical for tuning cgroups and obtaining metrics for this device only.
	fi, err := os.Stat(devName)
	if err != nil {
		return nil, errored.Errorf("Failed to stat rbd device %q: %v", devName, err)
	}

	rdev := fi.Sys().(*syscall.Stat_t).Rdev

	major := rdev >> 8
	minor := rdev & 0xFF

	// Mount the RBD
	if err := unix.Mount(devName, volumePath, do.FSOptions.Type, 0, ""); err != nil {
		return nil, errored.Errorf("Failed to mount RBD dev %q: %v", devName, err)
	}

	return &storage.Mount{
		Device:   devName,
		Path:     volumePath,
		Volume:   do.Volume,
		DevMajor: uint(major),
		DevMinor: uint(minor),
	}, nil
}
Example #4
0
// New creates new namespace at specified path
func New(path string) (*Namespace, error) {
	runtime.LockOSThread()
	if err := syscall.Unshare(syscall.CLONE_NEWNET); err != nil {
		return nil, err
	}
	f, err := os.Create(path)
	if err != nil {
		return nil, err
	}
	f.Close()
	if err := syscall.Mount(fmt.Sprintf("/proc/self/ns/net"), path, "bind", syscall.MS_BIND, ""); err != nil {
		return nil, err
	}
	return &Namespace{Path: path}, nil
}
func bindMountFile(src, dst string) (*os.File, error) {
	// mount point has to be an existing file
	f, err := os.OpenFile(dst, os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		return nil, err
	}
	f.Close()

	err = unix.Mount(src, dst, "none", unix.MS_BIND, "")
	if err != nil {
		return nil, fmt.Errorf("mount: %s")
	}

	return os.Open(dst)
}
Example #6
0
func MakeNetworkNS(containerID string) string {
	namespace := "/var/run/netns/" + containerID

	err := os.MkdirAll("/var/run/netns", 0600)
	Expect(err).NotTo(HaveOccurred())

	// create an empty file at the mount point
	mountPointFd, err := os.Create(namespace)
	Expect(err).NotTo(HaveOccurred())
	mountPointFd.Close()

	var wg sync.WaitGroup
	wg.Add(1)

	// do namespace work in a dedicated goroutine, so that we can safely
	// Lock/Unlock OSThread without upsetting the lock/unlock state of
	// the caller of this function.  See block comment above.
	go (func() {
		defer wg.Done()

		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		defer GinkgoRecover()

		// capture current thread's original netns
		currentThreadNetNSPath := getCurrentThreadNetNSPath()
		originalNetNS, err := unix.Open(currentThreadNetNSPath, unix.O_RDONLY, 0)
		Expect(err).NotTo(HaveOccurred())
		defer unix.Close(originalNetNS)

		// create a new netns on the current thread
		err = unix.Unshare(unix.CLONE_NEWNET)
		Expect(err).NotTo(HaveOccurred())

		// bind mount the new netns from the current thread onto the mount point
		err = unix.Mount(currentThreadNetNSPath, namespace, "none", unix.MS_BIND, "")
		Expect(err).NotTo(HaveOccurred())

		// reset current thread's netns to the original
		_, _, e1 := unix.Syscall(unix.SYS_SETNS, uintptr(originalNetNS), uintptr(unix.CLONE_NEWNET), 0)
		Expect(e1).To(BeZero())
	})()

	wg.Wait()

	return namespace
}
Example #7
0
func main() {
	// The need for this conversion is not clear to me, but we get an overflow error
	// on ARM without it.
	flags := uintptr(unix.MS_MGC_VAL)
	flag.Parse()
	a := flag.Args()
	if len(a) < 2 {
		log.Fatalf("Usage: mount [-r] [-t fstype] dev path")
	}
	dev := a[0]
	path := a[1]
	if *RO {
		flags |= unix.MS_RDONLY
	}
	if err := unix.Mount(a[0], a[1], *fsType, flags, ""); err != nil {
		log.Fatalf("Mount :%s: on :%s: type :%s: flags %x: %v\n", dev, path, *fsType, flags, err)
	}
}
Example #8
0
// Mount maps an RBD image and mount it on /mnt/ceph/<datastore>/<volume> directory
// FIXME: Figure out how to use rbd locks
func (cv *CephVolume) Mount(fstype string) (*CephMount, error) {
	cd := cv.driver
	// Directory to mount the volume
	dataStoreDir := filepath.Join(cd.mountBase, cv.PoolName)
	volumeDir := filepath.Join(dataStoreDir, cv.VolumeName)

	devName, err := cv.mapImage()
	if err != nil {
		return nil, err
	}

	// Create directory to mount
	if err := os.MkdirAll(cd.mountBase, 0700); err != nil && !os.IsExist(err) {
		return nil, fmt.Errorf("error creating %q directory: %v", cd.mountBase, err)
	}

	if err := os.MkdirAll(volumeDir, 0700); err != nil && !os.IsExist(err) {
		return nil, fmt.Errorf("error creating %q directory: %v", dataStoreDir)
	}

	// Obtain the major and minor node information about the device we're mounting.
	// This is critical for tuning cgroups and obtaining metrics for this device only.
	fi, err := os.Stat(devName)
	if err != nil {
		return nil, fmt.Errorf("Failed to stat rbd device %q: %v", devName, err)
	}

	rdev := fi.Sys().(*syscall.Stat_t).Rdev

	major := rdev >> 8
	minor := rdev & 0xFF

	// Mount the RBD
	if err := unix.Mount(devName, volumeDir, fstype, 0, ""); err != nil && err != unix.EBUSY {
		return nil, fmt.Errorf("Failed to mount RBD dev %q: %v", devName, err.Error())
	}

	return &CephMount{
		DeviceName: devName,
		MountPath:  volumeDir,
		DevMajor:   uint(major),
		DevMinor:   uint(minor),
	}, nil
}
func (m *Mounter) IdempotentlyMount(source, target string) error {
	err := os.MkdirAll(filepath.Dir(target), 0600)
	if err != nil {
		return fmt.Errorf("os.MkdirAll failed: %s", err)
	}

	fd, err := os.Create(target)
	if err != nil {
		return fmt.Errorf("os.Create failed: %s", err)
	}
	defer fd.Close()

	err = unix.Mount(source, target, "none", unix.MS_BIND, "")
	if err != nil {
		return fmt.Errorf("mount failed: %s", err)
	}

	return nil
}
Example #10
0
func makeNetworkNS(containerID string) string {
	namespace := "/var/run/netns/" + containerID
	pid := unix.Getpid()
	tid := unix.Gettid()

	err := os.MkdirAll("/var/run/netns", 0600)
	Expect(err).NotTo(HaveOccurred())

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	go (func() {
		defer GinkgoRecover()

		err = unix.Unshare(unix.CLONE_NEWNET)
		Expect(err).NotTo(HaveOccurred())

		fd, err := os.Create(namespace)
		Expect(err).NotTo(HaveOccurred())
		defer fd.Close()

		err = unix.Mount("/proc/self/ns/net", namespace, "none", unix.MS_BIND, "")
		Expect(err).NotTo(HaveOccurred())
	})()

	Eventually(namespace).Should(BeAnExistingFile())

	fd, err := unix.Open(fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid), unix.O_RDONLY, 0)
	Expect(err).NotTo(HaveOccurred())

	defer unix.Close(fd)

	_, _, e1 := unix.Syscall(unix.SYS_SETNS, uintptr(fd), uintptr(unix.CLONE_NEWNET), 0)
	Expect(e1).To(BeZero())

	return namespace
}
Example #11
0
// Creates a new persistent network namespace and returns an object
// representing that namespace, without switching to it
func NewNS() (NetNS, error) {
	const nsRunDir = "/var/run/netns"

	b := make([]byte, 16)
	_, err := rand.Reader.Read(b)
	if err != nil {
		return nil, fmt.Errorf("failed to generate random netns name: %v", err)
	}

	err = os.MkdirAll(nsRunDir, 0755)
	if err != nil {
		return nil, err
	}

	// create an empty file at the mount point
	nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
	nsPath := path.Join(nsRunDir, nsName)
	mountPointFd, err := os.Create(nsPath)
	if err != nil {
		return nil, err
	}
	mountPointFd.Close()

	// Ensure the mount point is cleaned up on errors; if the namespace
	// was successfully mounted this will have no effect because the file
	// is in-use
	defer os.RemoveAll(nsPath)

	var wg sync.WaitGroup
	wg.Add(1)

	// do namespace work in a dedicated goroutine, so that we can safely
	// Lock/Unlock OSThread without upsetting the lock/unlock state of
	// the caller of this function
	var fd *os.File
	go (func() {
		defer wg.Done()
		runtime.LockOSThread()

		var origNS NetNS
		origNS, err = GetNS(getCurrentThreadNetNSPath())
		if err != nil {
			return
		}
		defer origNS.Close()

		// create a new netns on the current thread
		err = unix.Unshare(unix.CLONE_NEWNET)
		if err != nil {
			return
		}
		defer origNS.Set()

		// bind mount the new netns from the current thread onto the mount point
		err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
		if err != nil {
			return
		}

		fd, err = os.Open(nsPath)
		if err != nil {
			return
		}
	})()
	wg.Wait()

	if err != nil {
		unix.Unmount(nsPath, unix.MNT_DETACH)
		return nil, fmt.Errorf("failed to create namespace: %v", err)
	}

	return &netNS{file: fd, mounted: true}, nil
}