// 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 }
// 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 }
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 }
// 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())
// 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 }
func RemoveNetworkNS(networkNS string) error { err := unix.Unmount(networkNS, unix.MNT_DETACH) err = os.RemoveAll(networkNS) return err }
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) }
func unmount(target string, flag int) error { err := unix.Unmount(target, flag) return err }