Beispiel #1
0
func (c *Cgroups) Remove(name string) error {
	errCpu := syscall.Rmdir(c.cpuacct + "/" + name)
	errMemory := syscall.Rmdir(c.memory + "/" + name)
	if errCpu != nil && errMemory != nil {
		return errCpu
	}
	return nil
}
Beispiel #2
0
// TestMkdirRmdir creates and deletes a directory
func TestMkdirRmdir(t *testing.T, plainDir string) {
	dir := plainDir + "/dir1"
	err := os.Mkdir(dir, 0777)
	if err != nil {
		t.Error(err)
		return
	}
	err = syscall.Rmdir(dir)
	if err != nil {
		t.Error(err)
		return
	}
	// Removing a non-empty dir should fail with ENOTEMPTY
	if os.Mkdir(dir, 0777) != nil {
		t.Error(err)
		return
	}
	f, err := os.Create(dir + "/file")
	if err != nil {
		t.Error(err)
		return
	}
	f.Close()
	err = syscall.Rmdir(dir)
	errno := err.(syscall.Errno)
	if errno != syscall.ENOTEMPTY {
		t.Errorf("Should have gotten ENOTEMPTY, go %v", errno)
	}
	if syscall.Unlink(dir+"/file") != nil {
		t.Error(err)
		return
	}
	if syscall.Rmdir(dir) != nil {
		t.Error(err)
		return
	}
	// We should also be able to remove a directory we do not have permissions to
	// read or write
	err = os.Mkdir(dir, 0000)
	if err != nil {
		t.Error(err)
		return
	}
	err = syscall.Rmdir(dir)
	if err != nil {
		// Make sure the directory can cleaned up by the next test run
		os.Chmod(dir, 0700)
		t.Error(err)
		return
	}
}
Beispiel #3
0
func (fs *FS) Delete(id string) error {
	//dn := fs.of_id(id)
	a, b, c, d := SplitFN(id)
	an := fs.Prefix + "/" + a
	bn := an + "/" + b
	cn := bn + "/" + c
	dn := cn + "/" + d
	e := os.RemoveAll(dn)
	if e == nil {
		syscall.Rmdir(cn)
		syscall.Rmdir(bn)
		syscall.Rmdir(an)
	}
	return e
}
Beispiel #4
0
func TestWriteFilePermissions(t *testing.T) {
	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	fullPath := path.Join(dir, "tmp", "foo")

	wf := File{
		Path:               fullPath,
		RawFilePermissions: "0755",
	}

	if err := WriteFile(&wf); err != nil {
		t.Fatalf("Processing of WriteFile failed: %v", err)
	}

	fi, err := os.Stat(fullPath)
	if err != nil {
		t.Fatalf("Unable to stat file: %v", err)
	}

	if fi.Mode() != os.FileMode(0755) {
		t.Errorf("File has incorrect mode: %v", fi.Mode())
	}
}
Beispiel #5
0
func (file *File) unlink() error {

	// Remove whatever was there.
	// NOTE: We will generally require the
	// write lock to be held for this routine.

	if file.write_deleted {
		err := cleardelattr(file.write_path)
		if err != nil {
			return err
		}
	}

	var stat syscall.Stat_t
	err := syscall.Lstat(file.write_path, &stat)
	if err == nil {
		if stat.Mode&syscall.S_IFDIR != 0 {
			err = syscall.Rmdir(file.write_path)
			if err != nil {
				return err
			}
		} else {
			err = syscall.Unlink(file.write_path)
			if err != nil {
				return err
			}
		}
	}

	file.write_exists = false
	file.write_deleted = false

	return nil
}
Beispiel #6
0
// Remove removes the named file or directory.
// If there is an error, it will be of type *PathError.
func Remove(name string) error {
	// System call interface forces us to know
	// whether name is a file or directory.
	// Try both: it is cheaper on average than
	// doing a Stat plus the right one.
	e := syscall.Unlink(name)
	if e == nil {
		return nil
	}
	e1 := syscall.Rmdir(name)
	if e1 == nil {
		return nil
	}

	// Both failed: figure out which error to return.
	// OS X and Linux differ on whether unlink(dir)
	// returns EISDIR, so can't use that. However,
	// both agree that rmdir(file) returns ENOTDIR,
	// so we can use that to decide which error is real.
	// Rmdir might also return ENOTDIR if given a bad
	// file path, like /etc/passwd/foo, but in that case,
	// both errors will be ENOTDIR, so it's okay to
	// use the error from unlink.
	if e1 != syscall.ENOTDIR {
		e = e1
	}
	return &PathError{"remove", name, e}
}
Beispiel #7
0
func cmd_rmdir(cmd *Interpreter) (ErrorLevel, error) {
	if len(cmd.Args) <= 1 {
		fmt.Println("Usage: rmdir [/s] DIRECTORIES...")
		return NOERROR, nil
	}
	s_option := false
	message := "%s: Rmdir Are you sure? [Yes/No/Quit] "
	errorcount := ErrorLevel(0)
	for _, arg1 := range cmd.Args[1:] {
		if arg1 == "/s" {
			s_option = true
			message = "%s : Delete Tree. Are you sure? [Yes/No/Quit] "
			continue
		}
		stat, statErr := os.Lstat(arg1)
		if statErr != nil {
			fmt.Fprintf(cmd.Stderr, "%s: %s\n", arg1, statErr)
			errorcount++
			continue
		}
		if !stat.IsDir() {
			fmt.Fprintf(cmd.Stderr, "%s: not directory\n", arg1)
			errorcount++
			continue
		}
		fmt.Fprintf(cmd.Stderr, message, arg1)
		ch := conio.GetCh()
		fmt.Fprintf(cmd.Stderr, "%c ", ch)
		switch ch {
		case 'y', 'Y':

		case 'q', 'Q':
			fmt.Fprintln(cmd.Stderr, "-> canceled all")
			return errorcount, nil
		default:
			fmt.Fprintln(cmd.Stderr, "-> canceled")
			continue
		}
		var err error
		if s_option {
			fmt.Fprintln(cmd.Stdout)
			err = dos.Truncate(arg1, func(path string, err error) bool {
				fmt.Fprintf(cmd.Stderr, "%s -> %s\n", path, err.Error())
				return true
			}, cmd.Stdout)
		} else {
			err = syscall.Rmdir(arg1)
		}
		if err != nil {
			fmt.Fprintf(cmd.Stderr, "-> %s\n", err.Error())
			errorcount++
		} else {
			fmt.Fprintln(cmd.Stderr, "-> done.")
		}
	}
	return errorcount, nil
}
Beispiel #8
0
// Create and delete a directory
func testMkdirRmdir(t *testing.T, plainDir string) {
	dir := plainDir + "dir1"
	err := os.Mkdir(dir, 0777)
	if err != nil {
		t.Fatal(err)
	}
	err = syscall.Rmdir(dir)
	if err != nil {
		t.Fatal(err)
	}

	// Removing a non-empty dir should fail with ENOTEMPTY
	if os.Mkdir(dir, 0777) != nil {
		t.Fatal(err)
	}
	f, err := os.Create(dir + "/file")
	if err != nil {
		t.Fatal(err)
	}
	f.Close()
	err = syscall.Rmdir(dir)
	errno := err.(syscall.Errno)
	if errno != syscall.ENOTEMPTY {
		t.Errorf("Should have gotten ENOTEMPTY, go %v", errno)
	}
	if syscall.Unlink(dir+"/file") != nil {
		t.Fatal(err)
	}
	if syscall.Rmdir(dir) != nil {
		t.Fatal(err)
	}

	// We should also be able to remove a directory we do not have permissions to
	// read or write
	err = os.Mkdir(dir, 0000)
	if err != nil {
		t.Fatal(err)
	}
	err = syscall.Rmdir(dir)
	if err != nil {
		t.Fatal(err)
	}
}
Beispiel #9
0
func (constor *Constor) Rmdir(header *fuse.InHeader, name string) (code fuse.Status) {
	constor.log("%d %s", header.NodeId, name)
	var stat syscall.Stat_t
	parentino := header.NodeId
	dirpath, err := constor.dentrymap.getPath(parentino)
	if err != nil {
		return fuse.ToStatus(err)
	}
	path := Path.Join(dirpath, name)
	if err := constor.Lstat(path, &stat); err != nil {
		return fuse.ToStatus(err)
	}
	li := constor.getLayer(path)
	if li == -1 {
		return fuse.EIO
	}
	pathlayer0 := Path.Join(constor.layers[0], path)

	if li == 0 {
		// FIXME: make sure the dir is not empty
		// err = os.RemoveAll(pathlayer0)
		err = syscall.Rmdir(pathlayer0)
		if err != nil {
			return fuse.ToStatus(err)
		}
		li = constor.getLayer(path)
	}

	if li > 0 {
		err := constor.createPath(dirpath)
		if err != nil {
			return fuse.ToStatus(err)
		}
		fd, err := syscall.Creat(pathlayer0, 0)
		if err != nil {
			return fuse.ToStatus(err)
		}
		syscall.Close(fd)
		err = constor.setdeleted(pathlayer0)
		if err != nil {
			return fuse.ToStatus(err)
		}
	}

	dentry, err := constor.dentrymap.findDentry(parentino, stat.Ino)
	if err != nil {
		return fuse.ToStatus(err)
	}
	constor.dentrymap.unhashDentry(dentry)
	return fuse.OK
}
func TestWriteFileInvalidPermission(t *testing.T) {
	wf := WriteFile{
		Path:        "/tmp/foo",
		Content:     "bar",
		Permissions: "pants",
	}
	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	if err := ProcessWriteFile(dir, &wf); err == nil {
		t.Fatalf("Expected error to be raised when writing file with invalid permission")
	}
}
func TestPlaceNetworkUnit(t *testing.T) {
	u := Unit{
		Name:    "50-eth0.network",
		Runtime: true,
		Content: `[Match]
Name=eth47

[Network]
Address=10.209.171.177/19
`,
	}

	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	if _, err := PlaceUnit(dir, &u); err != nil {
		t.Fatalf("PlaceUnit failed: %v", err)
	}

	fullPath := path.Join(dir, "run", "systemd", "network", "50-eth0.network")
	fi, err := os.Stat(fullPath)
	if err != nil {
		t.Fatalf("Unable to stat file: %v", err)
	}

	if fi.Mode() != os.FileMode(0644) {
		t.Errorf("File has incorrect mode: %v", fi.Mode())
	}

	contents, err := ioutil.ReadFile(fullPath)
	if err != nil {
		t.Fatalf("Unable to read expected file: %v", err)
	}

	expect := `[Match]
Name=eth47

[Network]
Address=10.209.171.177/19
`
	if string(contents) != expect {
		t.Fatalf("File has incorrect contents '%s'.\nExpected '%s'", string(contents), expect)
	}
}
Beispiel #12
0
func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) {
	if fs.isFiltered(relPath) {
		return fuse.EPERM
	}
	encPath, err := fs.getBackingPath(relPath)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if !fs.args.DirIV {
		return fuse.ToStatus(os.Mkdir(encPath, os.FileMode(mode)))
	}

	// We need write and execute permissions to create gocryptfs.diriv
	origMode := mode
	mode = mode | 0300

	// The new directory may take the place of an older one that is still in the cache
	fs.CryptFS.DirIVCacheEnc.Clear()
	// Create directory
	fs.dirIVLock.Lock()
	defer fs.dirIVLock.Unlock()
	err = os.Mkdir(encPath, os.FileMode(mode))
	if err != nil {
		return fuse.ToStatus(err)
	}
	// Create gocryptfs.diriv inside
	err = cryptfs.WriteDirIV(encPath)
	if err != nil {
		// This should not happen
		cryptfs.Warn.Printf("Mkdir: WriteDirIV failed: %v", err)
		err2 := syscall.Rmdir(encPath)
		if err2 != nil {
			cryptfs.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2)
		}
		return fuse.ToStatus(err)
	}

	// Set permissions back to what the user wanted
	if origMode != mode {
		err = os.Chmod(encPath, os.FileMode(origMode))
		if err != nil {
			cryptfs.Warn.Printf("Mkdir: Chmod failed: %v", err)
		}
	}

	return fuse.OK
}
func TestWriteFileEncodedContent(t *testing.T) {
	wf := WriteFile{
		Path:     "/tmp/foo",
		Content:  "",
		Encoding: "base64",
	}

	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	if err := ProcessWriteFile(dir, &wf); err == nil {
		t.Fatalf("Expected error to be raised when writing file with encoding")
	}
}
Beispiel #14
0
func TestWriteFileInvalidPermission(t *testing.T) {
	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	wf := File{
		Path:               path.Join(dir, "tmp", "foo"),
		Content:            "bar",
		RawFilePermissions: "pants",
	}

	if err := WriteFile(&wf); err == nil {
		t.Fatalf("Expected error to be raised when writing file with invalid permission")
	}
}
Beispiel #15
0
func cmd_rmdir(cmd *interpreter.Interpreter) (interpreter.NextT, error) {
	if len(cmd.Args) <= 1 {
		fmt.Println("Usage: rmdir [/s] DIRECTORIES...")
		return interpreter.CONTINUE, nil
	}
	s_option := false
	message := "%s: Rmdir Are you sure? [Yes/No/Quit] "
	for _, arg1 := range cmd.Args[1:] {
		if arg1 == "/s" {
			s_option = true
			message = "%s : Delete Tree. Are you sure? [Yes/No/Quit] "
			continue
		}
		fmt.Fprintf(cmd.Stderr, message, arg1)
		ch := conio.GetCh()
		fmt.Fprintf(cmd.Stderr, "%c ", ch)
		switch ch {
		case 'y', 'Y':

		case 'q', 'Q':
			fmt.Fprintln(cmd.Stderr, "-> canceled all")
			return interpreter.CONTINUE, nil
		default:
			fmt.Fprintln(cmd.Stderr, "-> canceled")
			continue
		}
		var err error
		if s_option {
			fmt.Fprintln(cmd.Stdout)
			err = dos.Truncate(arg1, func(path string, err error) bool {
				fmt.Fprintf(cmd.Stderr, "%s -> %s\n", path, err.Error())
				return true
			}, cmd.Stdout)
		} else {
			err = syscall.Rmdir(arg1)
		}
		if err != nil {
			fmt.Fprintf(cmd.Stderr, "-> %s\n", err.Error())
		} else {
			fmt.Fprintln(cmd.Stderr, "-> done.")
		}
	}
	return interpreter.CONTINUE, nil
}
func TestPlaceMountUnit(t *testing.T) {
	u := Unit{
		Name:    "media-state.mount",
		Runtime: false,
		Content: `[Mount]
What=/dev/sdb1
Where=/media/state
`,
	}

	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	if _, err := PlaceUnit(dir, &u); err != nil {
		t.Fatalf("PlaceUnit failed: %v", err)
	}

	fullPath := path.Join(dir, "etc", "systemd", "system", "media-state.mount")
	fi, err := os.Stat(fullPath)
	if err != nil {
		t.Fatalf("Unable to stat file: %v", err)
	}

	if fi.Mode() != os.FileMode(0644) {
		t.Errorf("File has incorrect mode: %v", fi.Mode())
	}

	contents, err := ioutil.ReadFile(fullPath)
	if err != nil {
		t.Fatalf("Unable to read expected file: %v", err)
	}

	expect := `[Mount]
What=/dev/sdb1
Where=/media/state
`
	if string(contents) != expect {
		t.Fatalf("File has incorrect contents '%s'.\nExpected '%s'", string(contents), expect)
	}
}
Beispiel #17
0
func Truncate(folder string, whenError func(string, error) bool, out io.Writer) error {
	attr, attrErr := GetFileAttributes(folder)
	if attrErr != nil {
		return fmt.Errorf("%s: %s", folder, attrErr)
	}
	if (attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0 {
		// Only not junction, delete files under folder.
		fd, fdErr := os.Open(folder)
		if fdErr != nil {
			return fdErr
		}
		fi, fiErr := fd.Readdir(-1)
		fd.Close()
		if fiErr != nil {
			return fiErr
		}
		for _, f := range fi {
			if f.Name() == "." || f.Name() == ".." {
				continue
			}
			fullpath := Join(folder, f.Name())
			var err error
			if f.IsDir() {
				fmt.Fprintf(out, "%s\\\n", fullpath)
				err = Truncate(fullpath, whenError, out)
			} else {
				fmt.Fprintln(out, fullpath)
				SetFileAttributes(fullpath, FILE_ATTRIBUTE_NORMAL)
				err = syscall.Unlink(fullpath)
			}
			if err != nil {
				if whenError != nil && !whenError(fullpath, err) {
					return fmt.Errorf("%s: %s", fullpath, err.Error())
				}
			}
		}
	}
	if err := syscall.Rmdir(folder); err != nil {
		return fmt.Errorf("%s: %s", folder, err.Error())
	}
	return nil
}
Beispiel #18
0
func compile(prog parse.Program, outfile string) int {
	tempdir, err := ioutil.TempDir("/tmp", "jikken")
	if err != nil {
		log.Println("could not create temporary directory:", err)
		return 1
	}
	defer func() {
		_ = syscall.Rmdir(tempdir)
	}()

	llfile := tempdir + "/jikken.ll"
	if err = ioutil.WriteFile(llfile, llcode(prog), 0644); err != nil {
		log.Println("could not write temporary file:", err)
		return 1
	}
	defer func() {
		_ = syscall.Unlink(llfile)
	}()

	sfile := tempdir + "/jikken.s"
	defer func() {
		_ = syscall.Unlink(sfile)
	}()
	llc := exec.Command("llc", llfile)
	llc.Stdout = os.Stdout
	llc.Stderr = os.Stderr
	if err = llc.Run(); err != nil {
		log.Println("llc failed:", err)
		return 1
	}

	gcc := exec.Command("gcc", "-o", outfile, sfile)
	gcc.Stdout = os.Stdout
	gcc.Stderr = os.Stderr
	if err = gcc.Run(); err != nil {
		log.Println("gcc failed:", err)
		return 1
	}

	return 0
}
Beispiel #19
0
func TestDetectRemote_NotFound(t *testing.T) {
	dir, err := ioutil.TempDir("", "")
	if err != nil {
		t.Error("failed to create tempdir:", err)
	}
	defer syscall.Rmdir(dir)

	remotes, err := DetectRemote(dir + "/not_found")

	if remotes != nil {
		t.Error("unexpected result:", remotes)
	}
	if err == nil {
		t.Error("error should be set")
	}

	re := regexp.MustCompile(`^chdir `)
	if re.MatchString(err.Error()) == false {
		t.Error("unexpected error", err)
	}
}
Beispiel #20
0
func (fs *FS) mkdirWithIv(cPath string, mode uint32) error {
	// Between the creation of the directory and the creation of gocryptfs.diriv
	// the directory is inconsistent. Take the lock to prevent other readers
	// from seeing it.
	fs.dirIVLock.Lock()
	// The new directory may take the place of an older one that is still in the cache
	fs.nameTransform.DirIVCache.Clear()
	defer fs.dirIVLock.Unlock()
	err := os.Mkdir(cPath, os.FileMode(mode))
	if err != nil {
		return err
	}
	// Create gocryptfs.diriv
	err = nametransform.WriteDirIV(cPath)
	if err != nil {
		err2 := syscall.Rmdir(cPath)
		if err2 != nil {
			tlog.Warn.Printf("mkdirWithIv: rollback failed: %v", err2)
		}
	}
	return err
}
Beispiel #21
0
func TestWriteFileUnencodedContent(t *testing.T) {
	dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
	if err != nil {
		t.Fatalf("Unable to create tempdir: %v", err)
	}
	defer syscall.Rmdir(dir)

	fullPath := path.Join(dir, "tmp", "foo")

	wf := File{
		Path:               fullPath,
		Content:            "bar",
		RawFilePermissions: "0644",
	}

	if err := WriteFile(&wf); err != nil {
		t.Fatalf("Processing of WriteFile failed: %v", err)
	}

	fi, err := os.Stat(fullPath)
	if err != nil {
		t.Fatalf("Unable to stat file: %v", err)
	}

	if fi.Mode() != os.FileMode(0644) {
		t.Errorf("File has incorrect mode: %v", fi.Mode())
	}

	contents, err := ioutil.ReadFile(fullPath)
	if err != nil {
		t.Fatalf("Unable to read expected file: %v", err)
	}

	if string(contents) != "bar" {
		t.Fatalf("File has incorrect contents")
	}
}
Beispiel #22
0
//   - [email protected]:username/repo.git
func TestDetectRemoteForBitBucket(t *testing.T) {
	dir, err := ioutil.TempDir("", "")
	if err != nil {
		t.Error("failed to create tempdir:", err)
	}
	defer syscall.Rmdir(dir)

	git := exec.Command("git", "init")
	git.Dir = dir
	if err := git.Run(); err != nil {
		t.Error("failed to run git init:", err)
	}

	git = exec.Command("git", "remote", "add", "origin", "[email protected]:username/repo.git")
	git.Dir = dir
	if err := git.Run(); err != nil {
		t.Error("failed to run git remote add :", err)
	}

	remotes, err := DetectRemote(dir)

	if err != nil {
		t.Error("error should be nil:", err)
	}

	if len(remotes) < 1 {
		t.Error("unexpected remotes count")
	}

	if remotes[0].Name != "origin" {
		t.Error("unexpected remote name", remotes[0].Name)
	}
	if remotes[0].Url != "[email protected]:username/repo.git" {
		t.Error("unexpected remote url", remotes[0].Url)
	}
}
Beispiel #23
0
func (constor *Constor) Rename(input *fuse.RenameIn, oldName string, newName string) (code fuse.Status) {
	sendEntryNotify := false
	var inodedel *Inode
	oldParent := constor.inodemap.findInodePtr(input.NodeId)
	if oldParent == nil {
		constor.error("oldParent == nil")
		return fuse.ENOENT
	}
	newParent := constor.inodemap.findInodePtr(input.Newdir)
	if newParent == nil {
		constor.error("newParent == nil")
		return fuse.ENOENT
	}
	if err := constor.copyup(newParent); err != nil {
		constor.error("copyup failed for %s - %s", newParent.id, err)
		return fuse.EIO
	}
	newParentPath := constor.getPath(0, newParent.id)
	newentrypath := Path.Join(newParentPath, newName)
	constor.log("%s %s %s %s", oldParent.id, oldName, newParent.id, newName)
	// remove any entry that existed in the newName's place
	if iddel, err := constor.getid(-1, newParent.id, newName); err == nil {
		if inodedel = constor.inodemap.findInodeId(iddel); inodedel != nil {
			if inodedel.layer == 0 {
				linkcnt, err := constor.declinkscnt(inodedel.id)
				if err != nil {
					constor.error("declinkscnt %s : %s", inodedel.id, err)
					return fuse.ToStatus(err)
				}
				if linkcnt == 0 {
					path := constor.getPath(0, iddel)
					fi, err := os.Lstat(path)
					if err != nil {
						constor.error("Lstat failed on %s", path)
						return fuse.ToStatus(err)
					}
					if fi.IsDir() {
						// FIXME: take care of this situation
						constor.error("path is a directory")
						return fuse.Status(syscall.EEXIST)
					}
					if err := syscall.Unlink(path); err != nil {
						constor.error("Unable to remove %s", path)
						return fuse.ToStatus(err)
					}
					inodedel.layer = -1
				}
			}
			stat := syscall.Stat_t{}
			// FIXME do copyup and declinkscnt
			if err := syscall.Lstat(newentrypath, &stat); err == nil {
				fi, err := os.Lstat(newentrypath)
				if err != nil {
					constor.error("Lstat failed on %s", newentrypath)
					return fuse.ToStatus(err)
				}
				if fi.IsDir() {
					// FIXME: take care of this situation
					constor.error("path is a directory")
					return fuse.Status(syscall.EEXIST)
				}
				if err := syscall.Unlink(newentrypath); err != nil {
					constor.error("Unable to remove %s", newentrypath)
					return fuse.ToStatus(err)
				}
			}
			// inodedel.parentPtr = input.Newdir
			// inodedel.name = newName
			sendEntryNotify = true
			// constor.ms.DeleteNotify(input.Newdir, uint64(uintptr(unsafe.Pointer(inodedel))), newName)
			// constor.ms.EntryNotify(input.Newdir, newName)
		} else {
			constor.error("inodedel == nil for %s %s", newParent.id, newName)
			return fuse.EIO
		}
	}
	// remove any deleted placeholder
	if constor.isdeleted(newentrypath, nil) {
		if err := syscall.Unlink(newentrypath); err != nil {
			constor.error("Unlink %s : %s", newentrypath, err)
			return fuse.ToStatus(err)
		}
	}
	oldid, err := constor.getid(-1, oldParent.id, oldName)
	if err != nil {
		constor.error("getid error %s %s", oldParent.id, oldName)
		return fuse.ToStatus(err)
	}
	oldinode := constor.inodemap.findInodeId(oldid)
	if oldinode == nil {
		constor.error("oldinode == nil for %s", oldid)
		return fuse.ENOENT
	}
	path := constor.getPath(oldinode.layer, oldid)
	fi, err := os.Lstat(path)
	if err != nil {
		constor.error("Lstat %s", path)
		return fuse.ToStatus(err)
	}
	oldParentPath := constor.getPath(0, oldParent.id)
	oldentrypath := Path.Join(oldParentPath, oldName)
	oldstat := syscall.Stat_t{}
	if err := syscall.Lstat(oldentrypath, &oldstat); err == nil {
		if fi.IsDir() {
			if err := syscall.Rmdir(oldentrypath); err != nil {
				constor.error("Rmdir %s : %s", oldentrypath, err)
				return fuse.ToStatus(err)
			}
		} else {
			if err := syscall.Unlink(oldentrypath); err != nil {
				constor.error("Unlink %s : %s", oldentrypath, err)
				return fuse.ToStatus(err)
			}
		}
	}
	if _, err := constor.getid(-1, oldParent.id, oldName); err == nil {
		constor.setdeleted(oldentrypath)
	}
	if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
		err = os.Symlink("placeholder", newentrypath)
		if err != nil {
			constor.error("Symlink %s : %s", newentrypath, err)
			return fuse.ToStatus(err)
		}
	} else if fi.Mode()&os.ModeDir == os.ModeDir {
		err := os.Mkdir(newentrypath, fi.Mode())
		if err != nil {
			constor.error("Mkdir %s : %s", newentrypath, err)
			return fuse.ToStatus(err)
		}
	} else {
		fd, err := syscall.Creat(newentrypath, uint32(fi.Mode()))
		if err != nil {
			constor.error("create %s : %s", newentrypath, err)
			return fuse.ToStatus(err)
		}
		syscall.Close(fd)
	}
	id := constor.setid(newentrypath, oldid)
	if id == "" {
		constor.error("setid %s : %s", newentrypath, err)
		return fuse.EIO
	}
	if sendEntryNotify {
		go func() {
			// FIXME: is this needed?
			constor.ms.DeleteNotify(input.Newdir, uint64(uintptr(unsafe.Pointer(inodedel))), newName)
			constor.ms.DeleteNotify(input.NodeId, uint64(uintptr(unsafe.Pointer(oldinode))), oldName)
		}()
	}
	return fuse.OK
}
Beispiel #24
0
func (fs *KakigooriFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
	fullPath := fs.GetPath(name)
	go event.Notify(event.Rmdir, fullPath)
	return fuse.ToStatus(syscall.Rmdir(fullPath))
}
Beispiel #25
0
// This test is inspired on xfstest, t_dir_offset2.c
func TestReaddirPlusSeek(t *testing.T) {
	tc := NewTestCase(t)
	defer tc.Cleanup()

	var names []string
	for i := 0; i < 20; i++ {
		names = append(names, fmt.Sprintf("abcd%d", i))
	}

	for _, n := range names {
		if err := os.MkdirAll(filepath.Join(tc.origSubdir, n), 0755); err != nil {
			t.Fatalf("Mkdir failed: %v", err)
		}
	}

	fd, err := syscall.Open(tc.mountSubdir, syscall.O_RDONLY, 0755)
	if err != nil {
		t.Fatalf("Open(%q): %v", tc.mountSubdir, err)
	}
	defer syscall.Close(int(fd))

	// store offsets
	type entryOff struct {
		ino uint64
		off int64
	}
	previous := map[int]entryOff{}
	var bufdata [1024]byte
	for {
		buf := bufdata[:]
		n, err := syscall.ReadDirent(fd, buf)
		if err != nil {
			t.Fatalf("ReadDirent: %v", err)
		}
		if n == 0 {
			break
		}

		buf = buf[:n]
		for _, d := range parseDirents(buf) {
			if d.name == "." || d.name == ".." {
				continue
			}
			i := len(previous)
			previous[i] = entryOff{d.ino, d.off}
		}
	}

	for i := len(previous) - 1; i >= 0; i-- {
		var off int64
		if i > 0 {
			off = previous[i-1].off
		}

		if _, err := syscall.Seek(fd, off, 0); err != nil {
			t.Fatalf("Seek %v", err)
		}

		buf := bufdata[:]
		n, err := syscall.ReadDirent(fd, buf)
		if err != nil {
			t.Fatalf("readdir after seek %d: %v", i, err)
		}
		if n == 0 {
			t.Fatalf("no dirent after seek to %d", i)
		}

		ds := parseDirents(buf[:n])
		if ds[0].ino != previous[i].ino {
			t.Errorf("got ino %d, want %d", ds[0].ino, previous[i].ino)
		}
	}

	// Delete has a forget as side-effect: make sure we get the lookup counts correct.
	for _, n := range names {
		full := filepath.Join(tc.mountSubdir, n)
		if err := syscall.Rmdir(full); err != nil {
			t.Fatalf("Rmdir(%q): %v", n, err)
		}
	}
}
Beispiel #26
0
func (fs *LoopbackFileSystem) Rmdir(name string, context *Context) (code Status) {
	return ToStatus(syscall.Rmdir(fs.GetPath(name)))
}
Beispiel #27
0
func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
	encPath, err := fs.getBackingPath(name)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if !fs.args.DirIV {
		return fuse.ToStatus(syscall.Rmdir(encPath))
	}

	// If the directory is not empty besides gocryptfs.diriv, do not even
	// attempt the dance around gocryptfs.diriv.
	fd, err := os.Open(encPath)
	if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES {
		// We need permission to read and modify the directory
		cryptfs.Debug.Printf("Rmdir: handling EACCESS")
		fi, err2 := os.Stat(encPath)
		if err2 != nil {
			cryptfs.Debug.Printf("Rmdir: Stat: %v", err2)
			return fuse.ToStatus(err2)
		}
		origMode := fi.Mode()
		newMode := origMode | 0700
		err2 = os.Chmod(encPath, newMode)
		if err2 != nil {
			cryptfs.Debug.Printf("Rmdir: Chmod failed: %v", err2)
			return fuse.ToStatus(err)
		}
		defer func() {
			if code != fuse.OK {
				// Undo the chmod if removing the directory failed
				err3 := os.Chmod(encPath, origMode)
				if err3 != nil {
					cryptfs.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2)
				}
			}
		}()
		// Retry open
		fd, err = os.Open(encPath)
	}
	if err != nil {
		cryptfs.Debug.Printf("Rmdir: Open: %v", err)
		return fuse.ToStatus(err)
	}
	list, err := fd.Readdirnames(10)
	fd.Close()
	if err != nil {
		cryptfs.Debug.Printf("Rmdir: Readdirnames: %v", err)
		return fuse.ToStatus(err)
	}
	if len(list) > 1 {
		return fuse.ToStatus(syscall.ENOTEMPTY)
	} else if len(list) == 0 {
		cryptfs.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion")
		return fuse.ToStatus(syscall.Rmdir(encPath))
	}

	// Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ"
	dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME)
	parentDir := filepath.Dir(encPath)
	tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptfs.RandUint64())
	tmpDirivPath := filepath.Join(parentDir, tmpName)
	cryptfs.Debug.Printf("Rmdir: Renaming %s to %s", cryptfs.DIRIV_FILENAME, tmpDirivPath)
	// The directory is in an inconsistent state between rename and rmdir. Protect against
	// concurrent readers.
	fs.dirIVLock.Lock()
	defer fs.dirIVLock.Unlock()
	err = os.Rename(dirivPath, tmpDirivPath)
	if err != nil {
		cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
		return fuse.ToStatus(err)
	}
	// Actual Rmdir
	err = syscall.Rmdir(encPath)
	if err != nil {
		// This can happen if another file in the directory was created in the
		// meantime, undo the rename
		err2 := os.Rename(tmpDirivPath, dirivPath)
		if err2 != nil {
			cryptfs.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
		}
		return fuse.ToStatus(err)
	}
	// Delete "gocryptfs.diriv.rmdir.INODENUMBER"
	err = syscall.Unlink(tmpDirivPath)
	if err != nil {
		cryptfs.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
	}
	// The now-deleted directory may have been in the DirIV cache. Clear it.
	fs.CryptFS.DirIVCacheEnc.Clear()
	return fuse.OK
}
Beispiel #28
0
func (me *LoopbackFileSystem) Rmdir(name string) (code Status) {
	return Status(syscall.Rmdir(me.GetPath(name)))
}
Beispiel #29
0
func (fs *loopbackFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
	return fuse.ToStatus(syscall.Rmdir(fs.GetPath(name)))
}
Beispiel #30
0
// Rmdir implements pathfs.FileSystem
func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
	cPath, err := fs.getBackingPath(path)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if fs.args.PlaintextNames {
		err = syscall.Rmdir(cPath)
		return fuse.ToStatus(err)
	}
	parentDir := filepath.Dir(cPath)
	parentDirFd, err := os.Open(parentDir)
	if err != nil {
		return fuse.ToStatus(err)
	}
	defer parentDirFd.Close()

	cName := filepath.Base(cPath)
	dirfdRaw, err := syscallcompat.Openat(int(parentDirFd.Fd()), cName,
		syscall.O_RDONLY, 0)
	if err == syscall.EACCES {
		// We need permission to read and modify the directory
		tlog.Debug.Printf("Rmdir: handling EACCESS")
		// TODO use syscall.Fstatat once it is available in Go
		var fi os.FileInfo
		fi, err = os.Lstat(cPath)
		if err != nil {
			tlog.Debug.Printf("Rmdir: Stat: %v", err)
			return fuse.ToStatus(err)
		}
		origMode := fi.Mode()
		// TODO use syscall.Chmodat once it is available in Go
		err = os.Chmod(cPath, origMode|0700)
		if err != nil {
			tlog.Debug.Printf("Rmdir: Chmod failed: %v", err)
			return fuse.ToStatus(err)
		}
		// Retry open
		var st syscall.Stat_t
		syscall.Lstat(cPath, &st)
		dirfdRaw, err = syscallcompat.Openat(int(parentDirFd.Fd()), cName,
			syscall.O_RDONLY, 0)
		// Undo the chmod if removing the directory failed
		defer func() {
			if code != fuse.OK {
				err = os.Chmod(cPath, origMode)
				if err != nil {
					tlog.Warn.Printf("Rmdir: Chmod rollback failed: %v", err)
				}
			}
		}()
	}
	if err != nil {
		tlog.Debug.Printf("Rmdir: Open: %v", err)
		return fuse.ToStatus(err)
	}
	dirfd := os.NewFile(uintptr(dirfdRaw), cName)
	defer dirfd.Close()

	children, err := dirfd.Readdirnames(10)
	if err == nil {
		// If the directory is not empty besides gocryptfs.diriv, do not even
		// attempt the dance around gocryptfs.diriv.
		if len(children) > 1 {
			return fuse.ToStatus(syscall.ENOTEMPTY)
		}
		// Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ"
		tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptocore.RandUint64())
		tlog.Debug.Printf("Rmdir: Renaming %s to %s", nametransform.DirIVFilename, tmpName)
		// The directory is in an inconsistent state between rename and rmdir.
		// Protect against concurrent readers.
		fs.dirIVLock.Lock()
		defer fs.dirIVLock.Unlock()
		err = syscallcompat.Renameat(int(dirfd.Fd()), nametransform.DirIVFilename,
			int(parentDirFd.Fd()), tmpName)
		if err != nil {
			tlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v",
				nametransform.DirIVFilename, tmpName, err)
			return fuse.ToStatus(err)
		}
		// Actual Rmdir
		// TODO Use syscall.Unlinkat with the AT_REMOVEDIR flag once it is available
		// in Go
		err = syscall.Rmdir(cPath)
		if err != nil {
			// This can happen if another file in the directory was created in the
			// meantime, undo the rename
			err2 := syscallcompat.Renameat(int(parentDirFd.Fd()), tmpName,
				int(dirfd.Fd()), nametransform.DirIVFilename)
			if err != nil {
				tlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
			}
			return fuse.ToStatus(err)
		}
		// Delete "gocryptfs.diriv.rmdir.XYZ"
		err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName)
		if err != nil {
			tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
		}
	} else if err == io.EOF {
		// The directory is empty
		tlog.Warn.Printf("Rmdir: %q: gocryptfs.diriv is missing", cPath)
		err = syscall.Rmdir(cPath)
		if err != nil {
			return fuse.ToStatus(err)
		}
	} else {
		tlog.Warn.Printf("Rmdir: Readdirnames: %v", err)
		return fuse.ToStatus(err)
	}
	// Delete .name file
	if nametransform.IsLongContent(cName) {
		nametransform.DeleteLongName(parentDirFd, cName)
	}
	// The now-deleted directory may have been in the DirIV cache. Clear it.
	fs.nameTransform.DirIVCache.Clear()
	return fuse.OK
}