如何实现文件系统?

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

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语言编写代码。我已经写了一些代码,但不适合。

  1. package main
  2. import (
  3. "fmt"
  4. "sort"
  5. "sync"
  6. "os/exec"
  7. "strings"
  8. )
  9. type LayerForMount struct {
  10. Upper string
  11. Lower string
  12. MountPoint string
  13. MountOptions string
  14. FSType string
  15. }
  16. type LayersOverlayFS struct {
  17. layers map[int]LayerForMount
  18. sync.RWMutex
  19. }
  20. func (l *LayersOverlayFS) Add(layer LayerForMount, key int) error {
  21. l.Lock()
  22. defer l.Unlock()
  23. if _, ok := l.layers[key]; ok {
  24. return fmt.Errorf("key %v exist", key)
  25. }
  26. l.layers[key] = layer
  27. return nil
  28. }
  29. func (l *LayersOverlayFS) Remove(key int) {
  30. l.Lock()
  31. defer l.Unlock()
  32. delete(l.layers, key)
  33. }
  34. /*
  35. 如果挂载点未挂载,则挂载lower、upper目录到挂载点
  36. TODO: 检查lower、upper是否与已挂载的相同
  37. */
  38. func (l *LayersOverlayFS) Mount() (err error) {
  39. l.RLock()
  40. defer l.RUnlock()
  41. forceRemount := false
  42. var keys []int
  43. for k, _ := range l.layers {
  44. keys = append(keys, k)
  45. }
  46. sort.Ints(keys)
  47. for _, k := range keys {
  48. err = MountLowerUpperLayer(l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount)
  49. if err != nil {
  50. 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)
  51. }
  52. }
  53. return nil
  54. }
  55. func (l *LayersOverlayFS) GetCFGofLastLayer() LayerForMount {
  56. l.RLock()
  57. defer l.RUnlock()
  58. var keys []int
  59. for k, _ := range l.layers {
  60. keys = append(keys, k)
  61. }
  62. sort.Ints(keys)
  63. lastLayer := keys[len(keys)]
  64. return l.layers[lastLayer]
  65. }
  66. /* 仅卸载最后一层 */
  67. func (l *LayersOverlayFS) Umount() (err error) {
  68. l.RLock()
  69. defer l.RUnlock()
  70. forceRemount := false
  71. var keys []int
  72. for k, _ := range l.layers {
  73. keys = append(keys, k)
  74. }
  75. sort.Ints(keys)
  76. lastLayer := keys[len(keys)]
  77. if IsMounted(l.layers[lastLayer].MountPoint, l.layers[lastLayer].FSType) == true {
  78. UnmountLayer(l.layers[lastLayer].FSType, l.layers[lastLayer].MountPoint, forceRemount)
  79. }
  80. return nil
  81. }
  82. func IsMounted(MountPoint, FSType string) bool {
  83. return true
  84. }
  85. func UnmountLayer(FSType, MountPoint string, forceRemount bool) {
  86. }
  87. func MountLowerUpperLayer(fstype, lower, upper, mountpoint, mount_options string, forceremount bool) (err error) {
  88. cmdLayerMount := "mount"
  89. cmd := " -n -t " + " " + fstype + " -o " + mount_options + ",lowerdir=" + lower + "/,upperdir=" + upper + "/ " + fstype + " " + mountpoint + "/"
  90. cmdObject := exec.Command(cmdLayerMount, strings.Fields(cmd)...)
  91. _, err = cmdObject.Output()
  92. if err != nil {
  93. return err
  94. }
  95. return nil
  96. }
  97. func main() {
  98. fmt.Println("Hello, playground")
  99. }

我想实现所有类型的文件系统,但现在这是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.

  1. package main
  2. import (
  3. "fmt"
  4. "sort"
  5. "sync"
  6. "os/exec"
  7. "strings"
  8. )
  9. type LayerForMount struct {
  10. Upper string
  11. Lower string
  12. MountPoint string
  13. MountOptions string
  14. FSType string
  15. }
  16. type LayersOverlayFS struct {
  17. layers map[int]LayerForMount
  18. sync.RWMutex
  19. }
  20. func (l *LayersOverlayFS) Add(layer LayerForMount, key int) error {
  21. l.Lock()
  22. defer l.Unlock()
  23. if _, ok := l.layers[key]; ok {
  24. return fmt.Errorf("key %v exist", key)
  25. }
  26. l.layers[key] = layer
  27. return nil
  28. }
  29. func (l *LayersOverlayFS) Remove(key int) {
  30. l.Lock()
  31. defer l.Unlock()
  32. delete(l.layers, key)
  33. }
  34. /*
  35. mount lower,upper dirs to mountpoint if mountpoint not mounted
  36. TODO: cheack that lower,upper == to already mounted
  37. */
  38. func (l *LayersOverlayFS) Mount() (err error) {
  39. l.RLock()
  40. defer l.RUnlock()
  41. forceRemount := false
  42. var keys []int
  43. for k, _ := range l.layers {
  44. keys = append(keys, k)
  45. }
  46. sort.Ints(keys)
  47. for _, k := range keys {
  48. err = MountLowerUpperLayer(l.layers[k].FSType, l.layers[k].Lower, l.layers[k].Upper, l.layers[k].MountPoint, l.layers[k].MountOptions, forceRemount)
  49. if err != nil {
  50. 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)
  51. }
  52. }
  53. return nil
  54. }
  55. func (l *LayersOverlayFS) GetCFGofLastLayer() LayerForMount {
  56. l.RLock()
  57. defer l.RUnlock()
  58. var keys []int
  59. for k, _ := range l.layers {
  60. keys = append(keys, k)
  61. }
  62. sort.Ints(keys)
  63. lastLayer := keys[len(keys)]
  64. return l.layers[lastLayer]
  65. }
  66. /* unmount only last layer */
  67. func (l *LayersOverlayFS) Umount() (err error) {
  68. l.RLock()
  69. defer l.RUnlock()
  70. forceRemount := false
  71. var keys []int
  72. for k, _ := range l.layers {
  73. keys = append(keys, k)
  74. }
  75. sort.Ints(keys)
  76. lastLayer := keys[len(keys)]
  77. if IsMounted(l.layers[lastLayer].MountPoint, l.layers[lastLayer].FSType) == true {
  78. UnmountLayer(l.layers[lastLayer].FSType, l.layers[lastLayer].MountPoint, forceRemount)
  79. }
  80. return nil
  81. }
  82. func IsMounted (MountPoint,FSType string) bool{
  83. return true
  84. }
  85. func UnmountLayer(FSType,MountPoint string,forceRemount bool) {
  86. }
  87. func MountLowerUpperLayer(fstype, lower, upper, mountpoint, mount_options string, forceremount bool) (err error) {
  88. cmdLayerMount:="mount"
  89. cmd := " -n -t " + " " + fstype + " -o " + mount_options + ",lowerdir=" + lower + "/,upperdir=" + upper + "/ " + fstype + " " + mountpoint + "/"
  90. cmdObject := exec.Command(cmdLayerMount, strings.Fields(cmd)...)
  91. _, err = cmdObject.Output()
  92. if err != nil {
  93. return err
  94. }
  95. return nil
  96. }
  97. func main() {
  98. fmt.Println("Hello, playground")
  99. }

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:

确定