예제 #1
0
파일: fanotify04.c 프로젝트: gibertre/ltp
static void check_mark(char *file, unsigned long long flag, char *flagstr,
		       int expect, void (*test_event)(char *))
{
	if (myfanotify_mark(fd_notify, FAN_MARK_ADD | flag, FAN_OPEN, AT_FDCWD,
			    file) != expect) {
		tst_resm(TFAIL,
		    "fanotify_mark (%d, FAN_MARK_ADD | %s, FAN_OPEN, AT_FDCWD, "
		    "'%s') %s", fd_notify, flagstr, file, expect_str_fail(expect));
	} else {
		tst_resm(TPASS,
		    "fanotify_mark (%d, FAN_MARK_ADD | %s, FAN_OPEN, AT_FDCWD, "
		    "'%s') %s", fd_notify, flagstr, file, expect_str_pass(expect));

		/* If we expected failure there's nothing to clean up */
		if (expect == -1)
			return;

		if (test_event)
			test_event(file);

		if (myfanotify_mark(fd_notify, FAN_MARK_REMOVE | flag,
				    FAN_OPEN, AT_FDCWD, file) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_REMOVE | %s, "
			    "FAN_OPEN, AT_FDCWD, '%s') failed",
			    fd_notify, flagstr, file);
		}
	}
}
예제 #2
0
파일: fanotify04.c 프로젝트: gibertre/ltp
int main(int ac, char **av)
{
	int lc;
	const char *msg;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/* Check ONLYDIR on a directory */
		CHECK_MARK(".", FAN_MARK_ONLYDIR, 0, NULL);

		/* Check ONLYDIR without a directory */
		CHECK_MARK(fname, FAN_MARK_ONLYDIR, -1, NULL);

		/* Check DONT_FOLLOW for a symlink */
		CHECK_MARK(sname, FAN_MARK_DONT_FOLLOW, 0, test_open_symlink);

		/* Check without DONT_FOLLOW for a symlink */
		CHECK_MARK(sname, 0, 0, test_open_file);

		/* Verify FAN_MARK_FLUSH destroys all inode marks */
		if (myfanotify_mark(fd_notify, FAN_MARK_ADD,
				    FAN_OPEN, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_ADD, FAN_OPEN, "
			    "AT_FDCWD, '%s') failed", fd_notify, fname);
		}
		if (myfanotify_mark(fd_notify, FAN_MARK_ADD,
				    FAN_OPEN | FAN_ONDIR, AT_FDCWD, dir) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_ADD, FAN_OPEN | "
			    "FAN_ONDIR, AT_FDCWD, '%s') failed", fd_notify,
			    dir);
		}
		open_file(fname);
		verify_event(S_IFREG);
		open_dir(dir);
		verify_event(S_IFDIR);
		if (myfanotify_mark(fd_notify, FAN_MARK_FLUSH,
				    0, AT_FDCWD, ".") < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_FLUSH, 0, "
			    "AT_FDCWD, '.') failed", fd_notify);
		}

		open_dir(dir);
		verify_no_event();
	}

	cleanup();
	tst_exit();
}
예제 #3
0
파일: fanotify03.c 프로젝트: ArnoldWu/ltp
static void setup(void)
{
	int fd;

	tst_sig(FORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;

	tst_tmpdir();
	sprintf(fname, "fname_%d", getpid());
	fd = SAFE_OPEN(cleanup, fname, O_CREAT | O_RDWR, 0644);
	SAFE_WRITE(cleanup, 1, fd, fname, 1);
	SAFE_CLOSE(cleanup, fd);

	if ((fd_notify = myfanotify_init(FAN_CLASS_CONTENT, O_RDONLY)) < 0) {
		if (errno == ENOSYS) {
			tst_brkm(TCONF, cleanup,
				 "fanotify is not configured in this kernel.");
		} else {
			tst_brkm(TBROK | TERRNO, cleanup,
				 "fanotify_init failed");
		}
	}

	if (myfanotify_mark(fd_notify, FAN_MARK_ADD, FAN_ACCESS_PERM |
			    FAN_OPEN_PERM, AT_FDCWD, fname) < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "fanotify_mark (%d, FAN_MARK_ADD, FAN_ACCESS_PERM | "
			 "FAN_OPEN_PERM, AT_FDCWD, %s) failed. "
			 "CONFIG_FANOTIFY_ACCESS_PERMISSIONS not "
			 "configured in kernel?", fd_notify, fname);
	}

}
예제 #4
0
파일: fanotify05.c 프로젝트: ArnoldWu/ltp
static void setup(void)
{
	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;

	tst_tmpdir();

	fd_notify = myfanotify_init(FAN_CLASS_NOTIF | FAN_NONBLOCK, O_RDONLY);
	if (fd_notify < 0) {
		if (errno == ENOSYS) {
			tst_brkm(TCONF, cleanup,
				 "fanotify is not configured in this kernel.");
		} else {
			tst_brkm(TBROK | TERRNO, cleanup,
				 "fanotify_init failed");
		}
	}

	if (myfanotify_mark(fd_notify, FAN_MARK_MOUNT | FAN_MARK_ADD, FAN_OPEN,
			    AT_FDCWD, ".") < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "fanotify_mark (%d, FAN_MARK_MOUNT | FAN_MARK_ADD, "
			 "FAN_OPEN, AT_FDCWD, \".\") failed",
			 fd_notify);
	}
}
예제 #5
0
파일: fanotify02.c 프로젝트: gibertre/ltp
int main(int ac, char **av)
{
	int lc;
	const char *msg;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		int ret, len, i = 0, test_num = 0;

		tst_count = 0;

		if (myfanotify_mark(fd_notify, FAN_MARK_ADD, FAN_ACCESS |
				    FAN_MODIFY | FAN_CLOSE | FAN_OPEN |
				    FAN_EVENT_ON_CHILD, AT_FDCWD, ".") < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_ADD, FAN_ACCESS | "
			    "FAN_MODIFY | FAN_CLOSE | FAN_OPEN | "
			    "FAN_EVENT_ON_CHILD, AT_FDCWD, '.') failed",
			    fd_notify);
		}

		/*
		 * generate sequence of events
		 */
		fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		SAFE_WRITE(cleanup, 1, fd, fname, strlen(fname));
		event_set[tst_count] = FAN_MODIFY;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_WRITE;
		tst_count++;

		/*
		 * Get list of events so far. We get events here to avoid
		 * merging of following events with the previous ones.
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf,
				EVENT_BUF_LEN);
		len = ret;

		fd = SAFE_OPEN(cleanup, fname, O_RDONLY);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE);
		event_set[tst_count] = FAN_ACCESS;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_NOWRITE;
		tst_count++;

		/*
		 * get next events
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		/*
		 * now remove child mark
		 */
		if (myfanotify_mark(fd_notify, FAN_MARK_REMOVE,
				    FAN_EVENT_ON_CHILD, AT_FDCWD, ".") < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK REMOVE, "
			    "FAN_EVENT_ON_CHILD, AT_FDCWD, '.') failed",
			    fd_notify);
		}

		/*
		 * Do something to verify events didn't get generated
		 */
		fd = SAFE_OPEN(cleanup, fname, O_RDONLY);

		SAFE_CLOSE(cleanup, fd);

		fd = SAFE_OPEN(cleanup, ".", O_RDONLY | O_DIRECTORY);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_NOWRITE;
		tst_count++;

		/*
		 * Check events got generated only for the directory
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		if (TST_TOTAL != tst_count) {
			tst_brkm(TBROK, cleanup,
				 "TST_TOTAL and tst_count are not equal");
		}
		tst_count = 0;

		/*
		 * check events
		 */
		while (i < len) {
			struct fanotify_event_metadata *event;

			event = (struct fanotify_event_metadata *)&event_buf[i];
			if (test_num >= TST_TOTAL) {
				tst_resm(TFAIL,
					 "get unnecessary event: mask=%llx "
					 "pid=%u fd=%u",
					 (unsigned long long)event->mask,
					 (unsigned)event->pid, event->fd);
			} else if (!(event->mask & event_set[test_num])) {
				tst_resm(TFAIL,
					 "get event: mask=%llx (expected %llx) "
					 "pid=%u fd=%u",
					 (unsigned long long)event->mask,
					 event_set[test_num],
					 (unsigned)event->pid, event->fd);
			} else if (event->pid != getpid()) {
				tst_resm(TFAIL,
					 "get event: mask=%llx pid=%u "
					 "(expected %u) fd=%u",
					 (unsigned long long)event->mask,
					 (unsigned)event->pid,
					 (unsigned)getpid(),
					 event->fd);
			} else {
				tst_resm(TPASS,
					    "get event: mask=%llx pid=%u fd=%u",
					    (unsigned long long)event->mask,
					    (unsigned)event->pid, event->fd);
			}
			event->mask &= ~event_set[test_num];
			/* No events left in current mask? Go for next event */
			if (event->mask == 0) {
				i += event->event_len;
				close(event->fd);
			}
			test_num++;
		}
		for (; test_num < TST_TOTAL; test_num++) {
			tst_resm(TFAIL, "didn't get event: mask=%llx",
				 event_set[test_num]);

		}
	}

	cleanup();
	tst_exit();
}
예제 #6
0
파일: fanotify01.c 프로젝트: gibertre/ltp
int main(int ac, char **av)
{
	int lc;
	const char *msg;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		int ret, len, i = 0, test_num = 0;

		tst_count = 0;

		if (myfanotify_mark(fd_notify, FAN_MARK_ADD, FAN_ACCESS | FAN_MODIFY |
				    FAN_CLOSE | FAN_OPEN, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_ADD, FAN_ACCESS | "
			    "FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, %s) "
			    "failed", fd_notify, fname);
		}

		/*
		 * generate sequence of events
		 */
		fd = SAFE_OPEN(cleanup, fname, O_RDONLY);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE);
		event_set[tst_count] = FAN_ACCESS;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_NOWRITE;
		tst_count++;

		/*
		 * Get list of events so far. We get events here to avoid
		 * merging of following events with the previous ones.
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf, EVENT_BUF_LEN);
		len = ret;

		fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		SAFE_WRITE(cleanup, 1, fd, fname, strlen(fname));
		event_set[tst_count] = FAN_MODIFY;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_WRITE;
		tst_count++;

		/*
		 * get another list of events
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		/*
		 * Ignore mask testing
		 */

		/* Ignore access events */
		if (myfanotify_mark(fd_notify,
				    FAN_MARK_ADD | FAN_MARK_IGNORED_MASK,
				    FAN_ACCESS, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			     "fanotify_mark (%d, FAN_MARK_ADD | "
			     "FAN_MARK_IGNORED_MASK, FAN_ACCESS, "
			     "AT_FDCWD, %s) failed", fd_notify, fname);
		}

		fd = SAFE_OPEN(cleanup, fname, O_RDWR);
		event_set[tst_count] = FAN_OPEN;
		tst_count++;

		/* This event should be ignored */
		SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE);

		/*
		 * get another list of events to verify the last one got ignored
		 */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		lseek(fd, 0, SEEK_SET);
		/* Generate modify event to clear ignore mask */
		SAFE_WRITE(cleanup, 1, fd, fname, 1);
		event_set[tst_count] = FAN_MODIFY;
		tst_count++;

		/*
		 * This event shouldn't be ignored because previous modification
		 * should have removed the ignore mask
		 */
		SAFE_READ(cleanup, 0, fd, buf, BUF_SIZE);
		event_set[tst_count] = FAN_ACCESS;
		tst_count++;

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_WRITE;
		tst_count++;

		/* Read events to verify previous access was properly generated */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		/*
		 * Now ignore open & close events regardless of file
		 * modifications
		 */
		if (myfanotify_mark(fd_notify,
				    FAN_MARK_ADD | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY,
				    FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			     "fanotify_mark (%d, FAN_MARK_ADD | "
			     "FAN_MARK_IGNORED_MASK | "
			     "FAN_MARK_IGNORED_SURV_MODIFY, FAN_OPEN | "
			     "FAN_CLOSE, AT_FDCWD, %s) failed", fd_notify,
			     fname);
		}

		/* This event should be ignored */
		fd = SAFE_OPEN(cleanup, fname, O_RDWR);

		SAFE_WRITE(cleanup, 1, fd, fname, 1);
		event_set[tst_count] = FAN_MODIFY;
		tst_count++;

		/* This event should be still ignored */
		SAFE_CLOSE(cleanup, fd);

		/* This event should still be ignored */
		fd = SAFE_OPEN(cleanup, fname, O_RDWR);

		/* Read events to verify open & close were ignored */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		/* Now remove open and close from ignored mask */
		if (myfanotify_mark(fd_notify,
				    FAN_MARK_REMOVE | FAN_MARK_IGNORED_MASK,
				    FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			     "fanotify_mark (%d, FAN_MARK_REMOVE | "
			     "FAN_MARK_IGNORED_MASK, FAN_OPEN | "
			     "FAN_CLOSE, AT_FDCWD, %s) failed", fd_notify,
			     fname);
		}

		SAFE_CLOSE(cleanup, fd);
		event_set[tst_count] = FAN_CLOSE_WRITE;
		tst_count++;

		/* Read events to verify close was generated */
		ret = SAFE_READ(cleanup, 0, fd_notify, event_buf + len,
				EVENT_BUF_LEN - len);
		len += ret;

		if (TST_TOTAL != tst_count) {
			tst_brkm(TBROK, cleanup,
				 "TST_TOTAL (%d) and tst_count (%d) are not "
				 "equal", TST_TOTAL, tst_count);
		}
		tst_count = 0;

		/*
		 * check events
		 */
		while (i < len) {
			struct fanotify_event_metadata *event;

			event = (struct fanotify_event_metadata *)&event_buf[i];
			if (test_num >= TST_TOTAL) {
				tst_resm(TFAIL,
					 "get unnecessary event: mask=%llx "
					 "pid=%u fd=%u",
					 (unsigned long long)event->mask,
					 (unsigned)event->pid, event->fd);
			} else if (!(event->mask & event_set[test_num])) {
				tst_resm(TFAIL,
					 "get event: mask=%llx (expected %llx) "
					 "pid=%u fd=%u",
					 (unsigned long long)event->mask,
					 event_set[test_num],
					 (unsigned)event->pid, event->fd);
			} else if (event->pid != getpid()) {
				tst_resm(TFAIL,
					 "get event: mask=%llx pid=%u "
					 "(expected %u) fd=%u",
					 (unsigned long long)event->mask,
					 (unsigned)event->pid,
					 (unsigned)getpid(),
					 event->fd);
			} else {
				if (event->fd == -2)
					goto pass;
				ret = read(event->fd, buf, BUF_SIZE);
				if (ret != strlen(fname)) {
					tst_resm(TFAIL,
						 "cannot read from returned fd "
						 "of event: mask=%llx pid=%u "
						 "fd=%u ret=%d (errno=%d)",
						 (unsigned long long)event->mask,
						 (unsigned)event->pid,
						 event->fd, ret, errno);
				} else if (memcmp(buf, fname, strlen(fname))) {
					tst_resm(TFAIL,
						 "wrong data read from returned fd "
						 "of event: mask=%llx pid=%u "
						 "fd=%u",
						 (unsigned long long)event->mask,
						 (unsigned)event->pid,
						 event->fd);
				} else {
pass:
					tst_resm(TPASS,
					    "get event: mask=%llx pid=%u fd=%u",
					    (unsigned long long)event->mask,
					    (unsigned)event->pid, event->fd);
				}
			}
			/*
			 * We have verified the data now so close fd and
			 * invalidate it so that we don't check it again
			 * unnecessarily
			 */
			close(event->fd);
			event->fd = -2;
			event->mask &= ~event_set[test_num];
			/* No events left in current mask? Go for next event */
			if (event->mask == 0) {
				i += event->event_len;
			}
			test_num++;
		}
		for (; test_num < TST_TOTAL; test_num++) {
			tst_resm(TFAIL, "didn't get event: mask=%llx",
				 event_set[test_num]);

		}
		/* Remove mark to clear FAN_MARK_IGNORED_SURV_MODIFY */
		if (myfanotify_mark(fd_notify, FAN_MARK_REMOVE, FAN_ACCESS | FAN_MODIFY |
				    FAN_CLOSE | FAN_OPEN, AT_FDCWD, fname) < 0) {
			tst_brkm(TBROK | TERRNO, cleanup,
			    "fanotify_mark (%d, FAN_MARK_REMOVE, FAN_ACCESS | "
			    "FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, %s) "
			    "failed", fd_notify, fname);
		}

	}

	cleanup();
	tst_exit();
}