[2.6.18 PATCH]: Filesystem Event Reporter V4 -- test program

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the test program for Filesystem Event Reporter V4, 
You need to use the header files of built 2.6.18 kernel to compile.
Assume your kernel dir is linux-2.6.18, this test program has the
 same parent directory with linux-2.6.18, then you can compile it
 using the following command:

# gcc -o fsevent-test -I linux-2.6.18/include fsevent-test.c

after insmod linux-2.6.18/fs/fsevent.ko, you can run it:

# ./fsevent-test > /tmp/fsevent.log

you can start some test tools in another terminal, for example
ltp, build kernel, fs stress tools, then you view /tmp/fsevent.log
 to see if it catch those file system operations. If you want to
 stop it, just press CTRL+C. you can grep system log by
 the following command to know how many process migration
 happens.

# cat /var/log/messages | grep migration | wc -l

if you don't want to use it, rmmod it to see if it is ok.

# rmmod fsevent


 Any feedback is welcomed.

Here is fsevent-test.c
/////////////////////////////////////////////
/*
 * fsevent_test.c - Filesystem Events Reporter Userspace Test Program
 * created by Yi Yang <[email protected]>
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <linux/netlink.h>
#define _LINUX_TIME_H
#include <linux/fsevent.h>

#define MAX_MSGSIZE 1024
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#define MATCH_FSEVENT_TYPE(t1, t2) (((t1) & (t2)) == (t2))

int sd;
struct sockaddr_nl l_local, daddr;
int on;
int len;
struct nlmsghdr *nlhdr = NULL;
struct msghdr msg;
struct iovec iov;
struct fsevent_filter * filter;
struct cn_msg * cnmsg;
struct fsevent * fsevent;
int counter = 0;
int ret;
struct sigaction sigint_action;
enum fsevent_type type;

void set_fsevent_filter(unsigned int mask, int control, int type, int id)
{
	memset(nlhdr, 0, sizeof(NLMSG_SPACE(MAX_MSGSIZE)));
	memset(&iov, 0, sizeof(struct iovec));
	memset(&msg, 0, sizeof(struct msghdr));
        filter = (struct fsevent_filter *)NLMSG_DATA(nlhdr);
        filter->mask = mask;
	if (type != FSEVENT_FILTER_ALL) {
		filter->id.pid = id;
	}
	filter->type = type;
	filter->control = control;
        nlhdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct fsevent_filter));
        nlhdr->nlmsg_pid = getpid();
        nlhdr->nlmsg_flags = 0;
        nlhdr->nlmsg_type = NLMSG_DONE;
        nlhdr->nlmsg_seq = 0;

        iov.iov_base = (void *)nlhdr;
        iov.iov_len = nlhdr->nlmsg_len;
        msg.msg_name = (void *)&daddr;
        msg.msg_namelen = sizeof(daddr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        ret = sendmsg(sd, &msg, 0);
        if (ret == -1) {
        	perror("sendmsg error:");
		exit(-1);
        }
}
int get_fsevent()
{
	memset(nlhdr, 0, NLMSG_SPACE(MAX_MSGSIZE));
	memset(&iov, 0, sizeof(struct iovec));
	memset(&msg, 0, sizeof(struct msghdr));

        iov.iov_base = (void *)nlhdr;
        iov.iov_len = NLMSG_SPACE(MAX_MSGSIZE);
        msg.msg_name = (void *)&daddr;
        msg.msg_namelen = sizeof(daddr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;

        return recvmsg(sd, &msg, 0);
}
void stop_listen()
{
	set_fsevent_filter(0xffffffff, FSEVENT_FILTER_IGNORE,
				FSEVENT_FILTER_ALL,0);
	set_fsevent_filter(0xffffffff, FSEVENT_FILTER_REMOVE,
				FSEVENT_FILTER_ALL,0);
}
void sigint_handler(int signo)
{
	stop_listen();
	printf("filesystem event: turn off filesystem event listening.\n");
	get_fsevent();
	get_fsevent();
	close(sd);
	exit(0);
}
void print_fsevent(struct fsevent * event, char * typestr, int flag)
{
	printf("filesystem event: %s\n"
		"process '%s' %s %s '%s'",
		typestr,
		fsevent->name,
		typestr,
		((fsevent->type & FSEVENT_ISDIR)
			== FSEVENT_ISDIR)?"dir":"file",
		fsevent->name + fsevent->pname_len + 1);
	if (flag)
		printf(" to '%s'", fsevent->name + fsevent->pname_len
                                        + fsevent->fname_len + 2);
	printf("\n");
}
void print_ack(char * typestr)
{
	printf("filesystem event: "
		"acknowledge for filter on %s\n", typestr);
}
int main(void)
{
	memset(&sigint_action, 0, sizeof(struct sigaction));
	sigint_action.sa_flags = SA_ONESHOT;
	sigint_action.sa_handler = &sigint_handler;
	sigaction(SIGINT, &sigint_action, NULL);
	nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSGSIZE));
	if (nlhdr == NULL) {
		perror("malloc:");
		exit(-1);
	}
	daddr.nl_family = AF_NETLINK;
        daddr.nl_pid = 0;
        daddr.nl_groups = 0;

	sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_FSEVENT);

	l_local.nl_family = AF_NETLINK;
	l_local.nl_groups = 0;
	l_local.nl_pid = getpid();

	if (bind(sd, (struct sockaddr *)&l_local,
			sizeof(struct sockaddr_nl)) == -1) {
        	perror("bind");
	        close(sd);
        	return -1;
	}
	//set_fsevent_filter(FSEVENT_MOUNT|FSEVENT_UMOUNT,
	set_fsevent_filter(0xffffffff,
			FSEVENT_FILTER_LISTEN, FSEVENT_FILTER_ALL, 0);
	printf("filesystem event: turn on filesystem event listening.\n");
	while (1) {
		ret = get_fsevent();
                if (ret == 0) {
                        printf("Exit.\n");
                        exit(0);
                }
                if (ret == -1) {
                        perror("recvmsg:");
                        exit(1);
                }
		fsevent = (struct fsevent *)NLMSG_DATA(nlhdr);
		type = fsevent->type;
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_ACCESS))
			print_fsevent(fsevent, "access", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_MODIFY))
			print_fsevent(fsevent, "modify", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_MODIFY_ATTRIB))
			print_fsevent(fsevent, "modify_attr", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_CLOSE))
			print_fsevent(fsevent, "close", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_OPEN))
			print_fsevent(fsevent, "open", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_MOVE))
			print_fsevent(fsevent, "move", 1);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_CREATE))
			print_fsevent(fsevent, "create", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_DELETE))
			print_fsevent(fsevent, "delete", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_MOUNT))
			print_fsevent(fsevent, "mount", 1);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_UMOUNT))
			print_fsevent(fsevent, "umount", 0);
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_FILTER_ALL))
			print_ack("all");
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_FILTER_PID))
			print_ack("pid");
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_FILTER_UID))
			print_ack("uid");
		if (MATCH_FSEVENT_TYPE(type, FSEVENT_FILTER_GID))
			print_ack("gid");
		printf("event type = %08x, pid = %d, uid = %d, gid = %d\n",
			fsevent->type, fsevent->pid,
			fsevent->uid, fsevent->gid);
		printf("counter = %d\n\n", counter++);
	}
}
///////////////////////////////////////

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux