Ejemplo n.º 1
0
func mkdirNormalMasterRun(master *Master, arg string, rep *WorkResponse) {
	rootless := strings.TrimLeft(arg, "/")
	dir, _ := SplitPath(rootless)
	dirAttr := master.fileServer.attributes.Get(dir)
	if dirAttr.Deletion() {
		rep.Stderr = fmt.Sprintf("File not found: /%s", dir)
		rep.Exit = syscall.WaitStatus(1 << 8)
		return
	}

	if !dirAttr.IsDir() {
		rep.Stderr = fmt.Sprintf("Is not a directory: /%s", dir)
		rep.Exit = syscall.WaitStatus(1 << 8)
		return
	}

	chAttr := master.fileServer.attributes.Get(rootless)
	if !chAttr.Deletion() {
		rep.Stderr = fmt.Sprintf("File exists: /%s", rootless)
		rep.Exit = syscall.WaitStatus(1 << 8)
		return
	}
	chAttr = mkdirEntry(rootless)

	fs := attr.FileSet{}

	ct := chAttr.ChangeTime()
	mt := chAttr.ModTime()
	dirAttr.SetTimes(nil, &mt, &ct)
	fs.Files = append(fs.Files, dirAttr, chAttr)
	master.replay(fs)
}
Ejemplo n.º 2
0
// fillReply empties the unionFs and hashes files as needed.  It will
// return the FS back the pool as soon as possible.
func (t *Mirror) fillReply(state *workerFSState) (*attr.FileSet, []string) {
	fsResult := state.fs.reap()
	t.returnFS(state)

	files := make([]*attr.FileAttr, 0, len(fsResult.files))
	wrRoot := strings.TrimLeft(state.fs.fuseFS.writableRoot, "/")
	reapedHashes := map[string]string{}
	for path, v := range fsResult.files {
		f := &attr.FileAttr{
			Path: fastpath.Join(wrRoot, path),
		}

		if v.Attr != nil {
			f.Attr = v.Attr
		}
		f.Link = v.Link
		if !f.Deletion() && f.IsRegular() {
			contentPath := fastpath.Join(wrRoot, v.Original)
			if v.Original != "" && v.Original != contentPath {
				fa := t.rpcFs.attr.Get(contentPath)
				if fa.Hash == "" {
					log.Panicf("Contents for %q disappeared.", contentPath)
				}
				f.Hash = fa.Hash
			}
			if v.Backing != "" {
				h, ok := reapedHashes[v.Backing]
				if !ok {
					var err error

					h, err = t.worker.content.DestructiveSavePath(v.Backing)
					if err != nil || h == "" {
						log.Fatalf("DestructiveSavePath fail %v, %q", err, h)
					}
					reapedHashes[v.Backing] = h
				}
				f.Hash = h
			}
		}
		files = append(files, f)
	}

	fset := attr.FileSet{Files: files}
	fset.Sort()
	err := os.Remove(fsResult.dir)
	if err != nil {
		log.Fatalf("fillReply: Remove failed: %v", err)
	}

	return &fset, fsResult.reads
}
Ejemplo n.º 3
0
func rmMaybeMasterRun(master *Master, req *WorkRequest, rep *WorkResponse) bool {
	g := Getopt(req.Argv[1:], nil, nil, true)

	force := g.HasLong("force") || g.HasShort('f')
	delete(g.Long, "force")
	delete(g.Short, 'f')

	recursive := g.HasLong("recursive") || g.HasShort('r') || g.HasShort('R')
	delete(g.Long, "recursive")
	delete(g.Short, 'R')
	delete(g.Short, 'r')

	if g.HasOptions() {
		return false
	}

	log.Println("Running in master:", req.Summary())
	todo := []string{}
	for _, a := range g.Args {
		if a[0] != '/' {
			a = filepath.Join(req.Dir, a)
		}
		a = strings.TrimLeft(filepath.Clean(a), "/")
		todo = append(todo, a)
	}

	fs := attr.FileSet{}
	msgs := []string{}
	status := 0
	now := time.Now()
	if recursive {
		for _, t := range todo {
			parentDir, _ := SplitPath(t)
			parent := master.attributes.Get(parentDir)
			if parent.Deletion() {
				continue
			}

			parent.SetTimes(nil, &now, &now)
			fs.Files = append(fs.Files, parent)
			for _, n := range recurseNames(master, t) {
				fs.Files = append(fs.Files, &attr.FileAttr{
					Path: n,
				})
			}
		}
	} else {
		for _, p := range todo {
			a := master.fileServer.attributes.GetDir(p)
			switch {
			case a.Deletion():
				if !force {
					msgs = append(msgs, fmt.Sprintf("rm: no such file or directory: %s", p))
					status = 1
				}
			case a.IsDir() && !recursive:
				msgs = append(msgs, fmt.Sprintf("rm: is a directory: %s", p))
				status = 1
			default:
				parentDir, _ := SplitPath(p)
				parentAttr := master.attributes.Get(parentDir)
				parentAttr.SetTimes(nil, &now, &now)
				fs.Files = append(fs.Files, parentAttr, &attr.FileAttr{Path: p})
			}
		}
	}
	master.replay(fs)

	rep.Stderr = strings.Join(msgs, "\n")
	rep.Exit = syscall.WaitStatus(status << 8)
	return true
}