int generic_open_file(struct thread_data *td, struct fio_file *f) { int is_std = 0; int flags = 0; int from_hash = 0; dprint(FD_FILE, "fd open %s\n", f->file_name); if (td_trim(td) && f->filetype != FIO_TYPE_BD) { log_err("fio: trim only applies to block device\n"); return 1; } if (!strcmp(f->file_name, "-")) { if (td_rw(td)) { log_err("fio: can't read/write to stdin/out\n"); return 1; } is_std = 1; /* * move output logging to stderr, if we are writing to stdout */ if (td_write(td)) f_out = stderr; } if (td_trim(td)) goto skip_flags; if (td->o.odirect) flags |= OS_O_DIRECT; if (td->o.sync_io) flags |= O_SYNC; if (td->o.create_on_open) flags |= O_CREAT; skip_flags: if (f->filetype != FIO_TYPE_FILE) flags |= FIO_O_NOATIME; open_again: if (td_write(td)) { if (!read_only) flags |= O_RDWR; if (f->filetype == FIO_TYPE_FILE) flags |= O_CREAT; if (is_std) f->fd = dup(STDOUT_FILENO); else from_hash = file_lookup_open(f, flags); } else if (td_read(td)) { if (f->filetype == FIO_TYPE_CHAR && !read_only) flags |= O_RDWR; else flags |= O_RDONLY; if (is_std) f->fd = dup(STDIN_FILENO); else from_hash = file_lookup_open(f, flags); } else { //td trim flags |= O_RDWR; from_hash = file_lookup_open(f, flags); } if (f->fd == -1) { char buf[FIO_VERROR_SIZE]; int __e = errno; if (__e == EPERM && (flags & FIO_O_NOATIME)) { flags &= ~FIO_O_NOATIME; goto open_again; } if (__e == EMFILE && file_close_shadow_fds(td)) goto open_again; snprintf(buf, sizeof(buf), "open(%s)", f->file_name); if (__e == EINVAL && (flags & OS_O_DIRECT)) { log_err("fio: looks like your file system does not " \ "support direct=1/buffered=0\n"); } td_verror(td, __e, buf); } if (!from_hash && f->fd != -1) { if (add_file_hash(f)) { int fio_unused ret; /* * Stash away descriptor for later close. This is to * work-around a "feature" on Linux, where a close of * an fd that has been opened for write will trigger * udev to call blkid to check partitions, fs id, etc. * That polutes the device cache, which can slow down * unbuffered accesses. */ if (f->shadow_fd == -1) f->shadow_fd = f->fd; else { /* * OK to ignore, we haven't done anything * with it */ ret = generic_close_file(td, f); } goto open_again; } } return 0; }
/* This method does the work of determining what happened, then allows us to act appropriately */ void handle_event(queue_entry_t event, int fd) { /* If the event was associated with a filename, we will store it here */ char *cur_event_filename = NULL; char *cur_event_file_or_dir = NULL; /* This is the watch descriptor the event occurred on */ int cur_event_wd = event->inot_ev.wd; int cur_event_cookie = event->inot_ev.cookie; unsigned long flags; time_t t; struct tm *tmptr; char query[69535]; char time_str[80]; char filename[1024]; char file_content[65535]; int len; char * end; FILE *fp; time(&t); tmptr = localtime(&t); strftime(time_str, sizeof(time_str), "%F %T", tmptr); if(event->inot_ev.len){ cur_event_filename = event->inot_ev.name; } if(event->inot_ev.mask & IN_ISDIR){ cur_event_file_or_dir = "Dir"; } else { cur_event_file_or_dir = "File"; sprintf(filename, "%s/%s", inotify_struct[cur_event_wd].dir_name, cur_event_filename); } sprintf(filename, "%s/%s", inotify_struct[cur_event_wd].dir_name, cur_event_filename); flags = event->inot_ev.mask & ~(IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED ); /* Perform event dependent handler routines */ /* The mask is the magic that tells us what file operation occurred */ switch (event->inot_ev.mask & (IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED)) { /* File was accessed */ case IN_ACCESS: printf ("ACCESS: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); //syslog(LOG_INFO, "ACCESS: %s \"%s\"\n", cur_event_file_or_dir, filename); break; /* File was modified */ case IN_MODIFY: printf ("MODIFY: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); char *p = strrchr(filename, '.'); if(p && (strcmp(p, file_suf) == 0) && check_md5_file(filename, cur_event_wd)){ if (!(fp = fopen(filename,"rb"))) { printf("Can not open %s this file!\n",filename); } len = fread(file_content, 1, 65535, fp); fclose(fp); memset(query, '\0', 1024); sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, content) values ('%s', %d, '%s', '%s', '%s', '%s', ", host_name, pid, filename, cur_event_file_or_dir, "MODIFY", time_str); end = query; end += strlen(query); *end++ = '\''; end += mysql_real_escape_string(&mysql, end, file_content, len); *end++ = '\''; *end++ = ')'; *end++ = ';'; mysql_real_query(&mysql, query, (unsigned int)(end - query)); printf("%s\n",query); } else { sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s')", host_name, pid, filename, cur_event_file_or_dir, "MODIFY", time_str); printf("%s\n",query); mysql_query(&mysql, query); } //print_inotify_struct(cur_event_wd); break; /* File changed attributes */ case IN_ATTRIB: printf("ATTRIB: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); break; /* File open for writing was closed */ case IN_CLOSE_WRITE: printf("CLOSE_WRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); break; /* File open read-only was closed */ case IN_CLOSE_NOWRITE: printf("CLOSE_NOWRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); break; /* File was opened */ case IN_OPEN: printf ("OPEN: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); break; /* File was moved from X */ case IN_MOVED_FROM: printf ("MOVED_FROM: %s \"%s\" on WD #%i. Cookie=%d\n", cur_event_file_or_dir, filename, cur_event_wd, cur_event_cookie); sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, cookie) values ('%s', %d, '%s', '%s', '%s', '%s', %d);", host_name, pid, filename, cur_event_file_or_dir, "MOVE_FROM", time_str, cur_event_cookie); mysql_query(&mysql, query); if( event->inot_ev.mask & IN_ISDIR ){ } else { char *p = strrchr(filename, '.'); if(p && (strcmp(p, file_suf) == 0)){ delete_file_hash(filename, cur_event_wd); //print_inotify_struct(cur_event_wd); } } break; /* File was moved to X */ case IN_MOVED_TO: printf ("MOVED_TO: %s \"%s\" on WD #%i. Cookie=%d\n", cur_event_file_or_dir, filename, cur_event_wd, cur_event_cookie); sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, cookie) values ('%s', %d, '%s', '%s', '%s', '%s', %d);", host_name, pid, filename, cur_event_file_or_dir, "MOVE_TO", time_str, cur_event_cookie); mysql_query(&mysql, query); if ( event->inot_ev.mask & IN_ISDIR ){ } else { char *p = strrchr(filename, '.'); if(p && (strcmp(p, file_suf) == 0)){ add_file_hash(filename, cur_event_wd); //print_inotify_struct(cur_event_wd); } } break; /* Subdir or file was deleted */ case IN_DELETE: printf ("DELETE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s');", host_name, pid, filename, cur_event_file_or_dir, "DELETE", time_str); mysql_query(&mysql, query); if(event->inot_ev.mask & IN_ISDIR){ } else { char *p = strrchr(filename, '.'); if(p && (strcmp(p, file_suf) == 0)){ delete_file_hash(filename, cur_event_wd); //print_inotify_struct(cur_event_wd); } } break; /* Subdir or file was created */ case IN_CREATE: printf ("CREATE: %s \"%s\"\n", cur_event_file_or_dir, filename); if ( event->inot_ev.mask & IN_ISDIR ){ watch_dir (fd, filename, IN_MODIFY | IN_MOVE | IN_CREATE | IN_DELETE ); } else { char *p = strrchr(filename, '.'); if(p && (strcmp(p, file_suf) == 0)){ add_file_hash(filename, cur_event_wd); print_inotify_struct(cur_event_wd); if (!(fp = fopen(filename,"rb"))) { printf("Can not open %s this file!\n",filename); } len = fread(file_content, 1, 65535, fp); fclose(fp); memset(query, '\0', 1024); sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, content) values ('%s', %d, '%s', '%s', '%s', '%s', ", host_name, pid, filename, cur_event_file_or_dir, "CREATE", time_str); end = query; end += strlen(query); *end++ = '\''; end += mysql_real_escape_string(&mysql, end, file_content, len); *end++ = '\''; *end++ = ')'; mysql_real_query(&mysql, query, (unsigned int)(end - query)); printf("%s\n",query); break; } } sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s');", host_name, pid, filename, cur_event_file_or_dir, "CREATE", time_str); mysql_query(&mysql, query); break; /* Watched entry was deleted */ case IN_DELETE_SELF: printf ("DELETE_SELF: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd); break; /* Watched entry was moved */ case IN_MOVE_SELF: printf ("MOVE_SELF: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd); break; /* Backing FS was unmounted */ case IN_UNMOUNT: printf ("UNMOUNT: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd); break; /* Too many FS events were received without reading them some event notifications were potentially lost. */ case IN_Q_OVERFLOW: printf ("Warning: AN OVERFLOW EVENT OCCURRED: \n"); break; /* Watch was removed explicitly by inotify_rm_watch or automatically because file was deleted, or file system was unmounted. */ case IN_IGNORED: watched_items--; printf ("IGNORED: WD #%d\n", cur_event_wd); printf("Watching = %d items\n",watched_items); break; /* Some unknown message received */ default: printf ("UNKNOWN EVENT \"%X\" OCCURRED for file \"%s\" on WD #%i\n", event->inot_ev.mask, cur_event_filename, cur_event_wd); break; } /* If any flags were set other than IN_ISDIR, report the flags */ if (flags & (~IN_ISDIR)) { flags = event->inot_ev.mask; printf ("Flags=%lX\n", flags); } }
int generic_open_file(struct thread_data *td, struct fio_file *f) { int is_std = 0; int flags = 0; int from_hash = 0; dprint(FD_FILE, "fd open %s\n", f->file_name); if (!strcmp(f->file_name, "-")) { if (td_rw(td)) { log_err("fio: can't read/write to stdin/out\n"); return 1; } is_std = 1; /* * move output logging to stderr, if we are writing to stdout */ if (td_write(td)) f_out = stderr; } if (td->o.odirect) flags |= OS_O_DIRECT; if (td->o.sync_io) flags |= O_SYNC; if (f->filetype != FIO_TYPE_FILE) flags |= FIO_O_NOATIME; if (td->o.create_on_open) flags |= O_CREAT; open_again: if (td_write(td)) { if (!read_only) flags |= O_RDWR; if (f->filetype == FIO_TYPE_FILE) flags |= O_CREAT; if (is_std) f->fd = dup(STDOUT_FILENO); else from_hash = file_lookup_open(f, flags); } else { if (f->filetype == FIO_TYPE_CHAR && !read_only) flags |= O_RDWR; else flags |= O_RDONLY; if (is_std) f->fd = dup(STDIN_FILENO); else from_hash = file_lookup_open(f, flags); } if (f->fd == -1) { char buf[FIO_VERROR_SIZE]; int __e = errno; if (__e == EPERM && (flags & FIO_O_NOATIME)) { flags &= ~FIO_O_NOATIME; goto open_again; } snprintf(buf, sizeof(buf) - 1, "open(%s)", f->file_name); td_verror(td, __e, buf); } if (!from_hash && f->fd != -1) { if (add_file_hash(f)) { int fio_unused ret; /* * OK to ignore, we haven't done anything with it */ ret = generic_close_file(td, f); goto open_again; } } return 0; }