12 #include <sys/fanotify.h>
15 void usage(const char *progname)
17 const char *base, *msg;
19 base = strrchr(progname, '/');
25 fprintf(stderr, "Usage:\n");
26 fprintf(stderr, " %s LUSTRE_MOUNT_DIR\n", base);
27 fprintf(stderr, "\n");
31 " Monitor some file operations on a lustre fs. Report the events as below:\n"
32 " <events>:<lustre_file>:<pid>:[<command>]\n"
34 " <events> is 1 event or multiple events separated by '&'. For example,\n"
35 " 'open', 'write&close'. Currently only these events are\n"
41 " <lustre_file> is the file to be operated.\n"
42 " <pid> is the process id who operates the file.\n"
43 " <command> is the command who operates the file. It is reported only if\n"
44 " the process is still running so it can be found from pid.\n"
46 fprintf(stderr, "%s", msg);
49 void print_event(struct fanotify_event_metadata *metadata)
52 char procfd_path[PATH_MAX], path[PATH_MAX], cmd_file[PATH_MAX];
53 int path_len, cmd_fd, cmd_len;
56 if (metadata->mask & FAN_OPEN) {
60 if (metadata->mask & FAN_ACCESS) {
66 if (metadata->mask & FAN_MODIFY) {
72 if (metadata->mask & FAN_CLOSE) {
80 // print the name of the file
81 snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
83 path_len = readlink(procfd_path, path, sizeof(path) - 1);
85 fprintf(stderr, "failed to read link target of %s. %d:%s\n",
86 procfd_path, errno, strerror(errno));
89 path[path_len] = '\0';
94 printf("%d:", metadata->pid);
96 // try to print the cmdline of process
97 snprintf(cmd_file, sizeof(cmd_file), "/proc/%d/cmdline", metadata->pid);
98 cmd_fd = open(cmd_file, O_RDONLY);
100 // reuse cmd_file as buffer
101 cmd_len = read(cmd_fd, cmd_file, sizeof(cmd_file) - 1);
103 cmd_file[cmd_len] = '\0';
104 printf("%s", cmd_file);
112 int main(int argc, char *argv[])
116 struct fanotify_event_metadata buf[256], *metadata;
124 fd = fanotify_init(FAN_CLASS_CONTENT, O_RDONLY | O_LARGEFILE);
126 fprintf(stderr, "failed to init fanotify. %d:%s\n", errno,
131 mask = FAN_OPEN | FAN_ACCESS | FAN_MODIFY | FAN_CLOSE;
132 rc = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT, mask, AT_FDCWD,
136 "failed to open watch descriptor on %s. %d:%s\n",
137 argv[1], errno, strerror(errno));
142 len = read(fd, (void *)&buf[0], sizeof(buf));
143 if (len < 0 && errno != EAGAIN) {
145 "failed to read from fanotiify file descriptor."
147 errno, strerror(errno));
154 while (FAN_EVENT_OK(metadata, len)) {
155 /* Check run-time and compile-time structures match */
156 if (metadata->vers != FANOTIFY_METADATA_VERSION) {
157 fprintf(stderr, "Mismatch of fanotify "
158 "metadata version.\n");
162 if (metadata->fd >= 0) {
163 print_event(metadata);
166 metadata = FAN_EVENT_NEXT(metadata, len);