[LTP] [PATCH 4/4] syscalls/fanotify: New test for FAN_MODIFY_DIR

Amir Goldstein amir73il@gmail.com
Sat May 2 16:58:39 CEST 2020


On Sat, May 2, 2020 at 12:39 PM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> On Tue, Apr 21, 2020 at 09:50:02AM +0300, Amir Goldstein wrote:
> > +void save_fid(const char *path, struct fid_t *fid)
> > +{
> > +     int *fh = (int *)(fid->handle.f_handle);
> > +     int *fsid = fid->fsid.val;
> > +
> > +     fh[0] = fh[1] = fh[2] = 0;
> > +     fid->handle.handle_bytes = MAX_HANDLE_SZ;
> > +     fanotify_get_fid(path, &fid->fsid, &fid->handle);
> > +
> > +     tst_res(TINFO,
> > +             "fid(%s) = %x.%x.%x.%x.%x...",
> > +             path, fsid[0], fsid[1], fh[0], fh[1], fh[2]);
> > +}
>
> What do you think about pulling this out and shoving it in fanotify.h
> as another helper? Perhaps future tests would/could also make use of
> this routine.
>

Ok. And I'll convert fanotify15/fanotify13 to use this helper in another patch.

> > +static void do_test(unsigned int number)
> > +{
> > +     int len = 0, i = 0, test_num = 0;
> > +     int tst_count = 0;
> > +     int fd;
>
> Just shove all these on one line?

ok.

>
> > +     if (fanotify_mark(fd_notify, FAN_MARK_ADD | mark->flag, tc->mask,
> > +                       AT_FDCWD, MOUNT_PATH) < 0) {
> > +             if (errno == EINVAL) {
> > +                     tst_brk(TCONF,
> > +                             "FAN_DIR_MODIFY not supported by kernel");
> > +                     return;
> > +             }
> > +             tst_brk(TBROK | TERRNO,
> > +                 "fanotify_mark (%d, FAN_MARK_ADD | %s, "
> > +                 "FAN_DIR_MODIFY, AT_FDCWD, '"MOUNT_PATH"') "
> > +                 "failed", fd_notify, mark->name);
>
> Should we be adding tc->mask here to the format string output?

Ok.

>
> > +     /*
> > +      * Create subdir and watch open events "on children" with name.
> > +      */
> > +     if (mkdir(dname1, 0755) < 0) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "mkdir('"DIR_NAME1"', 0755) failed");
> > +     }
>
> Perhaps we should be making use of the SAFE_MACROS() so that we're
> adhering to the test writing guidelines?
>

Of course.

> > +     if (tc->sub_mask &&
> > +         fanotify_mark(fd_notify, FAN_MARK_ADD | sub_mark->flag, tc->sub_mask,
> > +                       AT_FDCWD, dname1) < 0) {
> > +             tst_brk(TBROK | TERRNO,
> > +                 "fanotify_mark (%d, FAN_MARK_ADD | %s, "
> > +                 "FAN_DIR_MODIFY | FAN_DELETE_SELF | FAN_ONDIR, "
> > +                 "AT_FDCWD, '%s') "
> > +                 "failed", fd_notify, sub_mark->name, dname1);
> > +     }
>
> Maybe just replace the statically typed mask here with tc->sub_mask?
> That way, if test cases are added or modified in the future, you don't
> have to update it?
>

Sure.

> > +     if ((fd = creat(fname1, 0755)) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                     "creat(\"%s\", 755) failed", FILE_NAME1);
> > +     }
> > +
> > +     if (rename(fname1, fname2) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "rename(%s, %s) failed",
> > +                             FILE_NAME1, FILE_NAME2);
> > +     }
> > +
> > +     if (close(fd) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "close(%s) failed", FILE_NAME2);
> > +     }
> > +
> > +     /* Generate delete events with fname2 */
> > +     if (unlink(fname2) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "unlink(%s) failed", FILE_NAME2);
> > +     }
>
> The same applies with the above set of system calls?
>
> ...
>
> > +     if (rename(dname1, dname2) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "rename(%s, %s) failed",
> > +                             DIR_NAME1, DIR_NAME2);
> > +     }
> > +
> > +     if (rmdir(dname2) == -1) {
> > +             tst_brk(TBROK | TERRNO,
> > +                             "rmdir(%s) failed", DIR_NAME2);
> > +     }
>
>
> And here...
>
> > +     while (i < len) {
> > +             struct event_t *expected = &event_set[test_num];
> > +             struct fanotify_event_metadata *event;
> > +             struct fanotify_event_info_fid *event_fid;
> > +             struct file_handle *file_handle;
> > +             unsigned int fhlen;
> > +             const char *filename;
> > +             int namelen, info_type;
> > +
> > +             event = (struct fanotify_event_metadata *)&event_buf[i];
> > +             event_fid = (struct fanotify_event_info_fid *)(event + 1);
> > +             file_handle = (struct file_handle *)event_fid->handle;
> > +             fhlen = file_handle->handle_bytes;
> > +             filename = (char *)file_handle->f_handle + fhlen;
> > +             namelen = ((char *)event + event->event_len) - filename;
> > +             /* End of event could have name, zero padding, both or none */
> > +             if (namelen > 0) {
> > +                     namelen = strlen(filename);
> > +             } else {
> > +                     filename = "";
> > +                     namelen = 0;
> > +             }
> > +             if (expected->name[0]) {
> > +                     info_type = FAN_EVENT_INFO_TYPE_DFID_NAME;
> > +             } else {
> > +                     info_type = FAN_EVENT_INFO_TYPE_FID;
> > +             }
>
> Can we line break these conditional statements?
>

ok.

> ...
>
> > +static void setup(void)
> > +{
>
>         int fd;
>
>         fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, 0_RDONLY);
>         SAFE_CLOSE(fd);
>
> Above snippet missing from test bootstrap? I remember we had to add
> this in the past, but I can't remember the _why_?
>

Because, if kernel does not support fanotify, we want the test
to fail on setup with "fanotify is not configured in this kernel."
instead of inaccurately reporting later:
"FAN_REPORT_FID not supported by kernel".

Thanks a lot for the review,
Amir.


More information about the ltp mailing list