ToB企服应用市场:ToB评测及商务社交产业平台

标题: Golang之文件系统事件监听 [打印本页]

作者: 海哥    时间: 2024-4-9 19:59
标题: Golang之文件系统事件监听
Golang之文件系统事件监听

基本介绍

文件系统事件是指文件系统相关的各种操作和状态变化,当一个应用层的进程操作文件或目录时,会触发system call,内核的notification子系统可以守在那里,把该进程对文件的操作上报给应用层的监听进程。这些事件可以包括文件和目录的创建、修改、删除和文件权限的更改等。
Linux中常用的有两种机制能够监听这些文件事件,分别为inotify和fanotify。
inotify和fanotify最大的区别就是fanotify能够监听到是哪个进程对文件或目录进行操作,并且能够阻止该操作。
fanotify

fanotify:Linux 2.6.37版本引入,能够通知用户哪个进程触发了哪些事件,并且能够对其进行干预。
Golang中fanotify有两个函数:
  1. func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
  2. func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error)
复制代码
函数介绍

示例

[code]package mainimport (        "bytes"        "encoding/binary"        "errors"        "fmt"        "io"        "log"        "os"        "path/filepath"        "unsafe"        "golang.org/x/sys/unix")func handle_perm(initFd int, fanfd int32) error {        fd := unix.FanotifyResponse{                Fd:       fanfd,                Response: uint32(unix.FAN_DENY),        }        buf := new(bytes.Buffer)        err := binary.Write(buf, binary.LittleEndian, fd)        if err != nil {                log.Println(err)        }        ret, err := unix.Write(initFd, buf.Bytes())        if err != nil {                log.Println("handle_perm:err", err)        }        if ret < 0 {                return err        }        return nil}func main() {        path := "/root/testapp2/"        name := filepath.Clean(path)        initFd, err := unix.FanotifyInit(unix.FAN_CLOEXEC|unix.FAN_NONBLOCK|unix.FAN_CLASS_PRE_CONTENT, unix.O_RDONLY)        if err != nil {                log.Panicln("FanotifyInit err : ", err)        }        inotifyFile := os.NewFile(uintptr(initFd), "")        if initFd == -1 {                log.Println("fanFd err", err)        }        defer unix.Close(initFd)        mask := uint64(unix.FAN_EVENT_ON_CHILD | unix.FAN_OPEN_PERM)        err = unix.FanotifyMark(initFd, unix.FAN_MARK_ADD, mask, unix.AT_FDCWD, name)        if err != nil {                log.Panicln("FanotifyMark err : ", err)        }        fmt.Println("start:")        fmt.Println("监控目录:", name)        var (                buf [unix.FAN_EVENT_METADATA_LEN * 4096]byte        )        for {                n, err := inotifyFile.Read(buf[:])                if err != nil {                        continue                }                if n < unix.FAN_EVENT_METADATA_LEN {                        if n == 0 {                                err = io.EOF                        } else if n < 0 {                                err = errors.New("notify: short ")                        } else {                                err = errors.New("notify: short read in readEvents()")                        }                        continue                }                var offset int                for offset




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4