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 ); }