func createDevices() error { err := os.MkdirAll(pathPrefix, 644) if err != nil { log.Warnf("Failed to ensure presence of tether device directory: %s", err) } // create serial devices for i := 0; i < 3; i++ { path := fmt.Sprintf("%s/ttyS%d", pathPrefix, i) minor := 64 + i err = syscall.Mknod(path, syscall.S_IFCHR|uint32(os.FileMode(0660)), tether.Mkdev(4, minor)) if err != nil { return fmt.Errorf("failed to create %s for com%d: %s", path, i+1, err) } } // make an access to urandom path := fmt.Sprintf("%s/urandom", pathPrefix) err = syscall.Mknod(path, syscall.S_IFCHR|uint32(os.FileMode(0444)), tether.Mkdev(1, 9)) if err != nil { return fmt.Errorf("failed to create urandom access %s: %s", path, err) } return nil }
func (constor *Constor) setdeleted(path string) error { err := syscall.Mknod(path, syscall.S_IFCHR, 0) if err != nil { err := syscall.Unlink(path) if err != nil { constor.error("unable to rm %s %s", path, err) } return syscall.Mknod(path, syscall.S_IFCHR, 0) } return nil }
func extractArchive() int { archive := tar.NewReader(input) for { hdr, err := archive.Next() if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "An error occured while reading archive: %v\n", err) return 1 } if verbose { fmt.Fprintf(os.Stderr, "%s\n", hdr.Name) } switch hdr.Typeflag { case tar.TypeReg, tar.TypeRegA: var f *os.File if f, err = os.OpenFile(hdr.Name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.FileMode(hdr.Mode)); err == nil { io.Copy(f, archive) f.Close() err = os.Chtimes(hdr.Name, hdr.ModTime, hdr.ModTime) } case tar.TypeDir: err = os.Mkdir(hdr.Name, os.FileMode(hdr.Mode)) if err != nil { patherr, ok := err.(*os.PathError) if ok && patherr.Err == syscall.EEXIST { err = nil } } case tar.TypeSymlink: err = os.Link(hdr.Name, hdr.Linkname) case tar.TypeFifo: err = syscall.Mkfifo(hdr.Name, uint32(hdr.Mode)) case tar.TypeChar: err = errors.New("character devices unsupported") err = syscall.Mknod(hdr.Name, syscall.S_IFCHR, makedev(hdr.Devmajor, hdr.Devminor)) case tar.TypeBlock: err = errors.New("block devices unsupported") err = syscall.Mknod(hdr.Name, syscall.S_IFBLK, makedev(hdr.Devmajor, hdr.Devminor)) } if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) } } return 0 }
func (f *mknod1) test(path string, t *testing.T) { if os.Getuid() != 0 { t.Logf("skipping unless root") return } defer syscall.Umask(syscall.Umask(0)) err := syscall.Mknod(path+"/node", syscall.S_IFIFO|0666, 123) if err != nil { t.Fatalf("Mknod: %v", err) } gotr := <-f.seen.gotr if gotr == nil { t.Fatalf("no recorded MknodRequest") } if g, e := gotr.Name, "node"; g != e { t.Errorf("got Name = %q; want %q", g, e) } if g, e := gotr.Rdev, uint32(123); g != e { if runtime.GOOS == "linux" { // Linux fuse doesn't echo back the rdev if the node // isn't a device (we're using a FIFO here, as that // bit is portable.) } else { t.Errorf("got Rdev = %v; want %v", g, e) } } if g, e := gotr.Mode, os.FileMode(os.ModeNamedPipe|0666); g != e { t.Errorf("got Mode = %v; want %v", g, e) } t.Logf("Got request: %#v", gotr) }
// 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 ListenForClients(pipename string) { if _, err := os.Stat(pipename); err == nil { fmt.Printf("pipe already exists\n") } else { syscall.Mknod(pipename, syscall.S_IFIFO|0666, 0) } servedClients := make(map[string]bool) fmt.Printf("About to open pipe %s for read\n", pipename) for { readPipe, err := os.OpenFile(pipename, os.O_RDONLY, 0666) if err != nil { fmt.Printf("Could not open register pipe %s for read\n", REGISTER_PIPE) continue //log.Fatal(err) } msg := &Registration{} dataDecoder := gob.NewDecoder(readPipe) err = dataDecoder.Decode(msg) if err != nil { fmt.Printf("Error decoding registration msg from %s\n", pipename) //log.Fatal(err) } else { readPipe.Close() } if msg.ClientName == "" { continue } fmt.Printf("Need to open pipe for reading client commands: %+v\n", msg) if !servedClients[msg.ClientName] { go serveClient(msg.ClientName, servedClients) } servedClients[msg.ClientName] = true } }
func mknod(device string, major, minor int) error { var fileMode os.FileMode = 0600 fileMode |= syscall.S_IFBLK dev := int((major << 8) | (minor & 0xff) | ((minor & 0xfff00) << 12)) return syscall.Mknod(device, uint32(fileMode), dev) }
// make_console sets the right modes for the real console, then creates // a /dev/console in the chroot. func make_console(base, console string, unprivileged bool) { if err := os.Chmod(console, 0600); err != nil { log.Printf("%v", err) } if err := os.Chown(console, 0, 0); err != nil { log.Printf("%v", err) } st, err := os.Stat(console) if err != nil { log.Printf("%v", err) } nn := path.Join(base, "/dev/console") mode, dev := modedev(st) if unprivileged { // In unprivileged uses, we can't mknod /dev/console, however, // we can just create a file /dev/console and use bind mount on file. if _, err := os.Stat(nn); err != nil { ioutil.WriteFile(nn, []byte{}, 0600) // best effort, ignore error } } else { if err := syscall.Mknod(nn, mode, dev); err != nil { log.Printf("%v", err) } } // if any previous steps failed, this one will too, so we can bail here. if err := syscall.Mount(console, nn, "", syscall.MS_BIND, ""); err != nil { log.Fatalf("Mount :%s: on :%s: flags %v: %v", console, nn, syscall.MS_BIND, err) } }
func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) { base := filepath.Base(path) dir := filepath.Dir(path) // if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay if base == WhiteoutOpaqueDir { if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil { return false, err } // don't write the file itself return false, nil } // if a file was deleted and we are using overlay, we need to create a character device if strings.HasPrefix(base, WhiteoutPrefix) { originalBase := base[len(WhiteoutPrefix):] originalPath := filepath.Join(dir, originalBase) if err := syscall.Mknod(originalPath, syscall.S_IFCHR, 0); err != nil { return false, err } if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil { return false, err } // don't write the file itself return false, nil } return true, nil }
func TestMknod(t *testing.T) { t.Parallel() if os.Getuid() != 0 { t.Skip("skipping unless root") } f := &mknod1{} mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f}) if err != nil { t.Fatal(err) } defer mnt.Close() defer syscall.Umask(syscall.Umask(0)) err = syscall.Mknod(mnt.Dir+"/node", syscall.S_IFIFO|0666, 123) if err != nil { t.Fatalf("Mknod: %v", err) } want := fuse.MknodRequest{ Name: "node", Mode: os.FileMode(os.ModeNamedPipe | 0666), Rdev: uint32(123), } if runtime.GOOS == "linux" { // Linux fuse doesn't echo back the rdev if the node // isn't a device (we're using a FIFO here, as that // bit is portable.) want.Rdev = 0 } if g, e := f.RecordedMknod(), want; g != e { t.Fatalf("mknod saw %+v, want %+v", g, e) } }
// Creates the device node in the rootfs of the container. func CreateDeviceNode(rootfs string, node *devices.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), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) { return fmt.Errorf("mknod %s %s", node.Path, err) } return nil }
func Mknod(call []string) error { e := flagSet.Parse(call[1:]) if e != nil { return e } if flagSet.NArg() != 1 || *helpFlag { println("`mknod` [options] <file>") flagSet.PrintDefaults() return nil } mode, ok := typemap[strings.ToLower(*typeFlag)] if !ok { return errors.New("Invalid node type \"" + *typeFlag + "\"") } if mode == syscall.S_IFBLK && (*majorFlag == -1 || *minorFlag == -1) { return errors.New("When creating a block device, both minor and major number have to be given") } fmode, e := strconv.ParseUint(*modeFlag, 10, 8) if e != nil { return e } mode |= uint32(fmode) e = syscall.Mknod(flagSet.Arg(0), mode, *majorFlag<<8|*minorFlag) return e }
func (t *MknodTest) File() { // mknod(2) only works for root on OS X. if runtime.GOOS == "darwin" { return } var err error p := path.Join(t.Dir, "foo") // Create err = syscall.Mknod(p, syscall.S_IFREG|0641, 0) AssertEq(nil, err) // Stat fi, err := os.Stat(p) AssertEq(nil, err) ExpectEq(path.Base(p), fi.Name()) ExpectEq(0, fi.Size()) ExpectEq(os.FileMode(0641), fi.Mode()) // Read contents, err := ioutil.ReadFile(p) AssertEq(nil, err) ExpectEq("", string(contents)) }
func checkCanMknod() { /* TODO - mktemp */ fnam := shared.VarPath("null") // warning to cut-pasters: can't do the below in general, that is if minor is big if err := syscall.Mknod(fnam, syscall.S_IFCHR, int((int64(1)<<8)|int64(3))); err != nil { canMknod = false os.Remove(fnam) } }
func (fs *Filesystem) CreateDevice(devpath string, dev int, mode uint32) error { p := fs.absPath(devpath) um := syscall.Umask(0) if err := syscall.Mknod(p, mode, dev); err != nil { return fmt.Errorf("failed to mknod device '%s': %v", p, err) } syscall.Umask(um) return nil }
func (inode *SpecialInode) make(name string) error { if inode.Mode&syscall.S_IFBLK != 0 || inode.Mode&syscall.S_IFCHR != 0 { return syscall.Mknod(name, uint32(inode.Mode), int(inode.Rdev)) } else if inode.Mode&syscall.S_IFIFO != 0 { return syscall.Mkfifo(name, uint32(inode.Mode)) } else { return errors.New("unsupported mode") } }
// Mknod unless path does not exists. func Mknod(path string, mode uint32, dev int) error { if ExistsFile(path) { return nil } if err := syscall.Mknod(path, mode, dev); err != nil { return err } return nil }
func (constor *Constor) Mknod(input *fuse.MknodIn, 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.Mknod(entrypath, input.Mode, int(input.Rdev)) 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.Mknod(path, input.Mode, int(input.Rdev)) if err != nil { constor.error("Mknod 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 child() { // Create temp file for NS path := "/proc/self/ns/net" must(syscall.Mount("fs/rootfs", "fs/rootfs", "", syscall.MS_BIND, "")) must(os.MkdirAll("fs/rootfs/oldrootfs", 0700)) must(syscall.PivotRoot("fs/rootfs", "fs/rootfs/oldrootfs")) must(os.Chdir("/")) must(syscall.Unmount("/oldrootfs", syscall.MNT_DETACH)) must(os.Remove("/oldrootfs")) must(syscall.Mount("proc", "/proc", "proc", 0, "")) // Some devices syscall.Mknod("/dev/null", 0666, Mkdev(int64(1), int64(3))) syscall.Mknod("/dev/zero", 0666, Mkdev(int64(1), int64(5))) syscall.Mknod("/dev/random", 0666, Mkdev(int64(1), int64(8))) syscall.Mknod("/dev/urandom", 0666, Mkdev(int64(1), int64(9))) fmt.Println("Pid:", os.Getpid()) ns, err := netns.GetFromPath(path) if err != nil { fmt.Println("cant find ns") } must(netns.Set(ns)) routingUp() cmd := exec.Command(os.Args[2], os.Args[3:]...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { fmt.Println("ERROR", err) os.Exit(1) } routingDown() }
func (t *MknodTest) NonExistentParent() { // mknod(2) only works for root on OS X. if runtime.GOOS == "darwin" { return } var err error p := path.Join(t.Dir, "foo/bar") err = syscall.Mknod(p, syscall.S_IFREG|0600, 0) ExpectEq(syscall.ENOENT, err) }
func (me *testCase) testMknod() { me.tester.Log("Testing mknod.") errNo := syscall.Mknod(me.mountFile, syscall.S_IFIFO|0777, 0) if errNo != 0 { me.tester.Errorf("Mknod %v", errNo) } fi, _ := os.Lstat(me.origFile) if fi == nil || !fi.IsFifo() { me.tester.Errorf("Expected FIFO filetype.") } me.removeMountFile() }
func TestMknod(t *testing.T) { me := NewTestCase(t) defer me.Cleanup() t.Log("Testing mknod.") errNo := syscall.Mknod(me.mountFile, syscall.S_IFIFO|0777, 0) if errNo != nil { t.Errorf("Mknod %v", errNo) } fi, _ := os.Lstat(me.origFile) if fi == nil || !fi.IsFifo() { t.Errorf("Expected FIFO filetype.") } }
func TestMknod(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() if errNo := syscall.Mknod(tc.mountFile, syscall.S_IFIFO|0777, 0); errNo != nil { t.Errorf("Mknod %v", errNo) } if fi, err := os.Lstat(tc.origFile); err != nil { t.Errorf("Lstat(%q): %v", tc.origFile, err) } else if fi.Mode()&os.ModeNamedPipe == 0 { t.Errorf("Expected FIFO filetype, got %x", fi.Mode()) } }
func (fs *Filesystem) CreateDevice(devpath string, dev int, mode uint32, gid int) error { p := fs.absPath(devpath) um := syscall.Umask(0) if err := syscall.Mknod(p, mode, dev); err != nil { return fmt.Errorf("failed to mknod device '%s': %v", p, err) } if gid > 0 { if err := os.Chown(p, 0, gid); err != nil { return fmt.Errorf("failed to change group for device '%s': %v", p, err) } } syscall.Umask(um) return nil }
func (t *MknodTest) Directory() { // mknod(2) only works for root on OS X. if runtime.GOOS == "darwin" { return } var err error p := path.Join(t.Dir, "foo") // Quoth `man 2 mknod`: "Under Linux, this call cannot be used to create // directories." err = syscall.Mknod(p, syscall.S_IFDIR|0700, 0) ExpectEq(syscall.EPERM, err) }
func TestMknod(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() t.Log("Testing mknod.") errNo := syscall.Mknod(tc.mountFile, syscall.S_IFIFO|0777, 0) if errNo != nil { t.Errorf("Mknod %v", errNo) } fi, _ := os.Lstat(tc.origFile) if fi == nil || fi.Mode()&os.ModeNamedPipe == 0 { t.Errorf("Expected FIFO filetype.") } }
// mknod requires privilege ... func TestHeaderUnixDev(t *testing.T) { hExpect := tar.Header{ Name: "./dev/test0", Size: 0, Typeflag: tar.TypeBlock, Devminor: 5, Devmajor: 233, } // make our test block device var path string { var err error path, err = ioutil.TempDir("", "tarheader-test-") if err != nil { t.Fatal(err) } defer os.RemoveAll(path) if err := os.Mkdir(filepath.Join(path, "dev"), os.FileMode(0755)); err != nil { t.Fatal(err) } mode := uint32(hExpect.Mode&07777) | syscall.S_IFBLK dev := uint32(((hExpect.Devminor & 0xfff00) << 12) | ((hExpect.Devmajor & 0xfff) << 8) | (hExpect.Devminor & 0xff)) if err := syscall.Mknod(filepath.Join(path, hExpect.Name), mode, int(dev)); err != nil { if err == syscall.EPERM { t.Skip("no permission to CAP_MKNOD") } t.Fatal(err) } } fi, err := os.Stat(filepath.Join(path, hExpect.Name)) if err != nil { t.Fatal(err) } hGot := tar.Header{ Name: "./dev/test0", Size: 0, Typeflag: tar.TypeBlock, } seen := map[uint64]string{} populateHeaderUnix(&hGot, fi, seen) if hGot.Devminor != hExpect.Devminor { t.Errorf("dev minor: got %d, expected %d", hGot.Devminor, hExpect.Devminor) } if hGot.Devmajor != hExpect.Devmajor { t.Errorf("dev major: got %d, expected %d", hGot.Devmajor, hExpect.Devmajor) } }
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)) }
// Poor man's Mknodat func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { chdirMutex.Lock() defer chdirMutex.Unlock() if !filepath.IsAbs(path) { oldWd, err := os.Getwd() if err != nil { return err } defer os.Chdir(oldWd) } path, err = dirfdAbs(dirfd, path) if err != nil { return err } return syscall.Mknod(path, mode, dev) }
// Get the backing block device of the driver home directory // and create a block device node under the home directory // to be used by quotactl commands func makeBackingFsDev(home string) (string, error) { fileinfo, err := os.Stat(home) if err != nil { return "", err } backingFsBlockDev := path.Join(home, "backingFsBlockDev") // Re-create just in case comeone copied the home directory over to a new device syscall.Unlink(backingFsBlockDev) stat := fileinfo.Sys().(*syscall.Stat_t) if err := syscall.Mknod(backingFsBlockDev, syscall.S_IFBLK|0600, int(stat.Dev)); err != nil { return "", fmt.Errorf("Failed to mknod %s: %v", backingFsBlockDev, err) } return backingFsBlockDev, nil }