英文:
How to implement the file system?
问题
我需要编写一个程序,可以与所有类型的文件系统一起工作。
在Linux中,您可以挂载不同的文件系统。每个文件系统都有参数,一些“文件夹”和甚至命令执行的顺序。
示例:
- 简单示例:mount -t ntfs /dev/sda1 /mnt/win_xp
- 挂载/lxc/shared:
mount --bind /lxc/shared /lxc/shared
mount --make-unbindable /lxc/shared
mount --make-shared /lxc/shared - 接收两个目录而不是一个:
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:
- A simple example: mount -t ntfs / dev / sda1 / mnt / win_xp
- Mounting / lxc / shared:
mount --bind / lxc / shared / lxc / shared
mount --make-unbindable / lxc / shared mount --make-shared / lxc /
shared - 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
这些东西不需要重新实现。尝试研究一下GVFS或KIO以及相关组件。它们是Gnome和KDE的一部分,可以管理远程挂载和资源(显然也包括本地资源)。
你可以使用gccgo来使用GVFS,使用Swig来使用KIO。
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论