#include #include #include #include #include #include "rfs_assert.h" #include "profile.h" #define MKDIR 1 #define RMDIR 2 #define CREATE 3 #define REMOVE 4 #define WRITE 5 #define TRUNCATE 6 #define MAX_FILES 100000 #define MAX_DIRS 100000 #define FILE_FH_HTABLE_SIZE MAX_FILES #define MAX_NAMELEN 256 #define MAX_PLAY_PATH_SIZE 256 #define MAX_COMMAND_LEN (MAX_PLAY_PATH_SIZE+16) #define NFS_MAXDATA 32768 #define TRACE_FH_SIZE 64 #define FH_T_FLAG_FREE 0 #define FH_T_FLAG_IN_USE 1 #define IS_FILE 0 #define IS_DIR 1 #define NOT_EXIST 0 #define EXIST 1 typedef struct { char flag; //char trace_fh [TRACE_FH_SIZE+1]; char path[MAX_PLAY_PATH_SIZE]; } fh_t; typedef struct { char name[32]; fh_t * fh; //struct generic_entry * htable; int fh_size; int fh_max; int index; //int htable_size; } fh_info_t; fh_info_t file_fh, dir_fh; profile_t read_line_profile, fgets_profile; char trace_file[MAX_NAMELEN]; FILE * profile_fp = NULL; char testdir[MAX_NAMELEN]; int age_create_num = 0; int age_mkdir_num = 0; int assure_create_num = 0; int assure_mkdir_num = 0; int age_write_num = 0; int nonage_write_num = 0; int overlap_write_num = 0; int init_profile_variables() { init_profile ("read_line profile", &read_line_profile); init_profile ("fgets profile", &fgets_profile); } int init_fh_info (char * name, fh_info_t * fh_infop, int fh_size, int htable_size) { RFS_ASSERT (strlen(name) < sizeof(fh_infop->name)); strcpy (fh_infop->name, name); fh_infop->fh_max = 0; fh_infop->index = 0; fh_infop->fh_size = fh_size; //fh_infop->htable_size = htable_size; fh_infop->fh = (fh_t *)malloc (sizeof(fh_t)*fh_size); RFS_ASSERT (fh_infop->fh); //fh_infop->htable = malloc (sizeof(struct*generic_entry)*htable_size); //RFS_ASSERT (fh_infop->htable); printf("initialize %s size %d bytes\n", //name, sizeof(fh_t)*fh_size + sizeof(struct*generic_entry)*htable_size); name, sizeof(fh_t)*fh_size); } int init() { init_fh_info ("file_fh", &file_fh, MAX_FILES, MAX_FILES); init_fh_info ("dir_fh", &dir_fh, MAX_DIRS, MAX_DIRS); } int add_fh_t (fh_info_t * fh_table, char * path, int exist_flag) { int i; for (i=0; ifh_size; i++,fh_table->index++) { if (fh_table->index==fh_table->fh_size) fh_table->index = 0; if (fh_table->fh[fh_table->index].flag == FH_T_FLAG_FREE) { fh_table->fh[fh_table->index].flag = FH_T_FLAG_IN_USE; //RFS_ASSERT(strlen(path)fh[fh_table->index].path, path); if (fh_table->index > fh_table->fh_max) fh_table->fh_max = fh_table->index; return 0; } } //print_fh_map(fh_table); RFS_ASSERT (0); } int create_mkdir_op (int flag) { static int fhno = 0; char name[MAX_NAMELEN]; char command[MAX_COMMAND_LEN]; int i; int fd; int count = 0; fh_info_t * fh_infop; while (count++ < 100) { i = random()%dir_fh.fh_max; if (dir_fh.fh[i].flag==FH_T_FLAG_IN_USE) { assure_exist(dir_fh.fh[i].path); strcpy (name, dir_fh.fh[i].path); if (flag == IS_FILE) { sprintf (name+strlen(name), "AGEfile%d", fhno++); fd = creat (name, S_IRWXU); age_create_num++; //printf ("create fd %d\n", fd); close(fd); fh_infop = &file_fh; } else { sprintf (name+strlen(name), "AGEdir%d", fhno++); fd = mkdir (name, S_IRWXU); age_mkdir_num++; fh_infop = &dir_fh; } if (fd == -1) { perror(""); if (errno == ENOENT) { dir_fh.fh[i].flag = FH_T_FLAG_FREE; continue; } else RFS_ASSERT (0); } add_fh_t (fh_infop, name, EXIST); RFS_ASSERT (fd >=0); return 0; } }; return -1; } int remove_op () { int i; int count = 0; int ret; while (count++<100) { i = random()%file_fh.fh_max; if (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) { /* if (!strstr(file_fh.fh[i].path, "AGE")) continue; */ assure_exist(file_fh.fh[i].path); ret = remove (file_fh.fh[i].path); RFS_ASSERT (ret ==0); file_fh.fh[i].flag = FH_T_FLAG_FREE; return 0; } } return -1; } int rmdir_op() { int i; int count=0; char command[MAX_COMMAND_LEN]; int ret; while (count++<100) { i = random()%dir_fh.fh_max; if ( (dir_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) { /* if (!strstr(file_fh.fh[i].path, "AGE")) continue; */ assure_exist(file_fh.fh[i].path); ret = rmdir (dir_fh.fh[i].path); if (ret == 0) { dir_fh.fh[i].flag = FH_T_FLAG_FREE; return 0; } RFS_ASSERT ((ret == -1) && (errno == ENOTEMPTY)); //strcpy (command, "rm -r %s", dir_fh.fh[i].path); //system (command); } } return -1; } int loop_write (int fd, char * buf, int buflen) { int ret; int pos = 0; while (1) { ret = write (fd, buf+pos, buflen-pos); if (ret == -1) { perror ("loop write"); exit (-1); } if (ret == buflen-pos) break; pos += ret; } return 0; } int assure_exist(char * path) { char name[MAX_NAMELEN]; int ret; char *p, *q; int non_exist_flag = 0; int count=0; struct stat st; ret = stat (path, &st); if (ret == 0) return 0; RFS_ASSERT (errno == ENOENT); RFS_ASSERT (!strstr (path, "AGE")); p = path; q = name; while (count++<100) { for (; *p!=0 && *p!='/'; p++, q++ ) *q = *p; *q = 0; ret = stat (name, &st); if (ret == -1) { RFS_ASSERT (errno == ENOENT) if ((*p)==0) { ret = creat (name, S_IRWXU); assure_create_num ++; RFS_ASSERT (ret >=0); close(ret); } else { ret = mkdir (name, S_IRWXU); assure_mkdir_num ++; RFS_ASSERT (ret >=0); } } if ((*p)=='/') { *q = '/'; p++; q++; } else { RFS_ASSERT ((*p)==0) return 0; } } RFS_ASSERT (0); } int write_op (int off, int size) { static char buf[NFS_MAXDATA]; int i; int count=0; int fd; int ret; struct stat st; RFS_ASSERT (size <= NFS_MAXDATA); while (count++<100) { i = random()%file_fh.fh_max; if ( (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) { assure_exist(file_fh.fh[i].path); fd = open(file_fh.fh[i].path, O_WRONLY); if (fd == -1) perror(""); //else //printf ("write fd %d\n", fd); RFS_ASSERT (fd!=-1); fstat (fd, &st); if (st.st_size < (off+size)) { int written_bytes = 0; while (written_bytes+NFS_MAXDATA < off+size-st.st_size) { loop_write (fd, buf, NFS_MAXDATA); written_bytes += NFS_MAXDATA; } loop_write (fd, buf, off+size-st.st_size-written_bytes); if (strstr(file_fh.fh[i].path, "AGE")) { age_write_num+=(written_bytes+NFS_MAXDATA-1)/NFS_MAXDATA; } else nonage_write_num+=(written_bytes+NFS_MAXDATA-1)/NFS_MAXDATA; } else overlap_write_num++; /* if (strstr(file_fh.fh[i].path, "AGE")) { age_write_num++; } else nonage_write_num++; loop_write (fd, buf, size); */ close(fd); return 0; }; } return -1; } int truncate_op(int size) { int i; int count=0; int ret; while (count++<100) { i = random()%file_fh.fh_max; if ( (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) { /* if (!strstr(file_fh.fh[i].path, "AGE")) continue; */ assure_exist (file_fh.fh[i].path); ret = truncate(file_fh.fh[i].path, size); if (ret ==0) return 0; RFS_ASSERT (errno == ENOENT); file_fh.fh[i].flag = FH_T_FLAG_FREE; continue; } }; return -1; } int print_fh_map(fh_info_t * fhp) { int i; int num = 0; for (i=0; ifh_max; i++) { if (fhp->fh[i].flag == FH_T_FLAG_IN_USE) { num ++; printf("%s[%d] %s\n", fhp->name, i, fhp->fh[i].path); } } fprintf(stderr, "fh_max %d total %d entries \n", fhp->fh_max, num); } void read_fh_map(char * fh_map_file) { FILE * fp; int i = 0; char buf[1024]; char trace_fh[TRACE_FH_SIZE]; char intbuf[9]; char * trace_path; char * p; int map_flag; int lineno = 0; int fh_map_debug =0; char name[MAX_NAMELEN]; fp = fopen(fh_map_file, "r"); if (!fp) { printf ("can not opern %s\n", fh_map_file); perror("open"); exit (0); } RFS_ASSERT (fp!=NULL); intbuf[8]=0; memset(buf, 0, sizeof(buf)); while (fgets(buf, 1024, fp)) { RFS_ASSERT (fh_map_debug==0); lineno ++; if (lineno % 10000==0) printf("%d fh_map entry read\n", lineno); RFS_ASSERT (buf[strlen(buf)-1]=='\n'); buf[strlen(buf)-1]=0; trace_path = buf + TRACE_FH_SIZE +1; strcpy (name, testdir); strcat (name, trace_path); if ((*(buf+strlen(buf)-1))=='/') { *(buf+strlen(buf)-1)=0; add_fh_t (&dir_fh, name, NOT_EXIST); } else { add_fh_t (&file_fh, name, NOT_EXIST); } } fclose(fp); if (fh_map_debug) { print_fh_map (&file_fh); print_fh_map (&dir_fh); } } int print_usage() { printf("age trace_file fh_path_map testdir\n"); } inline char * read_line (int disk_index) { static FILE * fp=NULL; static int start=0; static int start_disk_index=0; int i; static int finish_flag = 0; #define READ_LINE_BUF_SIZE 1000 #define READ_LINE_LENGTH 32 static char line_buf[READ_LINE_BUF_SIZE][READ_LINE_LENGTH]; start_profile (&read_line_profile); if (fp==NULL) { if (strcmp(trace_file, "stdin")) { fp = fopen(trace_file, "r"); if (!fp) { printf("can not open files %s\n", fp); perror("open"); } } else { fp = stdin; } RFS_ASSERT (fp!=NULL); for (i=0; i