1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2021, Collabora Ltd.
12 #include <sys/fanotify.h>
13 #include <sys/types.h>
17 #define FAN_FS_ERROR 0x00008000
18 #define FAN_EVENT_INFO_TYPE_ERROR 5
20 struct fanotify_event_info_error
{
21 struct fanotify_event_info_header hdr
;
27 #ifndef FILEID_INO32_GEN
28 #define FILEID_INO32_GEN 1
31 #ifndef FILEID_INVALID
32 #define FILEID_INVALID 0xff
35 static void print_fh(struct file_handle
*fh
)
38 uint32_t *h
= (uint32_t *) fh
->f_handle
;
41 for (i
= 0; i
< fh
->handle_bytes
; i
++)
42 printf("%hhx", fh
->f_handle
[i
]);
45 printf("\tdecoded fh: ");
46 if (fh
->handle_type
== FILEID_INO32_GEN
)
47 printf("inode=%u gen=%u\n", h
[0], h
[1]);
48 else if (fh
->handle_type
== FILEID_INVALID
&& !fh
->handle_bytes
)
49 printf("Type %d (Superblock error)\n", fh
->handle_type
);
51 printf("Type %d (Unknown)\n", fh
->handle_type
);
55 static void handle_notifications(char *buffer
, int len
)
57 struct fanotify_event_metadata
*event
=
58 (struct fanotify_event_metadata
*) buffer
;
59 struct fanotify_event_info_header
*info
;
60 struct fanotify_event_info_error
*err
;
61 struct fanotify_event_info_fid
*fid
;
64 for (; FAN_EVENT_OK(event
, len
); event
= FAN_EVENT_NEXT(event
, len
)) {
66 if (event
->mask
!= FAN_FS_ERROR
) {
67 printf("unexpected FAN MARK: %llx\n",
68 (unsigned long long)event
->mask
);
72 if (event
->fd
!= FAN_NOFD
) {
73 printf("Unexpected fd (!= FAN_NOFD)\n");
77 printf("FAN_FS_ERROR (len=%d)\n", event
->event_len
);
79 for (off
= sizeof(*event
) ; off
< event
->event_len
;
81 info
= (struct fanotify_event_info_header
*)
82 ((char *) event
+ off
);
84 switch (info
->info_type
) {
85 case FAN_EVENT_INFO_TYPE_ERROR
:
86 err
= (struct fanotify_event_info_error
*) info
;
88 printf("\tGeneric Error Record: len=%d\n",
90 printf("\terror: %d\n", err
->error
);
91 printf("\terror_count: %d\n", err
->error_count
);
94 case FAN_EVENT_INFO_TYPE_FID
:
95 fid
= (struct fanotify_event_info_fid
*) info
;
97 printf("\tfsid: %x%x\n",
98 fid
->fsid
.val
[0], fid
->fsid
.val
[1]);
99 print_fh((struct file_handle
*) &fid
->handle
);
103 printf("\tUnknown info type=%d len=%d:\n",
104 info
->info_type
, info
->len
);
112 int main(int argc
, char **argv
)
119 printf("Missing path argument\n");
123 fd
= fanotify_init(FAN_CLASS_NOTIF
|FAN_REPORT_FID
, O_RDONLY
);
125 errx(1, "fanotify_init");
127 if (fanotify_mark(fd
, FAN_MARK_ADD
|FAN_MARK_FILESYSTEM
,
128 FAN_FS_ERROR
, AT_FDCWD
, argv
[1])) {
129 errx(1, "fanotify_mark");
133 int n
= read(fd
, buffer
, BUFSIZ
);
138 handle_notifications(buffer
, n
);