Привет всем Вопрос: Как реализовать менеджер для работ с файловыми системами. Детали:Сами по себе файловые системы имеют различные параметры, от которых зависят комманды для работы с ними. Хотя сами комманды унифицированны. Я начал реализовывать и столкнулся с проблемой: объекты(структуры) в которых храниться файловая система имеют универсальный интерфейс взаимодействия, но внутри они должны быть реализованы по разному. Примеры: - Простой пример:
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 - Принимает 2-е директории а не одну:
mount -t overlayfs -o rw,lowerdir=/low-layer,upperdir=/hilayer overlayfs /overlayfs find /overlayfs -lname '(overlay-whiteout)' -exec rm -rf {} \;
По сути дела у каждой файловой системы есть два состояния: смонтирована не смонтирована И над каждой можно провести: mount() unmount() iSmount() ЗЫ: Мой код play.golang.org/p/Ri5yAqsLu7 на Го. В котором я реализовал работу только с OverlayFS Код | package layers
import ( "fmt" "sort" "sync" "os/exec" "strings" )
// один слой OverlayFS type LayerForMount struct { Upper string Lower string MountPoint string MountOptions string FSType string }
// менеджер слоев OverlayFS 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) }
// монтирование слоя 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 }
|
|