// Delete physically removes namespace if it is possible
func (n *Namespace) Delete() error {
	runtime.LockOSThread()
	if err := syscall.Unmount(n.Path, syscall.MNT_DETACH); err != nil {
		return err
	}
	return os.Remove(n.Path)
}
func (m *Mounter) RemoveMount(target string) error {
	err := unix.Unmount(target, unix.MNT_DETACH)
	if err != nil {
		return fmt.Errorf("unmount failed: %s", err)
	}

	err = os.RemoveAll(target)
	if err != nil {
		return fmt.Errorf("removeall failed: %s", err) // not tested
	}

	return nil
}
Beispiel #3
0
// Unmount a volume.
func (c *Driver) Unmount(do storage.DriverOptions) error {
	poolName := do.Volume.Params["pool"]
	intName, err := c.internalName(do.Volume.Name)
	if err != nil {
		return err
	}

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

	// Unmount the RBD
	var retries int
	var lastErr error

retry:
	if retries < 3 {
		if err := unix.Unmount(volumeDir, 0); err != nil && err != unix.ENOENT && err != unix.EINVAL {
			lastErr = errored.Errorf("Failed to unmount %q (retrying): %v", volumeDir, err)
			logrus.Error(lastErr)
			retries++
			time.Sleep(100 * time.Millisecond)
			goto retry
		}
	} else {
		return errored.Errorf("Failed to umount after 3 retries").Combine(lastErr.(*errored.Error))
	}

	// Remove the mounted directory
	// FIXME remove all, but only after the FIXME above.
	if err := os.Remove(volumeDir); err != nil && !os.IsNotExist(err) {
		logrus.Error(errored.Errorf("error removing %q directory: %v", volumeDir, err))
		goto retry
	}

	if err := c.unmapImage(do); err != os.ErrNotExist {
		return err
	}

	return nil
}
Beispiel #4
0
func (ns *netNS) Close() error {
	if err := ns.errorIfClosed(); err != nil {
		return err
	}

	if err := ns.file.Close(); err != nil {
		return fmt.Errorf("Failed to close %q: %v", ns.file.Name(), err)
	}
	ns.closed = true

	if ns.mounted {
		if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
			return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err)
		}
		if err := os.RemoveAll(ns.file.Name()); err != nil {
			return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
		}
		ns.mounted = false
	}

	return nil
}
Beispiel #5
0
// Unmount unmounts a Ceph volume, remove the mount directory and unmap
// the RBD device
func (cv *CephVolume) Unmount() error {
	cd := cv.driver

	// formatted image name
	// Directory to mount the volume
	dataStoreDir := filepath.Join(cd.mountBase, cv.PoolName)
	volumeDir := filepath.Join(dataStoreDir, cv.VolumeName)

	// Unmount the RBD
	//
	// MNT_DETACH will make this mountpoint unavailable to new open file requests (at
	// least until it is remounted) but persist for existing open requests. This
	// seems to work well with containers.
	//
	// The checks for ENOENT and EBUSY below are safeguards to prevent error
	// modes where multiple containers will be affecting a single volume.
	// FIXME loop over unmount and ensure the unmount finished before removing dir
	if err := unix.Unmount(volumeDir, unix.MNT_DETACH); err != nil && err != unix.ENOENT {
		return fmt.Errorf("Failed to unmount %q: %v", volumeDir, err)
	}

	// Remove the mounted directory
	// FIXME remove all, but only after the FIXME above.
	if err := os.Remove(volumeDir); err != nil && !os.IsNotExist(err) {
		if err, ok := err.(*os.PathError); ok && err.Err == unix.EBUSY {
			return nil
		}

		return fmt.Errorf("error removing %q directory: %v", volumeDir, err)
	}

	if err := cv.unmapImage(); err != os.ErrNotExist {
		return err
	}

	return nil
}
func unlinkNetworkNamespace(path string) error {
	if err := unix.Unmount(path, unix.MNT_DETACH); err != nil {
		return err
	}
	return os.Remove(path)
}
func detachMounted(path string) error {
	//Solaris and FreeBSD do not support the lazy unmount or MNT_DETACH feature.
	// Therefore there are separate definitions for this.
	return unix.Unmount(path, 0)
}
	Describe("Create", func() {
		var repo namespace.Repository

		BeforeEach(func() {
			var err error
			repo, err = namespace.NewRepository(repoDir)
			Expect(err).NotTo(HaveOccurred())
		})

		It("creates a namespace in the repository", func() {
			ns, err := repo.Create("test-ns")
			Expect(err).NotTo(HaveOccurred())
			Expect(ns.Name()).To(Equal("test-ns"))

			nsPath := filepath.Join(repoDir, "test-ns")
			defer unix.Unmount(nsPath, unix.MNT_DETACH)

			var repoStat unix.Stat_t
			err = unix.Stat(nsPath, &repoStat)
			Expect(err).NotTo(HaveOccurred())

			var namespaceInode string
			callback := func(_ *os.File) error {
				// Stat of "/proc/self/ns/net" seemed to be flakey
				output, err := exec.Command("stat", "-L", "-c", "%i", "/proc/self/ns/net").CombinedOutput()
				namespaceInode = strings.TrimSpace(string(output))
				return err
			}

			err = ns.Execute(callback)
			Expect(err).NotTo(HaveOccurred())
Beispiel #9
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
}
Beispiel #10
0
func RemoveNetworkNS(networkNS string) error {
	err := unix.Unmount(networkNS, unix.MNT_DETACH)

	err = os.RemoveAll(networkNS)
	return err
}
Beispiel #11
0
func detachMounted(path string) error {
	return unix.Unmount(path, unix.MNT_DETACH)
}
func unlinkNetworkNamespace(path string) error {
	if err := unix.Unmount(path, unix.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount: %s", err)
	}
	return os.Remove(path)
}
Beispiel #13
0
func unmount(target string, flag int) error {
	err := unix.Unmount(target, flag)
	return err
}