15

メモリに保存される単純な FUSE ファイルシステムを記述します。ファイルシステムは、次のコマンドをサポートする必要があります。

ls、mkdir、cp

この質問は最近インタビューで聞かれましたが、私は答えることができませんでした。だから私はそれを学ぶことにしました。

いくつかの検索を行い、独自の FUSE ファイルシステムの構築に関するガイドを見つけました。ファイルシステムをメモリに実装する方法について、私は本当に無知です。

私の質問は

  • 私は正しい方向に向かっていますか?
  • 他に何を読むべきですか?
  • 解決策は何ですか?

私が読んでいるリンク:

最後のリンクには、PyFileSystemを使用したメモリ内キャッシュに関する言及があります。それがどのように役立つかはわかりません。

PS : これは筆記面接の質問なので、答えは 10 ~ 15 分以内に紙に書き込めるほどシンプルなものにする必要があります。

4

2 に答える 2

5

Frangipaniに似た設計のメモリ内分散ファイル システムを構築するコースを受講しました。このコースは、 MIT の分散システム コースから大きな影響を受けました。最初のいくつかのラボの割り当てを行うことは、良い練習になるでしょう。

このチュートリアルも非常に役立ちます。

于 2012-01-27T00:07:04.707 に答える
5

プログラミング言語を指定しませんでしたが、FUSE はネイティブ C++ ですが、ネイティブの Golang バインディングが bazil.org/fuse に実装されています

回答の主要な部分には、次のものが含まれている必要があると思います。

  1. メモリ内のファイル システム ツリーを処理するためのデータ構造
  2. ノードの説明と iNode との関係
  3. cli コマンドを処理するための FUSE サーバー要求をキャプチャするためのフック
  4. FUSE サーバーでフォルダーをマウントする方法の説明。

私は最近、このアダプターを使用してメモリ内ファイル システムを作成しました: github.com/bbengfort/memfs。そのパフォーマンスに関する私の記事はこちら: In-Memory File System with FUSE . すぐに、私が行ったいくつかの選択:

インメモリ データ構造には、両方のノードである dir と file の 2 つの主要な構造体が含まれています。

type Node struct {
    ID uint64 
    Name string 
    Attrs fuse.Attr 
    Parent *Dir 
}

type Dir struct {
    Node
    Children map[string]Node
}

type File struct {
    Node
    Data []byte 
}

Childrenご覧のとおり、これは単純なツリーで、 リンクとリンクを上下にたどることができParentます。FileのData属性は、ファイルのすべての内容を保持します。したがって、ファイル システムは"\"、マウント ポイントで呼び出される「ルート」ディレクトリを作成するだけで済みます。次に、mkdiraDirがその子に追加されcp、aFileが追加されます。Go では、これは次のように簡単です。

type FS struct {
    root *Dir 
}

func Mount(path string) error {

    // Unmount the FS in case it was mounted with errors.
    fuse.Unmount(path)

    // Mount the FS with the specified options
    conn, err := fuse.Mount(path)
    if err != nil {
        return err
    }

    // Ensure that the file system is shutdown
    defer conn.Close()

    // Create the root dir and file system 
    memfs := FS{
        root: &Dir{
            ID: 1, 
            Name: "\", 
            Parent: nil, 
        },
    }

    // Serve the file system
    if err := fs.Serve(conn, memfs); err != nil {
        return err
    }
}

ここで、さまざまな FUSE リクエストと呼び出しを実装するためのフックが必要です。の例を次に示しmkdirます。

func (d *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
    // Update the directory Atime
    d.Attrs.Atime = time.Now()

    // Create the child directory
    c := new(Dir)
    c.Init(req.Name, req.Mode, d)

    // Set the directory's UID and GID to that of the caller
    c.Attrs.Uid = req.Header.Uid
    c.Attrs.Gid = req.Header.Gid

    // Add the directory to the directory
    d.Children[c.Name] = c

    // Update the directory Mtime
    d.Attrs.Mtime = time.Now()

    return c, nil
}

最後に、サーバーをコンパイルして実行する方法、パスにマウントする方法、およびおそらく FUSE がカーネル呼び出しをインターセプトしてユーザー空間のプロセスに渡す方法について説明して、インタビューの質問を締めくくります。

于 2017-02-05T14:42:26.913 に答える