如何实现文件系统?

huangapple go评论77阅读模式
英文:

How to implement the file system?

问题

我需要编写一个程序,可以与所有类型的文件系统一起工作。

在Linux中,您可以挂载不同的文件系统。每个文件系统都有参数,一些“文件夹”和甚至命令执行的顺序。
示例:

  1. 简单示例:mount -t ntfs /dev/sda1 /mnt/win_xp
  2. 挂载/lxc/shared:
    mount --bind /lxc/shared /lxc/shared
    mount --make-unbindable /lxc/shared
    mount --make-shared /lxc/shared
  3. 接收两个目录而不是一个:
    mount -t overlayfs -o rw,lowerdir=/low-layer,upperdir=/hilayer overlayfs /overlayfs
    下一个命令:
    find /overlayfs -lname '(overlay-whiteout)' -exec rm -rf {} ;

实质上,每个文件系统有两个状态:

  • 已挂载
  • 未挂载

并且每个文件系统可以执行有限数量的操作:

  • 挂载(mount)
  • 卸载(unmount)
  • 检查是否已挂载
  • 删除(先卸载)

PS:
我使用Go语言编写代码。我已经写了一些代码,但不适合。

package main

import (
	"fmt"
	"sort"
	"sync"
	"os/exec"
	"strings"
)

type LayerForMount struct {
	Upper        string
	Lower        string
	MountPoint   string
	MountOptions string
	FSType       string
}

type LayersOverlayFS struct {
	layers map[int]LayerForMount
	sync.RWMutex
}

func (l *LayersOverlayFS) Add(layer LayerForMount, key int) error {
	l.Lock()
	defer l.Unlock()
	if _, ok := l.layers[key]; ok {
		return fmt.Errorf("key %v exist", key)
	}
	l.layers[key] = layer
	return nil
}

func (l *LayersOverlayFS) Remove(key int) {
	l.Lock()
	defer l.Unlock()
	delete(l.layers, key)
}

/*
   如果挂载点未挂载,则挂载lower、upper目录到挂载点
   TODO: 检查lower、upper是否与已挂载的相同
*/
func (l *LayersOverlayFS) Mount() (err error) {
	l.RLock()
	defer l.RUnlock()
	forceRemount := false
	var keys []int
	for k, _ := range l.layers {
		keys = append(keys, k)
	}
	sort.Ints(keys)

	for _, k := range keys {
		err = MountLowerUpperLayer(l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount)
		if err != nil {
			return fmt.Errorf("MountLowerUpperLayer(%v,%v,%v,%v,%v,%v) has error: %v", l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount, err)
		}
	}
	return nil
}

func (l *LayersOverlayFS) GetCFGofLastLayer() LayerForMount {
	l.RLock()
	defer l.RUnlock()
	var keys []int
	for k, _ := range l.layers {
		keys = append(keys, k)
	}
	sort.Ints(keys)
	lastLayer := keys[len(keys)]
	return l.layers[lastLayer]
}

/* 仅卸载最后一层 */
func (l *LayersOverlayFS) Umount() (err error) {
	l.RLock()
	defer l.RUnlock()

	forceRemount := false
	var keys []int
	for k, _ := range l.layers {
		keys = append(keys, k)
	}
	sort.Ints(keys)
	lastLayer := keys[len(keys)]
	if IsMounted(l.layers[lastLayer].MountPoint, l.layers[lastLayer].FSType) == true {
		UnmountLayer(l.layers[lastLayer].FSType, l.layers[lastLayer].MountPoint, forceRemount)
	}
	return nil
}


func IsMounted(MountPoint, FSType string) bool {
	return true
}

func UnmountLayer(FSType, MountPoint string, forceRemount bool) {
}

func MountLowerUpperLayer(fstype, lower, upper, mountpoint, mount_options string, forceremount bool) (err error) {
	cmdLayerMount := "mount"
	cmd := " -n -t " + " " + fstype + " -o " + mount_options + ",lowerdir=" + lower + "/,upperdir=" + upper + "/ " + fstype + " " + mountpoint + "/"
	cmdObject := exec.Command(cmdLayerMount, strings.Fields(cmd)...)
	_, err = cmdObject.Output()
	if err != nil {
		return err
	}

	return nil
}


func main() {
	fmt.Println("Hello, playground")
}

我想实现所有类型的文件系统,但现在这是OverlayFS。

英文:

I need write program which will mount(work) with all type of fyle system.

In linux you can mount the different file systems. And each file system has parameters, some number of "folders" and even the sequence of execution of commands.
examples:

  1. A simple example: mount -t ntfs / dev / sda1 / mnt / win_xp
  2. Mounting / lxc / shared:
    mount --bind / lxc / shared / lxc / shared
    mount --make-unbindable / lxc / shared mount --make-shared / lxc /
    shared
  3. receives 2-directory instead of one:
    mount -t overlayfs -o rw, lowerdir =/low-layer, upperdir = /hilayer overlayfs /overlayfs
    next-command:
    find / overlayfs -lname '(overlay-whiteout)' -exec rm -rf {} ;

In essence, each file system has two states:

  • mounted
  • not mounted

And over each can hold a limited number of operations:

  • mount ()
  • unmount ()
  • check mounted
  • Remove (previously unmounted)

PS:
I write code in the Go language. I have wrote some code http://play.golang.org/p/Ri5yAqsLu7 but it doesn't fit.

package main
import (
"fmt"
"sort"
"sync"
"os/exec"
"strings"
)
type LayerForMount struct {
Upper        string
Lower        string
MountPoint   string
MountOptions string
FSType       string
}
type LayersOverlayFS struct {
layers map[int]LayerForMount
sync.RWMutex
}
func (l *LayersOverlayFS) Add(layer LayerForMount, key int) error {
l.Lock()
defer l.Unlock()
if _, ok := l.layers[key]; ok {
return fmt.Errorf("key %v exist", key)
}
l.layers[key] = layer
return nil
}
func (l *LayersOverlayFS) Remove(key int) {
l.Lock()
defer l.Unlock()
delete(l.layers, key)
}
/*
mount lower,upper dirs to mountpoint if mountpoint not mounted
TODO: cheack that lower,upper == to already mounted
*/
func (l *LayersOverlayFS) Mount() (err error) {
l.RLock()
defer l.RUnlock()
forceRemount := false
var keys []int
for k, _ := range l.layers {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
err = MountLowerUpperLayer(l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount)
if err != nil {
return fmt.Errorf("MountLowerUpperLayer(%v,%v,%v,%v,%v,%v) has error: %v", l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount, err)
}
}
return nil
}
func (l *LayersOverlayFS) GetCFGofLastLayer() LayerForMount {
l.RLock()
defer l.RUnlock()
var keys []int
for k, _ := range l.layers {
keys = append(keys, k)
}
sort.Ints(keys)
lastLayer := keys[len(keys)]
return l.layers[lastLayer]
}
/* unmount only last layer */
func (l *LayersOverlayFS) Umount() (err error) {
l.RLock()
defer l.RUnlock()
forceRemount := false
var keys []int
for k, _ := range l.layers {
keys = append(keys, k)
}
sort.Ints(keys)
lastLayer := keys[len(keys)]
if IsMounted(l.layers[lastLayer].MountPoint, l.layers[lastLayer].FSType) == true {
UnmountLayer(l.layers[lastLayer].FSType, l.layers[lastLayer].MountPoint, forceRemount)
}
return nil
}
func IsMounted (MountPoint,FSType string) bool{
return true 
}
func UnmountLayer(FSType,MountPoint string,forceRemount bool) {
}
func MountLowerUpperLayer(fstype, lower, upper, mountpoint, mount_options string, forceremount bool) (err error) {		
cmdLayerMount:="mount"
cmd := " -n -t " + " " + fstype + " -o " + mount_options + ",lowerdir=" + lower + "/,upperdir=" + upper + "/ " + fstype + " " + mountpoint + "/"
cmdObject := exec.Command(cmdLayerMount, strings.Fields(cmd)...)
_, err = cmdObject.Output()
if err != nil {			
return err
}
return nil
}
func main() {
fmt.Println("Hello, playground")
}

I want implement all type of File system, but now this is OverlayFS

答案1

得分: 1

这些东西不需要重新实现。尝试研究一下GVFSKIO以及相关组件。它们是Gnome和KDE的一部分,可以管理远程挂载和资源(显然也包括本地资源)。

你可以使用gccgo来使用GVFS,使用Swig来使用KIO。

英文:

There shouldn't be any need to reimplement these things. Try researching GVFS or KIO, and the related components. They are parts of Gnome and KDE, allowing them to manage remote mounts and resources (also local, apparently).

GVFS you can use with gccgo, KIO with Swig.

huangapple
  • 本文由 发表于 2014年11月20日 21:23:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/27040741.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定