Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
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)
}
Пример #5
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
}
Пример #6
0
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
	}
}
Пример #7
0
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)
}
Пример #8
0
// 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)
	}

}
Пример #9
0
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
}
Пример #10
0
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)
	}
}
Пример #11
0
// 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
}
Пример #12
0
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
}
Пример #13
0
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))
}
Пример #14
0
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)
	}
}
Пример #15
0
Файл: fs.go Проект: drptbl/oz
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
}
Пример #16
0
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")
	}
}
Пример #17
0
// 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
}
Пример #18
0
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)
}
Пример #19
0
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()

}
Пример #20
0
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)
}
Пример #21
0
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()
}
Пример #22
0
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.")
	}
}
Пример #23
0
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())
	}
}
Пример #24
0
Файл: fs.go Проект: tdr130/oz
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
}
Пример #25
0
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)
}
Пример #26
0
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.")
	}
}
Пример #27
0
// 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)
	}
}
Пример #28
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))
}
Пример #29
0
// 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)
}
Пример #30
0
// 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
}