Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Go]Менеджер файловых систем


Автор: weldpua2008 23.11.2014, 10:55
Привет всем
Вопрос: Как реализовать менеджер для работ с файловыми системами.
Детали:
Сами по себе файловые системы имеют различные параметры, от которых зависят комманды для работы с ними. 
Хотя сами комманды унифицированны.

Я начал реализовывать и столкнулся с проблемой: объекты(структуры) в которых храниться файловая система имеют универсальный интерфейс взаимодействия, но внутри они должны быть реализованы по разному.

Примеры:
  • Простой пример:
    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
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)