Created
October 1, 2021 16:20
-
-
Save leveryd/9cd91c93fd6361b163291c1e5e4481da to your computer and use it in GitHub Desktop.
自制文件系统
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 实现一个叫做 hellofs 的文件系统 | |
// https://mp.weixin.qq.com/s?__biz=Mzg3NTU3OTgxOA==&mid=2247491246&idx=1&sn=d4b50e713618b10e44a6925ab9305706&chksm=cf3e0e6bf849877df80ad428f881ad989c6cc8387dd88b6510c8d80c40aa3789c4b27c6ba7d7&cur_album_id=1819478029098663939&scene=189#rd | |
package main | |
import ( | |
"context" | |
"flag" | |
"log" | |
"os" | |
"syscall" | |
"bazil.org/fuse" | |
"bazil.org/fuse/fs" | |
_ "bazil.org/fuse/fs/fstestutil" | |
) | |
func main() { | |
var mountpoint string | |
flag.StringVar(&mountpoint, "mountpoint", "", "mount point(dir)?") | |
flag.Parse() | |
if mountpoint == "" { | |
log.Fatal("please input invalid mount point\n") | |
} | |
// 建立一个负责解析和封装 FUSE 请求监听通道对象; | |
// c, err := fuse.Mount(mountpoint, fuse.FSName("helloworld"), fuse.Subtype("hellofs")) | |
c, err := fuse.Mount(mountpoint, fuse.FSName("proc"), fuse.Subtype("proc")) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer c.Close() | |
// 把 FS 结构体注册到 server,以便可以回调处理请求 | |
err = fs.Serve(c, FS{}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
// hellofs 文件系统的主体 | |
type FS struct{} | |
func (FS) Root() (fs.Node, error) { | |
return Dir{}, nil | |
} | |
// hellofs 文件系统中,Dir 是目录操作的主体 | |
type Dir struct{} | |
func (Dir) Attr(ctx context.Context, a *fuse.Attr) error { | |
a.Inode = 20210601 | |
a.Mode = os.ModeDir | 0555 | |
return nil | |
} | |
// 当 ls 目录的时候,触发的是 ReadDirAll 调用,这里返回指定内容,表明只有一个 hello 的文件; | |
func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { | |
// 只处理一个叫做 hello 的 entry 文件,其他的统统返回 not exist | |
if name == "hello" { | |
return File{}, nil | |
} | |
return nil, syscall.ENOENT | |
} | |
// 定义 Readdir 的行为,固定返回了一个 inode:2 name 叫做 hello 的文件。对应用户的行为一般是 ls 这个目录。 | |
func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { | |
var dirDirs = []fuse.Dirent{{Inode: 2, Name: "hello", Type: fuse.DT_File}} | |
return dirDirs, nil | |
} | |
// hellofs 文件系统中,File 结构体实现了文件系统中关于文件的调用实现 | |
type File struct{} | |
const fileContent = "hello, world\n" | |
const evilContent = "system\n" | |
// 当 stat 这个文件的时候,返回 inode 为 2,mode 为 444 | |
func (File) Attr(ctx context.Context, a *fuse.Attr) error { | |
a.Inode = 20210606 | |
a.Mode = 0444 | |
a.Size = uint64(len(fileContent)) | |
return nil | |
} | |
// 当 cat 这个文件的时候,文件内容返回 hello,world | |
func (File) ReadAll(ctx context.Context) ([]byte, error) { | |
_, err := os.Stat("/tmp/flag") | |
if err!= nil { | |
return []byte(evilContent), nil | |
} | |
return []byte(fileContent), nil | |
} |
Author
leveryd
commented
Oct 1, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment