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