Beispiel #1
0
func (constor *Constor) Create(input *fuse.CreateIn, name string, out *fuse.CreateOut) (code fuse.Status) {
	dirpath, err := constor.dentrymap.getPath(input.NodeId)
	if err != nil {
		constor.error("%s", err)
		return fuse.ToStatus(err)
	}
	constor.log("%s%s %d %d %d", dirpath, name, input.Mode, input.Uid, input.Gid)
	if err := constor.createPath(dirpath); err != nil {
		constor.error("%s", err)
		return fuse.ToStatus(err)
	}
	pathl := Path.Join(constor.layers[0], dirpath, name)
	// remove any deleted place holder entries
	if constor.isdeleted(pathl) {
		syscall.Unlink(pathl)
	}
	fd, err := syscall.Open(pathl, syscall.O_CREAT|syscall.O_RDWR, input.Mode)
	if err != nil {
		constor.error("%s", err)
		return fuse.ToStatus(err)
	}

	err = syscall.Chown(pathl, int(input.Uid), int(input.Gid))
	if err != nil {
		constor.error("%s", err)
		return fuse.ToStatus(err)
	}
	F := new(FD)
	F.fd = fd
	F.layer = 0
	constor.putfd(F)
	out.Fh = uint64(uintptr(unsafe.Pointer(F)))
	constor.log("%d", out.Fh)
	return constor.Lookup((*fuse.InHeader)(unsafe.Pointer(input)), name, &out.EntryOut)
}
Beispiel #2
0
// Creates the device node in the rootfs of the container.
func createDeviceNode(rootfs string, node *configs.Device) error {
	var (
		dest   = filepath.Join(rootfs, node.Path)
		parent = filepath.Dir(dest)
	)

	if err := os.MkdirAll(parent, 0755); err != nil {
		return err
	}

	fileMode := node.FileMode
	switch node.Type {
	case 'c':
		fileMode |= syscall.S_IFCHR
	case 'b':
		fileMode |= syscall.S_IFBLK
	default:
		return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
	}

	if err := syscall.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil && !os.IsExist(err) {
		return fmt.Errorf("mknod %s %s", node.Path, err)
	}

	if err := syscall.Chown(dest, int(node.Uid), int(node.Gid)); err != nil {
		return fmt.Errorf("chown %s to %d:%d", node.Path, node.Uid, node.Gid)
	}

	return nil
}
Beispiel #3
0
func main() {

	socket := "/home/vagrant/dev/src/github.com/r-fujiwara/goroutine-fcgi/go-home.sock"
	userid := 33
	groupid := 33

	_ = syscall.Umask(0177)

	l, err := net.Listen("unix", socket)

	_ = syscall.Chown(socket, userid, groupid)

	defer l.Close()

	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			log.Printf("Captured: %v", sig)
			l.Close()
		}
	}()

	mux := http.NewServeMux()
	mux.HandleFunc("/", hello)
	fcgi.Serve(l, mux)
}
Beispiel #4
0
func WriteFile(src io.Reader, targetFile string, permFile, uid, gid int) error {

	targetDir := filepath.Dir(targetFile)
	permDir := permFile | 0111

	if stat, err := os.Stat(targetDir); err != nil {
		if os.IsNotExist(err) {
			err = os.MkdirAll(targetDir, os.FileMode(permDir))
		}
		if err != nil {
			return err
		}
	} else if !stat.IsDir() {
		return errors.New("File target is not a dir: " + targetDir)
	}

	f, err := os.OpenFile(targetFile, os.O_RDWR|os.O_CREATE, os.FileMode(permFile))
	if err != nil {
		return err
	}
	defer f.Close()

	_, err = io.Copy(f, src)
	if err != nil {
		return err
	}

	if err = syscall.Chown(targetFile, uid, gid); err != nil {
		return err
	}

	return nil

}
Beispiel #5
0
func mknodDevice(dest string, node *configs.Device) error {
	fileMode := node.FileMode
	switch node.Type {
	case 'c':
		fileMode |= syscall.S_IFCHR
	case 'b':
		fileMode |= syscall.S_IFBLK
	default:
		return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
	}
	if err := syscall.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil {
		return err
	}
	return syscall.Chown(dest, int(node.Uid), int(node.Gid))
}
Beispiel #6
0
func (constor *Constor) createPath(dirpath string) error {
	dirs := strings.Split(dirpath, "/")
	if len(dirs) == 0 {
		return syscall.EIO
	}
	subdir := ""
	for _, dir := range dirs {
		if dir == "" {
			continue
		}
		subdir = Path.Join(subdir, "/", dir)
		li := constor.getLayer(subdir)
		if li == 0 {
			continue
		}
		if li == -1 {
			return syscall.EIO
		}
		stat := syscall.Stat_t{}
		if err := constor.Lstat(subdir, &stat); err != nil {
			return err
		}
		subdirl := Path.Join(constor.layers[0], subdir)
		if err := syscall.Mkdir(subdirl, stat.Mode); err != nil {
			return err
		}
		if err := syscall.Chown(subdirl, int(stat.Uid), int(stat.Gid)); err != nil {
			return err
		}
		if err := syscall.UtimesNano(subdirl, []syscall.Timespec{stat.Atim, stat.Mtim}); err != nil {
			return err
		}
		inoitoa := strconv.Itoa(int(stat.Ino))
		inobyte := []byte(inoitoa)
		if err := syscall.Setxattr(subdirl, INOXATTR, inobyte, 0); err != nil {
			return err
		}
		inode, err := constor.inodemap.findInode(stat.Ino)
		if err != nil {
			return err
		}
		inode.Lock()
		inode.layer = 0
		inode.Unlock()
	}
	return nil
}
Beispiel #7
0
func AttachFiles(containerId, fromFile, toDir, rootDir, perm, uid, gid string) error {
	if containerId == "" {
		return fmt.Errorf("Please make sure the arguments are not NULL!\n")
	}
	permInt := utils.ConvertPermStrToInt(perm)
	// It just need the block device without copying any files
	// FIXME whether we need to return an error if the target directory is null
	if toDir == "" {
		return nil
	}
	// Make a new file with the given premission and wirte the source file content in it
	if _, err := os.Stat(fromFile); err != nil && os.IsNotExist(err) {
		return err
	}
	buf, err := ioutil.ReadFile(fromFile)
	if err != nil {
		return err
	}
	targetDir := path.Join(rootDir, containerId, "rootfs", toDir)
	_, err = os.Stat(targetDir)
	targetFile := targetDir
	if err != nil && os.IsNotExist(err) {
		// we need to create a target directory with given premission
		if err := os.MkdirAll(targetDir, os.FileMode(permInt)); err != nil {
			return err
		}
		targetFile = targetDir + "/" + filepath.Base(fromFile)
	} else {
		targetFile = targetDir + "/" + filepath.Base(fromFile)
	}
	err = ioutil.WriteFile(targetFile, buf, os.FileMode(permInt))
	if err != nil {
		return err
	}

	user_id, _ := strconv.Atoi(uid)
	group_id, _ := strconv.Atoi(gid)
	if err = syscall.Chown(targetFile, user_id, group_id); err != nil {
		return err
	}

	return nil
}
Beispiel #8
0
func (constor *Constor) Mkdir(input *fuse.MkdirIn, name string, out *fuse.EntryOut) (code fuse.Status) {
	inode := constor.inodemap.findInodePtr(input.NodeId)
	if inode == nil {
		constor.error("inode == nil")
		return fuse.ENOENT
	}
	constor.log("%s %s", inode.id, name)
	err := constor.copyup(inode)
	if err != nil {
		constor.error("copyup failed on %s : ", inode.id, err)
		return fuse.ToStatus(err)
	}
	dirpath := constor.getPath(0, inode.id)
	entrypath := Path.Join(dirpath, name)
	syscall.Unlink(entrypath) // remove a deleted entry
	err = syscall.Mkdir(entrypath, input.Mode)
	if err != nil {
		constor.error("Failed on %s : %s", entrypath, err)
		return fuse.ToStatus(err)
	}
	id := constor.setid(entrypath, "")
	if id == "" {
		constor.error("setid failed on %s", entrypath)
		return fuse.ENOENT
	}
	if err := constor.createPath(id); err != nil {
		constor.error("createPath failed on %s : %s", id, err)
		return fuse.ToStatus(err)
	}
	path := constor.getPath(0, id)
	err = syscall.Mkdir(path, input.Mode)
	if err != nil {
		constor.error("Mkdir failed on %s : %s", path, err)
		return fuse.ToStatus(err)
	}
	err = syscall.Chown(path, int(input.Uid), int(input.Gid))
	if err != nil {
		constor.error("Chown failed on %s : %s", path, err)
		return fuse.ToStatus(err)
	}
	return constor.Lookup((*fuse.InHeader)(unsafe.Pointer(input)), name, out)
}
Beispiel #9
0
func (constor *Constor) Mknod(input *fuse.MknodIn, name string, out *fuse.EntryOut) (code fuse.Status) {
	path, err := constor.dentrymap.getPath(input.NodeId)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if err = constor.createPath(path); err != nil {
		return fuse.ToStatus(err)
	}
	pathl := Path.Join(constor.layers[0], path, name)
	syscall.Unlink(pathl) // remove a deleted entry
	err = syscall.Mknod(pathl, input.Mode, int(input.Rdev))
	if err != nil {
		return fuse.ToStatus(err)
	}
	err = syscall.Chown(pathl, int(input.Uid), int(input.Gid))
	if err != nil {
		return fuse.ToStatus(err)
	}
	return constor.Lookup((*fuse.InHeader)(unsafe.Pointer(input)), name, out)
}
Beispiel #10
0
// Chown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link's target.
// If there is an error, it will be of type *PathError.
func Chown(name string, uid, gid int) error {
	if e := syscall.Chown(name, uid, gid); e != nil {
		return &PathError{"chown", name, e}
	}
	return nil
}
Beispiel #11
0
// Chown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link's target.
func Chown(name string, uid, gid int) Error {
	if e := syscall.Chown(name, uid, gid); e != 0 {
		return &PathError{"chown", name, Errno(e)}
	}
	return nil
}
Beispiel #12
0
func AttachFiles(containerId, devPrefix, fromFile, toDir, rootPath, perm, uid, gid string) error {
	if containerId == "" {
		return fmt.Errorf("Please make sure the arguments are not NULL!\n")
	}
	permInt, err := strconv.Atoi(perm)
	if err != nil {
		return err
	}
	// Define the basic directory, need to get them via the 'info' command
	var (
		mntPath = fmt.Sprintf("%s/mnt/", rootPath)
		devName = fmt.Sprintf("%s-%s", devPrefix, containerId)
	)

	// Get the mount point for the container ID
	idMountPath := path.Join(mntPath, containerId)
	rootFs := path.Join(idMountPath, "rootfs")
	targetDir := path.Join(rootFs, toDir)

	// Whether we have the mounter directory
	if _, err := os.Stat(idMountPath); err != nil && os.IsNotExist(err) {
		if err := os.MkdirAll(idMountPath, os.FileMode(permInt)); err != nil {
			return err
		}
	}

	// Mount the block device to that mount point
	var flags uintptr = syscall.MS_MGC_VAL
	devFullName := fmt.Sprintf("/dev/mapper/%s", devName)
	fstype, err := ProbeFsType(devFullName)
	if err != nil {
		return err
	}
	glog.V(3).Infof("The filesytem type is %s\n", fstype)
	options := ""
	if fstype == "xfs" {
		// XFS needs nouuid or it can't mount filesystems with the same fs
		options = joinMountOptions(options, "nouuid")
	}

	err = syscall.Mount(devFullName, idMountPath, fstype, flags, joinMountOptions("discard", options))
	if err != nil && err == syscall.EINVAL {
		err = syscall.Mount(devFullName, idMountPath, fstype, flags, options)
	}
	if err != nil {
		return fmt.Errorf("Error mounting '%s' on '%s': %s", devFullName, idMountPath, err)
	}

	// It just need the block device without copying any files
	if fromFile == "" || toDir == "" {
		// we need to unmout the device from the mounted directory
		syscall.Unmount(idMountPath, syscall.MNT_DETACH)
		return nil
	}
	// Make a new file with the given premission and wirte the source file content in it
	if _, err := os.Stat(fromFile); err != nil && os.IsNotExist(err) {
		// The given file is not exist, we need to unmout the device and return
		syscall.Unmount(idMountPath, syscall.MNT_DETACH)
		return err
	}
	buf, err := ioutil.ReadFile(fromFile)
	if err != nil {
		// unmout the device
		syscall.Unmount(idMountPath, syscall.MNT_DETACH)
		return err
	}
	_, err = os.Stat(targetDir)
	targetFile := targetDir
	if err != nil && os.IsNotExist(err) {
		// we need to create a target directory with given premission
		if err := os.MkdirAll(targetDir, os.FileMode(permInt)); err != nil {
			// we need to unmout the device
			syscall.Unmount(idMountPath, syscall.MNT_DETACH)
			return err
		}
		targetFile = targetDir + "/" + filepath.Base(fromFile)
	} else {
		targetFile = targetDir + "/" + filepath.Base(fromFile)
	}
	err = ioutil.WriteFile(targetFile, buf, os.FileMode(permInt))
	if err != nil {
		// we need to unmout the device
		syscall.Unmount(idMountPath, syscall.MNT_DETACH)
		return err
	}
	user_id, _ := strconv.Atoi(uid)
	group_id, _ := strconv.Atoi(gid)
	if err = syscall.Chown(targetFile, user_id, group_id); err != nil {
		syscall.Unmount(idMountPath, syscall.MNT_DETACH)
		return err
	}
	// finally we need to unmout the device
	syscall.Unmount(idMountPath, syscall.MNT_DETACH)
	return nil
}
Beispiel #13
0
func (k *PosixKernel) Chown(path string, uid, gid int) uint64 {
	return Errno(syscall.Chown(path, uid, gid))
}
Beispiel #14
0
func (constor *Constor) Create(input *fuse.CreateIn, name string, out *fuse.CreateOut) (code fuse.Status) {
	flags := 0

	inode := constor.inodemap.findInodePtr(input.NodeId)
	if inode == nil {
		constor.error("inode == nil")
		return fuse.ENOENT
	}
	err := constor.copyup(inode)
	if err != nil {
		constor.error("copyup failed for %s - %s", inode.id, err)
		return fuse.ToStatus(err)
	}
	dirpath := constor.getPath(0, inode.id)
	entrypath := Path.Join(dirpath, name)

	if constor.isdeleted(entrypath, nil) {
		if err := syscall.Unlink(entrypath); err != nil {
			constor.error("Unlink %s : %s", entrypath, err)
			return fuse.ToStatus(err)
		}
	}

	fd, err := syscall.Creat(entrypath, input.Mode)
	if err != nil {
		constor.error("Creat %s : %s", entrypath, err)
		return fuse.ToStatus(err)
	}
	syscall.Close(fd)
	id := constor.setid(entrypath, "")
	if id == "" {
		constor.error("setid %s : %s", entrypath, err)
		return fuse.EIO
	}
	constor.log("%s : %s", entrypath, id)
	if err := constor.createPath(id); err != nil {
		constor.error("createPath %s : %s", id, err)
		return fuse.ToStatus(err)
	}
	path := constor.getPath(0, id)
	if input.Flags != 0 {
		flags = int(input.Flags) | syscall.O_CREAT
	} else {
		flags = syscall.O_CREAT | syscall.O_RDWR | syscall.O_EXCL
	}
	fd, err = syscall.Open(path, flags, input.Mode)
	// fd, err = syscall.Open(path, int(input.Flags), input.Mode)
	if err != nil {
		constor.error("open %s : %s", path, err)
		return fuse.ToStatus(err)
	}
	err = syscall.Chown(path, int(input.Uid), int(input.Gid))
	if err != nil {
		constor.error("Chown %s : %s", path, err)
		return fuse.ToStatus(err)
	}
	F := new(FD)
	F.fd = fd
	F.layer = 0
	F.id = id
	F.pid = input.Pid
	constor.putfd(F)
	if flags&syscall.O_DIRECT != 0 {
		out.OpenFlags = fuse.FOPEN_DIRECT_IO
	} else {
		out.OpenFlags = fuse.FOPEN_KEEP_CACHE
	}

	out.Fh = uint64(uintptr(unsafe.Pointer(F)))
	constor.log("%d", out.Fh)
	return constor.Lookup((*fuse.InHeader)(unsafe.Pointer(input)), name, &out.EntryOut)
}