From patchwork Sat Apr 20 12:49:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1088389 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="NavnczyY"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44mXk23fXhz9s5c for ; Sat, 20 Apr 2019 22:50:01 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id ED6D53EA193 for ; Sat, 20 Apr 2019 14:49:54 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-2.smtp.seeweb.it (in-2.smtp.seeweb.it [IPv6:2001:4b78:1:20::2]) by picard.linux.it (Postfix) with ESMTP id 3EC943EA0CD for ; Sat, 20 Apr 2019 14:49:53 +0200 (CEST) Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-2.smtp.seeweb.it (Postfix) with ESMTPS id DB4C1600AAF for ; Sat, 20 Apr 2019 14:49:51 +0200 (CEST) Received: by mail-pg1-x543.google.com with SMTP id j26so3816629pgl.5 for ; Sat, 20 Apr 2019 05:49:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=xCP2LmgC942gdku/871L8R9CZSkXu8nYzIT0B8JDUAI=; b=NavnczyY1ZYpStil/EVZrGB1ZbOi6peJEaAomSTdAmTqaWDo61GEBOeMSPyEbC4BcW XwdoFZU6uzZ7RF42xgdoWhY6HWFfSeYfq83ve7D2HusaauKaAohqkqXprUExrkgoEUIC 30qi/6MS3zaSmN42nbrxXiL08NKIYSt19XakkoULskVOM+jb8C2/CTvVq+KfQSJMwJlW 1Y8AVy5SjBLrU/oLW+kyBcHBuggMQJaaeUNC/LT7xdurD0KwwbYY1lBf29qCdgRNMp/i w5EIYrr7JQdwP78wyE3+GJTeOlnm5kFVUBI4uz12hrjJUTc3bRli0uXDX8D9JrgbDIAp ZAYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=xCP2LmgC942gdku/871L8R9CZSkXu8nYzIT0B8JDUAI=; b=mxFOxlWLaW6doWpPI11qN8uUIjCwZsJPm1DsXG3jWgSf6AgaZVaSRWq8JlVHRitxh5 TIJc2Xfszhy+ZxzsgYY/VfisC6M/QWm+t35dUaiiTZpBhi5jJ5eZLyu3XajRqvIWS5i3 yukI3EGUMBa+h8S0lhYSubXWJKmSEp5Ia3cWzBnxvMp9nz8IYjUmR1KnCHkTGHUV1CP7 tkTRhUSUcRCumh5vr+aBAFe/KNRgs6nhoYhxbGxiYg0tFwh818KNFpRsgv6z+kqNDJe5 0jPiVMNROKH2ocvFdgLMcg3pVuC26jxL6a+LXBluiKduuzbRsjfj32G9ZyGMMuwR5U26 vNiA== X-Gm-Message-State: APjAAAXLs3yADmSEela1k+awmtQJhzGbiPyzbSUHL8km+ti3XaoJC0uE HNbEHCdZ6t0yacGL82ABdiYWy8MpfQ== X-Google-Smtp-Source: APXvYqzvGoQbNa9KvaYO0+q79ZKfEpQxMI+a+wYbtA4OZEUMiELfjVe6DS2TzNtNalVCpCnWPyF4fw== X-Received: by 2002:aa7:8edd:: with SMTP id b29mr9860967pfr.241.1555764590027; Sat, 20 Apr 2019 05:49:50 -0700 (PDT) Received: from lithium.mbobrowski.org ([103.230.158.220]) by smtp.gmail.com with ESMTPSA id 10sm10499804pfh.14.2019.04.20.05.49.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Apr 2019 05:49:49 -0700 (PDT) Date: Sat, 20 Apr 2019 22:49:43 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: <6639dd7a9ff9929ce79f4f353f3e1db075594ea2.1555763787.git.mbobrowski@mbobrowski.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Virus-Scanned: clamav-milter 0.99.2 at in-2.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-2.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" Newly defined test file to validate the fanotify FAN_REPORT_FID functionality. A new line entry for this test file has been added within runtest/syscalls. Additionally, defined a helper function that can be used to obtain __kernel_fsid_t and file_handle objects. This helper will be used by tests related to FAN_REPORT_FID. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify.h | 52 +++- testcases/kernel/syscalls/fanotify/fanotify13.c | 313 ++++++++++++++++++++++++ 4 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify13.c diff --git a/runtest/syscalls b/runtest/syscalls index 2b8ca71..dfdc6cb 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -537,6 +537,7 @@ fanotify09 fanotify09 fanotify10 fanotify10 fanotify11 fanotify11 fanotify12 fanotify12 +fanotify13 fanotify13 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index 4256b8c..16bdd99 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -10,4 +10,5 @@ /fanotify10 /fanotify11 /fanotify12 +/fanotify13 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h index 14654b7..e9b23cc 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify.h +++ b/testcases/kernel/syscalls/fanotify/fanotify.h @@ -29,6 +29,11 @@ #define __FANOTIFY_H__ #include "config.h" +#include +#include +#include +#include +#include #if defined(HAVE_SYS_FANOTIFY_H) @@ -57,9 +62,6 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask, #ifndef FAN_REPORT_TID #define FAN_REPORT_TID 0x00000100 #endif -#ifndef FAN_REPORT_FID -#define FAN_REPORT_FID 0x00000200 -#endif #ifndef FAN_MARK_INODE #define FAN_MARK_INODE 0 @@ -89,6 +91,50 @@ struct fanotify_mark_type { const char * name; }; +#ifndef FAN_REPORT_FID +#define FAN_REPORT_FID 0x00000200 + +struct fanotify_event_info_header { + uint8_t info_type; + uint8_t pad; + uint16_t len; +}; + +struct fanotify_event_info_fid { + struct fanotify_event_info_header hdr; + __kernel_fsid_t fsid; + unsigned char handle[0]; +}; + +/* + * Helper function used to obtain __kernel_fsid_t and file_handle objects + * for a given path. Used by test files correlated to FAN_REPORT_FID + * functionality. + */ +static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid, + struct file_handle *handle) +{ + int mount_id; + struct statfs stats; + + if (statfs(path, &stats) == -1) + tst_brk(TBROK | TERRNO, + "statfs(%s, ...) failed", path); + memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid)); + + if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) { + if (errno == EOPNOTSUPP) { + tst_res(TCONF, + "filesystem %s does not support file handles", + tst_device->fs_type); + } + tst_brk(TBROK | TERRNO, + "name_to_handle_at(AT_FDCWD, %s, ...) failed", path); + } +} + +#endif + #define INIT_FANOTIFY_MARK_TYPE(t) \ { FAN_MARK_ ## t, "FAN_MARK_" #t } diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c new file mode 100644 index 0000000..820f139 --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify13.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved. + * + * Started by Matthew Bobrowski + * + * DESCRIPTION + * Validate that the values returned within an event when + * FAN_REPORT_FID is specified matches those that are obtained via + * explicit invocation to system calls statfs(2) and + * name_to_handle_at(2). + */ +#define _GNU_SOURCE +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tst_test.h" +#include "fanotify.h" + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define PATH_LEN 128 +#define BUF_SIZE 256 +#define DIR_ONE "dir_one" +#define FILE_ONE "file_one" +#define FILE_TWO "file_two" +#define MOUNT_PATH "mntpoint" +#define EVENT_MAX ARRAY_SIZE(objects) +#define DIR_PATH_ONE MOUNT_PATH"/"DIR_ONE +#define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE +#define FILE_PATH_TWO MOUNT_PATH"/"FILE_TWO + +struct event_t { + unsigned long long expected_mask; + __kernel_fsid_t fsid; + struct file_handle handle; + char buf[MAX_HANDLE_SZ]; +}; + +static struct object_t { + const char *path; + int is_dir; +} objects[] = { + {FILE_PATH_ONE, 0}, + {FILE_PATH_TWO, 0}, + {DIR_PATH_ONE, 1} +}; + +static struct test_case_t { + struct fanotify_mark_type mark; + unsigned long long mask; +} test_cases[] = { + { + INIT_FANOTIFY_MARK_TYPE(INODE), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(INODE), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + }, + { + INIT_FANOTIFY_MARK_TYPE(MOUNT), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(MOUNT), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + }, + { + INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + } +}; + +static int fanotify_fd; +static char events_buf[BUF_SIZE]; +static struct event_t event_set[EVENT_MAX]; + +static void create_objects(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (objects[i].is_dir) + SAFE_MKDIR(objects[i].path, 0755); + else + SAFE_FILE_PRINTF(objects[i].path, "0"); + } +} + +static void get_object_stats(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(objects); i++) { + event_set[i].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(objects[i].path, &event_set[i].fsid, + &event_set[i].handle); + } +} + +static void do_setup(void) +{ + int fd; + + /* Check for kernel fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + /* Create file and directory objects for testing */ + create_objects(); + + /* Get the filesystem fsid and file handle for each created object */ + get_object_stats(); +} + + +static int setup_marks(unsigned int fd, struct test_case_t *tc) +{ + unsigned int i; + struct fanotify_mark_type *mark = &tc->mark; + + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (fanotify_mark(fd, FAN_MARK_ADD | mark->flag, tc->mask, + AT_FDCWD, objects[i].path) == -1) { + if (errno == EINVAL && + mark->flag & FAN_MARK_FILESYSTEM) { + tst_res(TCONF, + "FAN_MARK_FILESYSTEM not supported by " + "kernel"); + return 1; + } else if (errno == ENODEV && + !event_set[i].fsid.val[0] && + !event_set[i].fsid.val[1]) { + tst_res(TCONF, + "FAN_REPORT_FID not supported on " + "filesystem type %s", + tst_device->fs_type); + return 1; + } + tst_brk(TBROK | TERRNO, + "fanotify_mark(%d, FAN_MARK_ADD, FAN_OPEN, " + "AT_FDCWD, %s) failed", + fanotify_fd, objects[i].path); + } + + /* Setup the expected mask for each generated event */ + event_set[i].expected_mask = tc->mask; + if (!objects[i].is_dir) + event_set[i].expected_mask &= ~FAN_ONDIR; + } + return 0; +} + +static void do_test(unsigned int number) +{ + unsigned int i; + int len, fds[ARRAY_SIZE(objects)]; + + struct file_handle *event_file_handle; + struct fanotify_event_metadata *metadata; + struct fanotify_event_info_fid *event_fid; + struct test_case_t *tc = &test_cases[number]; + struct fanotify_mark_type *mark = &tc->mark; + + tst_res(TINFO, + "Test #%d: FAN_REPORT_FID with mark flag: %s", + number, mark->name); + + fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY); + if (fanotify_fd == -1) { + if (errno == EINVAL) { + tst_res(TCONF, + "FAN_REPORT_FID not supported by kernel"); + return; + } + tst_brk(TBROK | TERRNO, + "fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, " + "O_RDONLY) failed"); + } + + /* Place marks on a set of objects and setup the expected masks + * for each event that is expected to be generated + */ + if (setup_marks(fanotify_fd, tc) != 0) + return; + + /* Generate sequence of FAN_OPEN events on objects */ + for (i = 0; i < ARRAY_SIZE(objects); i++) + fds[i] = SAFE_OPEN(objects[i].path, O_RDONLY); + + /* Generate sequence of FAN_CLOSE_NOWRITE events on objects. Each + * FAN_CLOSE_NOWRITE event is expected to be merged with its + * respective FAN_OPEN event that was performed on the same object + */ + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (fds[i] > 0) + SAFE_CLOSE(fds[i]); + } + + /* Read events from event queue */ + len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE); + + /* Iterate over event queue */ + for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf; + FAN_EVENT_OK(metadata, len); + metadata = FAN_EVENT_NEXT(metadata, len), i++) { + event_fid = (struct fanotify_event_info_fid *) (metadata + 1); + event_file_handle = (struct file_handle *) event_fid->handle; + + /* File descriptor is redundant with FAN_REPORT_FID */ + if (metadata->fd != FAN_NOFD) + tst_res(TFAIL, + "Unexpectedly received file descriptor %d in " + "event. Expected to get FAN_NOFD(%d)", + metadata->fd, FAN_NOFD); + + /* Ensure that the correct mask has been reported in event */ + if (metadata->mask != event_set[i].expected_mask) + tst_res(TFAIL, + "Unexpected mask received: %llx (expected: " + "%llx) in event", + metadata->mask, + event_set[i].expected_mask); + + /* Verify handle_bytes returned in event */ + if (event_file_handle->handle_bytes + != event_set[i].handle.handle_bytes) { + tst_res(TFAIL, + "handle_bytes (%x) returned in event does not " + "equal to handle_bytes (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_bytes, + event_set[i].handle.handle_bytes); + continue; + } + + /* Verify handle_type returned in event */ + if (event_file_handle->handle_type != + event_set[i].handle.handle_type) { + tst_res(TFAIL, + "handle_type (%x) returned in event does not " + "equal to handle_type (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_type, + event_set[i].handle.handle_type); + continue; + } + + /* Verify file identifier f_handle returned in event */ + if (memcmp(event_file_handle->f_handle, + event_set[i].handle.f_handle, + event_set[i].handle.handle_bytes) != 0) { + tst_res(TFAIL, + "event_file_handle->f_handle does not match " + "event_set[i].handle.f_handle returned in " + "name_to_handle_at(2)"); + continue; + } + + /* Verify filesystem ID fsid returned in event */ + if (memcmp(&event_fid->fsid, &event_set[i].fsid, + sizeof(event_set[i].fsid)) != 0) { + tst_res(TFAIL, + "event_fid.fsid != stat.f_fsid that was " + "obtained via statfs(2)"); + continue; + } + + tst_res(TPASS, + "got event: mask=%llx, pid=%d, fid=%x.%x.%lx values " + "returned in event match those returned in statfs(2) " + "and name_to_handle_at(2)", + metadata->mask, + getpid(), + event_fid->fsid.val[0], + event_fid->fsid.val[1], + *(unsigned long *) event_file_handle->f_handle); + } +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .setup = do_setup, + .test = do_test, + .tcnt = ARRAY_SIZE(test_cases), + .cleanup = do_cleanup, + .needs_root = 1, + .needs_tmpdir = 1, + .mount_device = 1, + .mntpoint = MOUNT_PATH, + .all_filesystems = 1 +}; + +#else + TST_TEST_CONF("System does not have required fanotify support"); +#endif From patchwork Sat Apr 20 12:50:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1088390 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="n+rV1wYr"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44mXkH4Dqrz9s5c for ; Sat, 20 Apr 2019 22:50:15 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id B6FA63EA0CD for ; Sat, 20 Apr 2019 14:50:12 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id A5E113EA0CD for ; Sat, 20 Apr 2019 14:50:10 +0200 (CEST) Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id A1BE42009A0 for ; Sat, 20 Apr 2019 14:50:09 +0200 (CEST) Received: by mail-pf1-x443.google.com with SMTP id t21so3694173pfh.2 for ; Sat, 20 Apr 2019 05:50:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=wDF9M4X19Qsp5PJ72U812rJ+PuwFLm2AqSamCwjhrR4=; b=n+rV1wYrClxzFTg8FPUvpnLa/NYAwkTSxIszzk301qJmQKOeYYLK82SXb41U+T5bzh GGXS7VG1p42lYrhObrIO6EB/9LG7+FzsLZuFoMcLqcEWDyc7N0m1ItMUsJM518IKVwJk HhfF4h4INeM53eD4SwA5xMUai05HsOQ1W7AJHzK/Mw6oDZhtJrsKJMo7ibjUz4z8tEny cg5ukfeLtVIAmYwDvaoR/oBGcsW/jpqQiJGtlfuIIrjIf85KveG0mZh8q7gV02Rp9roU McNDoP694FChhwDnsLR30hd7HCXs8LjxPsmdWeJeQyMpN5LEQj2Wndg2yrmXty8LqgUT UCzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=wDF9M4X19Qsp5PJ72U812rJ+PuwFLm2AqSamCwjhrR4=; b=j/fl1IWYQIPiSyyGhtAmECPFHK2to+itDIoxb0SfMeuUbc9Euap9XkgGoeGD2GqIFy TxNcMynWP7EibL7YLHqnQa6k+xxC4uJJwz6wtPl3X8/PavVJz/yDGKleVwav5ArT/oEz QC2GTsf6q/e8m5MIyRQy9NOd03W68HhtPjodEdhgbKW2JBW4HuDelktEP64C6+/iln/h dFKb3V8jwK8Flk8fxpIR7Y39lDgnTjeXYipq1CNWiusseNvubqMxmPz/SwphSvRyBSnJ 2eBhlXVc/yWKTkWk+YAD6RZKEmPzVvqfVXLO5S7aYFaLA/v8Jf/38bD1k2rA7OFtAzeh 8Jcg== X-Gm-Message-State: APjAAAV7JZ2zNeISlh3gIjnqS1mZuPrELPqvX/4+SlaXvB9XlUCqimbv gbh0HUSFG/Y1N4i+cotaeaP5z5gpaA== X-Google-Smtp-Source: APXvYqxbneJkF3/UkdSwKpwrzg1rAmOYflMbYa22nKlFRKDrq0FBhJoSvAnIBSquFvLu243J+9VOyQ== X-Received: by 2002:a65:6496:: with SMTP id e22mr9160114pgv.249.1555764607799; Sat, 20 Apr 2019 05:50:07 -0700 (PDT) Received: from lithium.mbobrowski.org ([103.230.158.220]) by smtp.gmail.com with ESMTPSA id w5sm2853601pgp.94.2019.04.20.05.50.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Apr 2019 05:50:07 -0700 (PDT) Date: Sat, 20 Apr 2019 22:50:01 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Virus-Scanned: clamav-milter 0.99.2 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v2 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" New test file has been introduced to validate that the fanotify interface returns the correct error values upon specifying invalid flags and masks in conjunction with FAN_REPORT_FID. A new line entry within runtest/syscalls for this new test file. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify.h | 25 ++++ testcases/kernel/syscalls/fanotify/fanotify14.c | 171 ++++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify14.c diff --git a/runtest/syscalls b/runtest/syscalls index dfdc6cb..5c62895 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -538,6 +538,7 @@ fanotify10 fanotify10 fanotify11 fanotify11 fanotify12 fanotify12 fanotify13 fanotify13 +fanotify14 fanotify14 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index 16bdd99..bf389c9 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -11,4 +11,5 @@ /fanotify11 /fanotify12 /fanotify13 +/fanotify14 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h index e9b23cc..7c88fa8 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify.h +++ b/testcases/kernel/syscalls/fanotify/fanotify.h @@ -69,6 +69,31 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask, #ifndef FAN_MARK_FILESYSTEM #define FAN_MARK_FILESYSTEM 0x00000100 #endif +/* New dirent event masks */ +#ifndef FAN_ATTRIB +#define FAN_ATTRIB 0x00000004 +#endif +#ifndef FAN_MOVED_FROM +#define FAN_MOVED_FROM 0x00000040 +#endif +#ifndef FAN_MOVED_TO +#define FAN_MOVED_TO 0x00000080 +#endif +#ifndef FAN_CREATE +#define FAN_CREATE 0x00000100 +#endif +#ifndef FAN_DELETE +#define FAN_DELETE 0x00000200 +#endif +#ifndef FAN_DELETE_SELF +#define FAN_DELETE_SELF 0x00000400 +#endif +#ifndef FAN_MOVE_SELF +#define FAN_MOVE_SELF 0x00000800 +#endif +#ifndef FAN_MOVE +#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO) +#endif #ifndef FAN_OPEN_EXEC #define FAN_OPEN_EXEC 0x00001000 #endif diff --git a/testcases/kernel/syscalls/fanotify/fanotify14.c b/testcases/kernel/syscalls/fanotify/fanotify14.c new file mode 100644 index 0000000..735d6ac --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify14.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved. + * + * Started by Matthew Bobrowski + * + * DESCRIPTION + * This test file has been designed to ensure that the fanotify + * system calls fanotify_init(2) and fanotify_mark(2) return the + * correct error code to the calling process when an invalid flag or + * mask value has been specified in conjunction with FAN_REPORT_FID. + */ + +#include "tst_test.h" +#include "fanotify.h" + +#include + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define MNTPOINT "mntpoint" +#define FILE1 MNTPOINT"/file1" + +/* List of inode events that are only available when notification group is + * set to report fid + */ +#define INODE_EVENTS (FAN_ATTRIB | FAN_CREATE | FAN_DELETE | FAN_MOVE | \ + FAN_DELETE_SELF | FAN_MOVE_SELF) + +static int fanotify_fd; + +/* Each test case has been designed in a manner whereby the values defined + * within should result in the interface to return an error to the calling + * process. + */ +static struct test_case_t { + unsigned int init_flags; + unsigned int mark_flags; + unsigned long long mask; +} test_cases[] = { + { + FAN_CLASS_CONTENT | FAN_REPORT_FID, 0, 0 + }, + { + FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID, 0, 0 + }, + { + FAN_CLASS_NOTIF, 0, INODE_EVENTS + }, + { + FAN_CLASS_NOTIF | FAN_REPORT_FID, FAN_MARK_MOUNT, INODE_EVENTS + } +}; + +static void do_setup(void) +{ + int fd; + + /* Check for kernel fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + /* Create temporary test file to place marks on */ + SAFE_FILE_PRINTF(FILE1, "0"); +} + +static void do_test(unsigned int number) +{ + int ret; + struct test_case_t *tc = &test_cases[number]; + + fanotify_fd = fanotify_init(tc->init_flags, O_RDONLY); + + if (fanotify_fd < 0) { + /* EINVAL is to be returned to the calling process when + * an invalid notification class is specified in + * conjunction with FAN_REPORT_FID + */ + if (errno == EINVAL) { + tst_res(TPASS, + "fanotify_fd=%d, fanotify_init(%x, O_RDONLY) " + "failed with error EINVAL as expected", + fanotify_fd, + tc->init_flags); + return; + } + tst_brk(TBROK | TERRNO, + "fanotify_fd=%d, fanotify_init(%x, O_RDONLY) failed", + fanotify_fd, + tc->init_flags); + } + + /* A test case with a mask set to zero indicate that they've been + * specifically designed to test and fail on the fanotify_init() + * system call. + */ + if (tc->mask == 0) { + tst_res(TFAIL, + "fanotify_fd=%d fanotify_init(%x, O_RDONLY) " + "unexpectedly succeeded when tests with mask 0 are" + "expected to fail when calling fanotify_init()", + fanotify_fd, + tc->init_flags); + return; + } + + ret = fanotify_mark(fanotify_fd, FAN_MARK_ADD | tc->mark_flags, + tc->mask, AT_FDCWD, FILE1); + + if (ret < 0) { + /* EINVAL is to be returned to the calling process when + * attempting to use INODE_EVENTS without FAN_REPORT_FID + * specified on the notification group, or using + * INODE_EVENTS with mark type FAN_MARK_MOUNT. + */ + if (errno == EINVAL) { + tst_res(TPASS, + "ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, " + "%llx, AT_FDCWD, %s) failed with error EINVAL " + "as expected", + ret, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); + return; + } + tst_brk(TBROK | TERRNO, + "ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, " + "AT_FDCWD, %s) failed", + ret, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); + } + + tst_res(TFAIL, + "fanotify_fd=%d, ret=%d, fanotify_init(%x, O_RDONLY) and " + "fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, AT_FDCWD, %s) did " + "not return any errors as expected", + fanotify_fd, + ret, + tc->init_flags, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .needs_root = 1, + .setup = do_setup, + .test = do_test, + .tcnt = ARRAY_SIZE(test_cases), + .cleanup = do_cleanup, + .mount_device = 1, + .mntpoint = MNTPOINT, + .all_filesystems = 1 +}; + +#else + TST_TEST_CONF("System does not have required fanotify support") +#endif From patchwork Sat Apr 20 12:50:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1088391 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="JSUE90tI"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44mXkZ3g6Gz9s5c for ; Sat, 20 Apr 2019 22:50:30 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id DE2AB3EA195 for ; Sat, 20 Apr 2019 14:50:27 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id 60CF03EA0A1 for ; Sat, 20 Apr 2019 14:50:26 +0200 (CEST) Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id 4FE922009A2 for ; Sat, 20 Apr 2019 14:50:25 +0200 (CEST) Received: by mail-pl1-x643.google.com with SMTP id e92so1979417plb.6 for ; Sat, 20 Apr 2019 05:50:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=RB1/2/QBphCtZbipUDuIKbUtwVrOX0GOv4/EaFlfZ44=; b=JSUE90tI0+J/awFthXRq60XXw0ElWVsJL1JRXu7qi8sl2QWjdUhwKkwB6tDzmthR0Z 93WeCQCr75G7blFSZyXefDHlCJqifcOl776QEV26dRybfOfVMCVY+YhUvos1jGOuqJcp 371ZoXsAY6mEHsjloT7vbIYtYPgNty0om0/+sDEVlCAbyzRSfhJtSqNED/Ec69wTrzbI nVJTFXkQWcDDoDc96LWYwaSElZiChfBTmRGDHNGK7F1CTVNoeDLhK5NUuCVSoiBA7+lp HtSIupqhywxM6n2kqowvxCAS9/MsDNVbZB6AHLsevJuginlHlxKjQRp5JaJAgv290WW4 DS3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=RB1/2/QBphCtZbipUDuIKbUtwVrOX0GOv4/EaFlfZ44=; b=md7LC3gausVhawun5EpSF+q4Zf3ddahKfj0VjaryVf31Vp7idmxDvHB9ajkCF2VFQP DMs12Xhq5tvz1h1d2mxI5C+VcXZMPbKWvl2tnUsI05AnFWuRXpkFt4Fz2MCoQ3pBZOXw cP8jf9Ec/pdyiVeZQFBYEvTWZGveSCcJNDjAZCYXbYHfg2qVr+dOxa6Q1A28/Z3a6WL7 U056yUzMb2PjEUw9MaA3s1HaHMrFVoVieEOhlnmEhkCHZrB9QWvo9kopdBrZFI1yhGPt /m7Wt1RCsO6Y6xJPcYuSXWqUCAfPDh0WRLy2kkhRR5phlS1/32a07f+dH5jzT46kmXvg mJag== X-Gm-Message-State: APjAAAWuC4gpeikfLhFP2T0oFdCTcwfT+xJB/eRVeLg57WDdp3Ldi5DP /ozeZcuijyWl5vGX8oVNbdJ2WGSeGw== X-Google-Smtp-Source: APXvYqyQhdjmk6LM2SAxenYY51CwCen9XH7Njs8VSuw7vhC537xILK6hfN+mk8iLYoifc/GSxTUf1Q== X-Received: by 2002:a17:902:20cb:: with SMTP id v11mr9476285plg.324.1555764623470; Sat, 20 Apr 2019 05:50:23 -0700 (PDT) Received: from lithium.mbobrowski.org ([103.230.158.220]) by smtp.gmail.com with ESMTPSA id 10sm30570847pft.100.2019.04.20.05.50.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 Apr 2019 05:50:22 -0700 (PDT) Date: Sat, 20 Apr 2019 22:50:17 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Virus-Scanned: clamav-milter 0.99.2 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v2 3/3] syscalls/fanotify15: verify fid for dirent events X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" New test file that provides coverage for new dirent events. A new line entry within the runtest/syscalls file has been added to support this new test file. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify15.c | 245 ++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify15.c diff --git a/runtest/syscalls b/runtest/syscalls index 5c62895..2f9f147 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -539,6 +539,7 @@ fanotify11 fanotify11 fanotify12 fanotify12 fanotify13 fanotify13 fanotify14 fanotify14 +fanotify15 fanotify15 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index bf389c9..68e4cc7 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -12,4 +12,5 @@ /fanotify12 /fanotify13 /fanotify14 +/fanotify15 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify15.c b/testcases/kernel/syscalls/fanotify/fanotify15.c new file mode 100644 index 0000000..02f3b34 --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify15.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2019 CTERA Networks. All Rights Reserved. + * + * Started by Amir Goldstein + * Modified by Matthew Bobrowski + * + * DESCRIPTION + * Test file that has been purposely designed to verify + * FAN_REPORT_FID functionality while using newly defined dirent + * events. + */ +#define _GNU_SOURCE +#include "config.h" + +#include +#include +#include +#include +#include + +#include "tst_test.h" +#include "fanotify.h" + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define BUF_SIZE 256 +#define EVENT_MAX 256 + +#define MOUNT_POINT "mntpoint" +#define TEST_DIR MOUNT_POINT"/test_dir" +#define DIR1 TEST_DIR"/dir1" +#define DIR2 TEST_DIR"/dir2" +#define FILE1 TEST_DIR"/file1" +#define FILE2 TEST_DIR"/file2" + +struct event_t { + unsigned long long mask; + __kernel_fsid_t fsid; + struct file_handle handle; + char buf[MAX_HANDLE_SZ]; +}; + +static int fanotify_fd; +static char events_buf[BUF_SIZE]; +static struct event_t event_set[EVENT_MAX]; + +static void do_setup(void) +{ + int fd; + + /* Check kernel for fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + fanotify_fd = fanotify_init(FAN_REPORT_FID, O_RDONLY); + if (fanotify_fd == -1) { + if (errno == EINVAL) + tst_brk(TCONF, + "FAN_REPORT_FID not supported in kernel"); + tst_brk(TBROK | TERRNO, + "fanotify_init(FAN_REPORT_FID, O_RDONLY) failed"); + } + + SAFE_MKDIR(TEST_DIR, 0755); +} + +static void do_test(void) +{ + int i, fd, len, count = 0; + + struct file_handle *event_file_handle; + struct fanotify_event_metadata *metadata; + struct fanotify_event_info_fid *event_fid; + + if (fanotify_mark(fanotify_fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM, + FAN_CREATE | FAN_DELETE | FAN_ATTRIB | + FAN_MOVED_FROM | FAN_MOVED_TO | + FAN_DELETE_SELF | FAN_ONDIR, + AT_FDCWD, TEST_DIR) == -1) { + if (errno == ENODEV) + tst_brk(TCONF, + "FAN_REPORT_FID not supported on %s " + "filesystem", tst_device->fs_type); + tst_brk(TBROK | TERRNO, + "fanotify_mark(%d, FAN_MARK_ADD, FAN_CREATE | " + "FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | " + "FAN_DELETE_SELF | FAN_ONDIR, AT_FDCWD, %s) failed", + fanotify_fd, TEST_DIR); + } + + /* Generate a sequence of events */ + event_set[count].mask = FAN_CREATE | FAN_MOVED_FROM | FAN_MOVED_TO | \ + FAN_DELETE; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(TEST_DIR, &event_set[count].fsid, + &event_set[count].handle); + count++; + + fd = SAFE_CREAT(FILE1, 0644); + SAFE_CLOSE(fd); + + SAFE_RENAME(FILE1, FILE2); + + event_set[count].mask = FAN_ATTRIB | FAN_DELETE_SELF; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(FILE2, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_UNLINK(FILE2); + + /* Generate a sequence of events on a directory. Subsequent events + * are merged, so it's required that we set FAN_ONDIR once in + * order to acknowledge that changes related to a subdirectory + * took place. Events on subdirectories are not merged with events + * on non-subdirectories. + */ + event_set[count].mask = FAN_ONDIR | FAN_CREATE | FAN_MOVED_FROM | \ + FAN_MOVED_TO | FAN_DELETE; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(TEST_DIR, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_MKDIR(DIR1, 0755); + + SAFE_RENAME(DIR1, DIR2); + + event_set[count].mask = FAN_ONDIR | FAN_DELETE_SELF; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(DIR2, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_RMDIR(DIR2); + + /* Read events from the event queue */ + len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE); + + /* Process each event in buffer */ + for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf; + FAN_EVENT_OK(metadata, len); + metadata = FAN_EVENT_NEXT(metadata,len), i++) { + event_fid = (struct fanotify_event_info_fid *) (metadata + 1); + event_file_handle = (struct file_handle *) event_fid->handle; + + if (i >= count) { + tst_res(TFAIL, + "got unnecessary event: mask=%llx " + "pid=%u fd=%d", + (unsigned long long) metadata->mask, + metadata->pid, + metadata->fd); + metadata->mask = 0; + } else if (metadata->fd != FAN_NOFD) { + tst_res(TFAIL, + "Received unexpected file descriptor %d in " + "event. Expected to get FAN_NOFD(%d)", + metadata->fd, FAN_NOFD); + } else if (metadata->mask != event_set[i].mask) { + tst_res(TFAIL, + "Got event: mask=%llx (expected %llx) " + "pid=%u fd=%d", + (unsigned long long) metadata->mask, + event_set[i].mask, + (unsigned) metadata->pid, + metadata->fd); + } else if (metadata->pid != getpid()) { + tst_res(TFAIL, + "Got event: mask=%llx pid=%u " + "(expected %u) fd=%d", + (unsigned long long) metadata->mask, + (unsigned) metadata->pid, + (unsigned) getpid(), + metadata->fd); + } else if (event_file_handle->handle_bytes != + event_set[i].handle.handle_bytes) { + tst_res(TFAIL, + "Got event: handle_bytes (%x) returned in " + "event does not equal handle_bytes (%x) " + "retunred in name_to_handle_at(2)", + event_file_handle->handle_bytes, + event_set[i].handle.handle_bytes); + } else if (event_file_handle->handle_type != + event_set[i].handle.handle_type) { + tst_res(TFAIL, + "handle_type (%x) returned in event does not " + "equal to handle_type (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_type, + event_set[i].handle.handle_type); + } else if (memcmp(event_file_handle->f_handle, + event_set[i].handle.f_handle, + event_set[i].handle.handle_bytes) + != 0) { + tst_res(TFAIL, + "event_file_handle->f_handle does not match " + "handle.f_handle returned in " + "name_to_handle_at(2)"); + } else if (memcmp(&event_fid->fsid, &event_set[i].fsid, + sizeof(event_set[i].fsid)) != 0) { + tst_res(TFAIL, + "event_fid->fsid != stats.f_fsid that was " + "obtained via statfs(2)"); + } else { + tst_res(TPASS, + "Got event: mask=%llx, pid=%u, " + "fid=%x.%x.%lx values", + metadata->mask, + getpid(), + event_fid->fsid.val[0], + event_fid->fsid.val[1], + *(unsigned long *) + event_file_handle->f_handle); + } + } + + for (; i < count; i++) + tst_res(TFAIL, + "Didn't receive event: mask=%llx", + event_set[i].mask); +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .needs_root = 1, + .needs_tmpdir = 1, + .mount_device = 1, + .mntpoint = MOUNT_POINT, + .all_filesystems = 1, + .setup = do_setup, + .test_all = do_test, + .cleanup = do_cleanup +}; + +#else + TST_TEST_CONF("System does not have required fanotify support"); +#endif