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) }
// 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 }
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) }
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 }
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)) }
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 }
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 }
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) }
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) }
// 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 }
// 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 }
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 }
func (k *PosixKernel) Chown(path string, uid, gid int) uint64 { return Errno(syscall.Chown(path, uid, gid)) }
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) }