dwatch/scheme.md

73 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

```mermaid
sequenceDiagram
%%{init: { 'theme': 'default', 'themeVariables': {
'primaryColor': '#ff0000',
'nodeTextColor': '#ffffff',
'edgeLabelBackground': '#f0f0f0'
}}}%%
autonumber
participant Watcher as Демон-наблюдатель
participant Kernel as Ядро (fanotify)
participant Editor as Процесс-редактор (PID X)
participant FS as Файловая система (целевой каталог/файл)
participant Ep as epoll
participant Pfd as pidfd(PID X)
participant Map as Карта соответствий (в памяти)
participant ChLog as Журнал изменений
Note over Watcher: Инициализация
Watcher->>Kernel: fanotify_init(PRE_CONTENT|NONBLOCK|CLOEXEC, O_RDONLY|O_CLOEXEC|O_LARGEFILE)
Watcher->>Kernel: fanotify_mark(ADD|ONLYDIR, EVENT_ON_CHILD|(OPEN[_EXEC]_PERM)|OPEN|CLOSE_WRITE, watchDir)
Watcher->>Ep: add(fanotify_fd, tag=FAN)
Note over Editor: Запрос доступа к файлу
Editor->>FS: open(target, O_RDONLY/O_RDWR/EXEC)
FS-->>Kernel: системный вызов доступа
Kernel-->>Watcher: PERM-событие (+fd, mask, pid)
Note over Watcher: Сбор контекста
Watcher->>FS: fstat(fd) → (inode, dev)
FS-->>Watcher: inode, dev
Watcher->>Watcher: readlink(/proc/self/fd/FD) → file_path_open
Watcher->>Watcher: read /proc/PID/{comm,status} → proc_name, RUID, UID(EUID)
%% КЛАДЁМ СВЯЗКУ
Watcher->>Map: PUT key=(PID,inode,dev), val={proc_name,RUID,UID,file_path_open,changed=false}
Note over Map: Добавлена связка key=(PID,inode,dev)
%% pidfd и epoll
Watcher->>Pfd: pidfd_open(PID, flags=0)
Pfd-->>Watcher: pidfd
Watcher->>Ep: add(pidfd, tag=PID, events=IN|HUP|RDHUP|ERR)
%% Разрешаем доступ
Watcher->>Kernel: fanotify_response{fd, FAN_ALLOW}
Watcher->>FS: close(fd)
Note over Editor: Работа с файлом
Editor->>FS: write(...)
Editor->>FS: close()
Kernel-->>Watcher: CLOSE_WRITE (+fd)
Note over Watcher: Фиксация факта изменения
Watcher->>FS: fstat(fd) → (inode, dev)
FS-->>Watcher: inode, dev
Watcher->>Map: GET key=(PID,inode,dev)
Map-->>Watcher: {…}
Watcher->>Map: SET changed=true
Watcher->>FS: close(fd)
Note over Editor: Завершение процесса
Editor->>Editor: exit()
Pfd-->>Ep: EPOLLIN/HUP (pid завершён)
Ep-->>Watcher: событие(tag=PID)
%% ПИШЕМ ЖУРНАЛ И ЧИСТИМ
Watcher->>Map: GET_ALL where pid=PID
Map-->>Watcher: список записей
Watcher->>ChLog: APPEND для всех changed=true → {proc=proc_name, file=file_path_open, uid=UID, ruid=RUID}
Watcher->>Ep: remove(pidfd)
Watcher->>Pfd: close(pidfd)
Watcher->>Map: DELETE_ALL where pid=PID
Note over Map: Удалены все связки для PID
```