Hello again,

I downloaded smartos latest image (joyent_20141127T173954Z) and tested
inotify using it.

Two issues were observed:

1. ioctl(fd, FIONREAD, ...) does not work as expected. It does not return
the number of bytes that are available to be read on an inotify instance.

2. In an OS zone, touching a file always generates an IN_CREATE event, even
though the file already exists. This only happens in an OS zone, not in
global zone.

Attached is the test program I used for testing. Just compile and run it,
then in another terminal window, 'touch /tmp/file' twice. Please look at
the details at the end of this e-mail.

Thanks,

-Youzhong

--- In global zone ---
[root@batfs5999 /var/tmp]# ./inotify
ioctl = 64, errno = 0, bufsize = 0
got 48 bytes
   :: mask 256
   -> New file file created
   :: mask 4
   -> file ATTRIB
ioctl = 32, errno = 0, bufsize = 0
got 24 bytes
   :: mask 4
   -> file ATTRIB

--- In OS zone ---
[root@batfs5999-cifs0 /var/tmp]# ./inotify
ioctl = 64, errno = 0, bufsize = 0
got 48 bytes
   :: mask 256
   -> New file file created
   :: mask 4
   -> file ATTRIB
ioctl = 64, errno = 0, bufsize = 0
got 48 bytes
   :: mask 256
   -> New file file created
   :: mask 4
   -> file ATTRIB

--- On Linux  ---
% ./inotify
ioctl = 0, errno = 0, bufsize = 32
got 32 bytes
   :: mask 256
   -> New file file created
ioctl = 0, errno = 0, bufsize = 32
got 32 bytes
   :: mask 4
   -> file ATTRIB
ioctl = 0, errno = 0, bufsize = 32
got 32 bytes
   :: mask 4
   -> file ATTRIB



-------------------------------------------
smartos-discuss
Archives: https://www.listbox.com/member/archive/184463/=now
RSS Feed: https://www.listbox.com/member/archive/rss/184463/25769125-55cfbc00
Modify Your Subscription: 
https://www.listbox.com/member/?member_id=25769125&id_secret=25769125-7688e9fb
Powered by Listbox: http://www.listbox.com
/*
	This is the sample program to test inotify.
	
	- compile this program: gcc -o inotify inotify.c
	- run it by ./inotify or ./inotify <direcotory to monitor>
	
	If no argument is given, it will monitor /tmp.	  
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/inotify.h>
#ifdef __sun__
#include <sys/filio.h>
#endif

#include <unistd.h>
#include <stropts.h>
#include <poll.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 64 ) )

void print_inotify_event(struct inotify_event *event)
{
	if ( event->len ) {
		printf("   :: mask %d\n", event->mask);
		if ( event->mask & IN_CREATE ) {
			if ( event->mask & IN_ISDIR ) {
				printf( "   -> New directory %s created\n", event->name );
			}
			else {
				printf( "   -> New file %s created\n", event->name );
			}
		}
		else if ( event->mask & IN_DELETE ) {
			if ( event->mask & IN_ISDIR ) {
				printf( "   -> Directory %s deleted\n", event->name );
			}
			else {
				printf( "   -> File %s deleted\n", event->name );
			}
		}
		else if ( event->mask & IN_MOVED_FROM ) {
			printf( "   -> %s MOVED_FROM\n", event->name );
		}
		else if ( event->mask & IN_MOVED_TO ) {
			printf( "   -> %s MOVED_TO\n", event->name );
		}
		else if ( event->mask & IN_ATTRIB ) {
			printf( "   -> %s ATTRIB\n", event->name );
		}	  
		else if ( event->mask & IN_MODIFY ) {
			printf( "   -> %s MODIFY\n", event->name );
		}	  	 
		else {
			printf( "   -> MASK %d -> %s\n", event->mask, event->name);
		}
	}
}

int main(int argc, char *argv[] )
{
	int length, i = 0;
	int fd;
	int wd;
	char buffer[EVENT_BUF_LEN];
	int bufsize;
	int ret;
  
	struct pollfd fds[1];

	/*creating the INOTIFY instance*/
	fd = inotify_init();
	/*checking for error*/
	if ( fd < 0 ) {
		perror( "inotify_init" );
		exit(1);
	}

	/* monitor /tmp or the given directory */
	if(argc == 1)
		wd = inotify_add_watch( fd, "/tmp", IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_ATTRIB | IN_MODIFY | IN_ONLYDIR);
	else
		wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_ATTRIB | IN_MODIFY | IN_ONLYDIR);

	fds[0].fd = fd;
	fds[0].events = POLLIN;
  
	while(1)
	{
		/* check if there's data available for reading */
		ret = poll(fds, 1, 1000);
		if(ret <= 0) continue;

		bufsize = 0;		
		/* check how many bytes available for reading */
		ret = ioctl(fd, FIONREAD, &bufsize); /* FIONREAD = 0x4004667f */
		printf("ioctl = %d, errno = %d, bufsize = %d\n", ret, errno, bufsize);
	  
		/* Read the data. Normally the program can allocate a buffer based
		   on the size returned by above iotcl call. Here we just use a static
		   buffer 
		*/
		length = read( fd, buffer, EVENT_BUF_LEN ); 

		/* checking for error */
		if ( length < 0 ) {
			perror( "read" );
			break;
		}  
		printf("got %d bytes\n", length);
	  
		/*
			Actually read the list of change events. 
			Here, read the change event one by one and process it accordingly.
		*/
		i = 0;
		while ( i < length ) {     
			struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];     
			print_inotify_event(event);
			i += EVENT_SIZE + event->len;
		}	  
	}

	inotify_rm_watch( fd, wd );

	close( fd );

}

Reply via email to