Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_play / rfs_c_age.c.trace_base
diff --git a/TBBT/trace_play/rfs_c_age.c.trace_base b/TBBT/trace_play/rfs_c_age.c.trace_base
new file mode 100644 (file)
index 0000000..adeeca5
--- /dev/null
@@ -0,0 +1,551 @@
+#include <sys/vfs.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#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; i<fh_table->fh_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)<MAX_PLAY_PATH_SIZE);
+                       strcpy (fh_table->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; i<fhp->fh_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<READ_LINE_BUF_SIZE; i++) {
+                       start_profile(&fgets_profile);
+                       if (!fgets(line_buf[i], READ_LINE_LENGTH, fp)) {
+                               RFS_ASSERT (0);
+                       }
+                       end_profile(&fgets_profile);
+                       //printf ("read_line, line_buf[%d]:%s", i, line_buf[i]);
+               }
+       }
+       
+       RFS_ASSERT (disk_index <= start_disk_index+READ_LINE_BUF_SIZE)
+       if (disk_index==(start_disk_index+READ_LINE_BUF_SIZE)) {
+               if (finish_flag) {
+                       return NULL;
+               }
+               start_profile(&fgets_profile);
+               if (!fgets(line_buf[start], READ_LINE_LENGTH, fp)) {
+                       end_profile(&fgets_profile);
+                       fclose(fp);
+                       finish_flag = 1;
+                       return NULL;
+               }
+               end_profile(&fgets_profile);
+               //printf ("read_line, line_buf[%d]:%s", start, line_buf[start]);
+               start = (start+1) % READ_LINE_BUF_SIZE;
+               start_disk_index ++;
+       }
+       RFS_ASSERT (disk_index < start_disk_index+READ_LINE_BUF_SIZE)
+       i = (start+disk_index-start_disk_index)%READ_LINE_BUF_SIZE;
+
+       end_profile (&read_line_profile);
+       return (line_buf[i]);
+}
+
+int f()
+{};
+
+int print_result()
+{
+       struct statfs stfs;
+       int ret;
+       ret = statfs (testdir, &stfs);
+       RFS_ASSERT (ret == 0);
+       fprintf(stderr, "number of files %d size of file system %d\n", stfs.f_files, stfs.f_bfree);
+       fprintf(stderr, "assure_create_num %d assure_mkdir_num %d, age_create_num %d age_mkdir_num %d age_write_num %d nonage_write_num %d overlap_write_num %d\n",
+                       assure_create_num, assure_mkdir_num, age_create_num, age_mkdir_num, age_write_num, nonage_write_num, overlap_write_num);
+       printf("assure_create_num %d assure_mkdir_num %d, age_create_num %d age_mkdir_num %d age_write_num %d nonage_write_num %d overlap_write_num %d\n",
+                       assure_create_num, assure_mkdir_num, age_create_num, age_mkdir_num, age_write_num, nonage_write_num, overlap_write_num);
+}
+
+int main(int argc, char ** argv)
+{
+       char * buf;
+       static int disk_index=0;
+       int j, nfs3proc, size, off, count;
+       char procname[16];
+       struct stat st;
+       int ret;
+
+       if (argc!=4) {
+               print_usage();
+               exit(0);
+       }
+
+       init();
+       strcpy (trace_file, argv[1]);
+       strcpy (testdir, argv[3]);
+       ret = stat (testdir, &st);
+       RFS_ASSERT (ret == 0);
+       read_fh_map(argv[2]);
+       init_profile_variables();
+
+       while ((buf=read_line(++disk_index))!=NULL) {
+
+               memset (procname, 0, sizeof(procname));
+               //printf ("line[%d] %s", disk_index, buf);
+               sscanf (&buf[0], "%s", procname);
+               j = 0;
+               while ((*(buf+j)!=' ') && (*(buf+j)!='\n'))
+                       j++;
+               j++;
+               if (!strcmp(procname, "write"))
+                       sscanf (&buf[j], "off %x count %x", &off, &count);
+
+               if (!strcmp(procname, "setattr")) 
+                       sscanf (&buf[j], "size %x", &size);
+
+               if (!strcmp(procname, "write"))
+                       ret = write_op(off, count);
+               else if (!strcmp(procname, "create")) 
+                       ret = create_mkdir_op(IS_FILE); 
+               else if (!strcmp(procname, "mkdir")) 
+                       ret = create_mkdir_op(IS_DIR);
+               else if (!strcmp(procname, "remove")) 
+                       ret = remove_op(); 
+               else if (!strcmp(procname, "rmdir")) 
+                       ret = rmdir_op();
+               else if (!strcmp(procname, "setattr")) 
+                       ret = truncate_op(size);
+               else {
+                       printf("disk_index %d procname %s\n", disk_index, procname);
+                       RFS_ASSERT (0);
+               }
+               if (ret!=0) {
+                       printf("execute disk_line[%d] %s error\n", disk_index, buf);
+               }
+               if ((disk_index%100)==0) {
+                       fprintf (stderr, "%d disk trace parsed \n", disk_index);
+                       print_result();
+               }
+       }
+       print_result();
+}