现在的位置: 首页 > 综合 > 正文

Trace处理小工具

2013年07月06日 ⁄ 综合 ⁄ 共 13534字 ⁄ 字号 评论关闭

Seer Trace Collection:

http://www.lasr.cs.ucla.edu/seer/seer_traces.html

----------------------------------------------------------------------------------------------------------------------------------------------------------

/*
 * =====================================================================================
 *
 *       Filename:  seer_trace.c
 *    Description:  traslating seer format traces to the format can be used in object oriented file system
 *        Version:  1.0
 *        Created:  07/05/2012 12:17:11 AM
 *       Revision:  none
 *       Compiler:  gcc
 *          Author:  Si Ma 	
 *
 * =====================================================================================
 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "list.h"

#define MAX_CHARS 10000		// max number of chars of one line
#define MAX_FILES 20000		//max number of files used at the same time in one trace
#define SYSCALL_NUM 7
#define SYSCALL_NUM_MAC 5
/**
 *      file_node
 *      @  oid: 		       object id of this file, from the value of time33(pathname)
 *	  @  cur_offset:      current read/write offset
 *	  fd will be the index of file_node array...
 */
struct file_node{
	unsigned long oid;
	unsigned long cur_offset;
};
struct file_node File_hstb[MAX_FILES];


struct user{
	int usr_id;
	char cur_path[1000];
	struct list_head list;
};


/**
 *      system call list that we care about in the original trace file
 */
char *SYS_CALL[SYSCALL_NUM]={
	"open\0",	"chdir\0", "read\0",	"write\0",	"lstat\0",	"stat\0", "close\0"		//0--5
};

/**
 *      system call list that we care about in the original trace file
 */
char *SYS_CALL_MAC[SYSCALL_NUM_MAC]={
	"oread\0",
	"owrite\0",	
	"ogattr\0",	
	"osattr\0",
	"oflush\0"
};

/**
 *      type list of the lines in the trace file
 */
char *LINE_TYPE[3]={
	"UID\0",			//we only need this type and the other two will be ignored
	"TIMESTAMP\0",	
	"RESTART\0"
};

/**
 *      path2oid       -       mapping pathname to object id: time33 hashing
 */
unsigned long path2oid(char const *pathname, int len)
{
	unsigned long  hash = 0;
	int i ;
	for (i=0; i < len; i++) {
		hash = ((hash <<5) + hash) + (unsigned long) pathname[i];
	}
	return hash;
} 

/**
 *      type_of_op       -       check and return the specific index number according to SYS_CALL array
 *	  @op: operation string abstracted from the line buffer
 */
int type_of_op(char *op)
{
	int i=0;
	for(i=0; i<SYSCALL_NUM;i++){
		//printf("\nloop for the %d time", i+1);
		if(strcmp(op,SYS_CALL[i])==0)
			return i;
	}
	return -1;
}

/**
 *      extract_no_str       -       to extract the NO.(no+1) item from this line: l_buf
 *	  @l_buf: line buffer
 *	  @   no: the number of item in l_buf 
  *	  @  str: to save the NO.no item  in l_buf 
 */
int extract_no_str(char *l_buf, int no, char* str)
{
	int l_len=strlen(l_buf);
	int i=0, j=0, k=0;
	
	if(!str)
		return 1;
	for(i=0; i< l_len; i++){
		if(l_buf[i]==32){	//space: 32...
			j++;
			i=i+1;
			if(j==no-1)
				break;
		}
	}

	while(l_buf[i]!=32)
		str[k++]=l_buf[i++];
	str[k]='\0';
	return 0;
}

/**
 *      extract_op       -       to extract the operation item from this line: l_buf
 *	  @l_buf: line buffer
  *	  @  op: to save the operation item  in l_buf 
 */
int extract_op(char *l_buf, char* op)
{
	int l_len=strlen(l_buf);
	int i=0, j=0, k=0;
	
	if(!op)
		return 1;
	for(i=0; i< l_len; i++){
		if(l_buf[i]==32){	//space: 32...
			j++;
			i=i+1;
			if(j==8)
				break;
		}
	}

	while(l_buf[i]!='(')
		op[k++]=l_buf[i++];
	op[k]='\0';
	return 0;
}

/**
 *      extract_path       -       to extract the path item from this line: l_buf
 *	  @l_buf: line buffer
  *	  @  op: to save the path item  in l_buf 
 */
int extract_path(char *l_buf, char* path)
{
	int l_len=strlen(l_buf);
	int i=0, k=0;
	
	if(!path)
		return 1;
	while(l_buf[i]!=34)	//34 is ascii of ' "  '
		i++;
	i++;

	while(l_buf[i]!=34)
		path[k++]=l_buf[i++];
	path[k]='\0';

	//printf("\nIn extract_path and path is: %s", path);
	return 0;
}

/**
 *      extract_last_item       -       to extract the last item: return value from this line: l_buf
 *	  @l_buf: line buffer
 *	  @  rt: to save the last item  in l_buf 
 */
int extract_last_item(char *l_buf, char* rt)
{
	int k=0, l_len=strlen(l_buf);
	int off_set=l_len-3;
	while(l_buf[off_set]!='=')
			off_set--;

	//printf("\noff_set is: %d", off_set);
	k=0;
	off_set+=2;
	while((l_buf[off_set]<58)&&(l_buf[off_set]>44)&&(off_set < l_len))
		rt[k++]= l_buf[off_set++];
	rt[k]='\0';
	//printf("\nIn extract_last_item and fd is |%s|", rt);
	return 0;
}

struct user * user_lookup(struct list_head *user_list, int uid)
{
	struct list_head *pos;
	struct user *tmp;
	list_for_each(pos, user_list){
		tmp = list_entry(pos, struct user, list);
		//printf("\nuserid is :%d  pathname is: %s", tmp->usr_id, tmp->cur_path);
	}
	
	list_for_each(pos, user_list){
		tmp = list_entry(pos, struct user, list);
		if(tmp->usr_id==uid)
			return tmp;
	}
	return NULL;
}

int  free_userlist(struct list_head *user_list)
{
	printf("\nuser_lookup is called ...");
	struct list_head *pos;
	struct user *tmp;
	list_for_each(pos, user_list){
		tmp = list_entry(pos, struct user, list);
		list_del(&(tmp->list));
		free(tmp);
	}
	return 0;
}

int extract_rw_fd(char *l_buf, char *s_fd)
{
	int i=0, j=0;
	for(i=0;i<strlen(l_buf);i++)
		if(l_buf[i]=='(')
			break;
	i++;
	while(l_buf[i]!=',')
		s_fd[j++]=l_buf[i++];
	s_fd[j]='\0';

	return 0;
}

/**
 *      line_process       -       refine the operation and parameters according to the specific content of this line 
 *      @  l_buf: buffer contains this line
 *	  @   o_fs: object file stream handler 
 *	   file obj_trace.txt will contai the final trace result
 */
int line_process(char *l_buf, FILE *o_fs, struct list_head *user_list)
{
	int op_no=100;
	char l_type[10], op[10];
	extract_no_str(l_buf, 2, l_type);
	if(-1==strcmp(l_type,LINE_TYPE[0]))	//we only need type of "UID" and ignore "RESTART" and "TIMESTAMP"
			return 0;
	extract_op(l_buf, op);		//operation type
	op_no = type_of_op(op);
	switch(op_no){
	case 0:
		//printf("\nhandle line open...");
		handle_line_open(l_buf, user_list);
		break;
	case 1:
		//printf("\nhandle line chdir...");
		handle_line_chdir(l_buf, user_list);
		break;
	case 2:
		//printf("\nhandle line read...");
		handle_line_read(l_buf,o_fs);
		break;
	case 3:
		//printf("\nhandle line write...");
		handle_line_write(l_buf, o_fs);
		break;
	case 4:
	case 5:
		//printf("\nhandle line stat...");
		handle_line_path_stat(l_buf, user_list, o_fs);
		break;
	case 6:
		handle_line_close(l_buf,o_fs);
		break;
	default:
		break;
	}
	//printf("\nOne line is processed...");
	return 0;
}

int main(int argc, char *argv[])
{
	if(argc < 2){
		printf("\nPlease make sure that you have input your trace file!!\n");
		return 0;
	}else{
		printf("\nTrace file is: %s\n", argv[1]);
	}
	char  line_buf[MAX_CHARS];
	int i=0;
	FILE * fs, *ofs;
	struct list_head *user_list;	//=&usr_list;
	LIST_HEAD(ulist);
	user_list=&ulist;
	INIT_LIST_HEAD(user_list);	//define and init the user list

	
	fs = fopen(argv[1], "r+");
	ofs = fopen("obj_trace.txt", "a+");
	for(i=0;i<MAX_FILES;i++){	
		File_hstb[i].cur_offset = 0;
		File_hstb[i].oid =0;
	}

	i=0;
	if(fs && ofs){
		while(fgets(line_buf, MAX_CHARS, fs) > 0){	//get one line from the file...
				//if(i>220000)
				//	break;
				i++;
				line_process(line_buf, ofs, user_list);
		}
	}

	//free_userlist();
	printf("\nThe number of last line is:%d \n", i);
	fclose(fs);
	fclose(ofs);
	return 0;
}



/**
 *      handle_line_open       -       process a line of open trace
 *      @  l_buf: buffer contains this line 
 */
 
int handle_line_open(char *l_buf, struct list_head *user_list)
{
	int fd=0;
	char pathname[500], s_fd[150], tmppath[500];
	struct user *cur_user=NULL;
	int i=0, j=0;
	int usr_id;
	char uid[10];
	
	extract_last_item(l_buf, s_fd);
	fd=atoi(s_fd);
	//printf("\nfd:%d...",fd);
	if(fd<0||fd>20000)		//if open failed , just ignore this line
		return 0;

	extract_path(l_buf,pathname);
	switch(pathname[0]){

	case '.':
		//printf("\nopen case .    ..");
		extract_no_str(l_buf, 3, uid);
		usr_id=atoi(uid);
		cur_user=user_lookup(user_list, usr_id);
		if(cur_user==NULL){
			cur_user=(struct user*)malloc(sizeof(struct user));
			cur_user->cur_path[0]='/';
			cur_user->cur_path[1]='\0';	//default current path :  "/"
			cur_user->usr_id=usr_id;
			list_add(&(cur_user->list), user_list);	//add this new user to the list
			strcpy(pathname,cur_user->cur_path);
		}else{
			if((strlen(pathname)>=2)&&pathname[1]=='.'){
				strcpy(tmppath,cur_user->cur_path);
				for(i=strlen(tmppath);i>0; i--)	//here we assume ../../../  will not emerge...
					if(tmppath[i]=='/'){
						tmppath[i]='\0';
						break;
					}
				for(i=0; i<strlen(pathname)-2;i++)//delete .. from the head
					pathname[i]=pathname[i+2];
				strcat(tmppath, pathname);
				strcpy(pathname,tmppath);		//here the dir of the file is ok...
			}else if((strlen(pathname)>=2)&&pathname[1]=='/'){
				strcpy(tmppath,cur_user->cur_path);
				for(i=0; i<strlen(pathname);i++)
					pathname[i]=pathname[i+1];
				strcat(tmppath, pathname);
				strcpy(pathname,tmppath);		
			}else{						//case the file type like .config
				strcpy(tmppath,cur_user->cur_path);
				j=strlen(pathname);
				if(pathname[j-1]!='/'){
					pathname[j]='/';
					pathname[j+1]='\0';
				}
				strcat(tmppath, pathname);
				strcpy(pathname,tmppath);		
			}
		}
		break;
	case '/':
		//printf("\nopen case /    ..");
		break;
	default:
		//printf("\nopen case default    ..");
		extract_no_str(l_buf, 3, uid);
		usr_id=atoi(uid);
		cur_user=user_lookup(user_list, usr_id);
		if(cur_user==NULL){
			cur_user=(struct user*)malloc(sizeof(struct user));
			cur_user->cur_path[0]='/';
			cur_user->cur_path[1]='\0';	//default current path :  "/"
			cur_user->usr_id=usr_id;
			list_add(&(cur_user->list), user_list);	//add this new user to the list
			strcpy(pathname,cur_user->cur_path);
		}else{
			strcpy(tmppath,cur_user->cur_path);
			j=strlen(pathname);
			if(pathname[j-1]!='/'){
				pathname[j]='/';
				pathname[j+1]='\0';
			}
			strcat(tmppath, pathname);
			strcpy(pathname,tmppath);		//here the dir of the file is ok...
		}
		break;
	}

	//printf("\npathname is: %s", pathname);
	File_hstb[fd].cur_offset= 0;
	File_hstb[fd].oid=path2oid(pathname, strlen(pathname));
	return 0;
}

int handle_line_chdir(char *l_buf, struct list_head *user_list)
{
	int fd=0;
	char pathname[5000], s_fd[15], tmppath[5000];
	struct user *cur_user=NULL;
	int i=0, j=0;
	int usr_id;
	char uid[10];
	
	extract_last_item(l_buf, s_fd);
	fd=atoi(s_fd);
	if(fd<0||fd>20000)		//if open failed , just ignore this line
		return 0;
	extract_path(l_buf,pathname);
	extract_no_str(l_buf, 3, uid);
	usr_id=atoi(uid);
	cur_user=user_lookup(user_list, usr_id);
	if(cur_user==NULL){
		cur_user=(struct user*)malloc(sizeof(struct user));
		cur_user->cur_path[0]='/';
		cur_user->cur_path[1]='\0';
		cur_user->usr_id=usr_id;
		list_add(&(cur_user->list), user_list);	//add this new user to the list
		strcpy(cur_user->cur_path, pathname);
	}else{
		//printf("\nOrignal cur-path is:%s and pathname is: %s", cur_user->cur_path, pathname);
		switch(pathname[0]){
		case '.':
			//printf("\nEntering . dir...");
			if((strlen(pathname)>=2)&&(pathname[1]=='.')){
				strcpy(tmppath,cur_user->cur_path);
				//printf("\nAfter strcpy .. dir...");
				j=0;
				for(i=strlen(tmppath);i>0; i--){	//cd .. here we assume ../../../  will not emerge...
					if(tmppath[i]=='/'){
						j++;
						if(j==2){
							tmppath[i]='\0';
							break;
						}
					}
					//printf("\ni value is: %d", i);
				}
				for(i=0; i<strlen(pathname);i++)//delete .. from the head
					pathname[i]=pathname[i+2];
				strcat(tmppath, pathname);
				strcpy(cur_user->cur_path,tmppath);	
			}else{
				strcpy(tmppath,cur_user->cur_path);
				for(i=0; i<strlen(pathname);i++) 
					pathname[i]=pathname[i+1];
				strcat(tmppath, pathname);
				strcpy(cur_user->cur_path,tmppath);		//here the dir of the file is ok...
			}
			break;
		case '/':
			if(cur_user->cur_path[strlen(cur_user->cur_path)-1]=='/'){
				for(i=0; i<strlen(pathname)-1;i++)
					tmppath[i]=pathname[i+1];
				tmppath[i]='\0';
				strcat(cur_user->cur_path,tmppath);	
			}else
				strcat(cur_user->cur_path, pathname);
			strcpy(cur_user->cur_path,pathname);
			break;
		default:		//	directly a name string....
			if(cur_user->cur_path[strlen(cur_user->cur_path)-1]!='/'){
				tmppath[0]='/';
				for(i=0; i<strlen(pathname);i++)
					tmppath[i+1]=pathname[i];
				tmppath[i+2]='\0';
				strcat(cur_user->cur_path,tmppath);	
			}else
				strcat(cur_user->cur_path, pathname);

			break;
		}
	}
	//printf("\nAfter chdir:  cur-path is:%s", cur_user->cur_path);
	
	return 0;
}

int handle_line_read(char *l_buf,  FILE * o_fs)
{
	int fd, rcount;
	char s_fd[15],  s_rct[15];
	extract_rw_fd(l_buf, s_fd);	
	fd=atoi(s_fd);
	extract_last_item(l_buf, s_rct);	
	rcount=atoi(s_rct);
	if(rcount<=0)
		return 0;
	if(o_fs)
		fprintf(o_fs,"0 %s %lu %lu %d\n", SYS_CALL_MAC[0], File_hstb[fd].oid, File_hstb[fd].cur_offset, rcount);
	else
		printf("\nInvalid file handler...");
	File_hstb[fd].cur_offset+=rcount;
	
	return 0;
}

int handle_line_close(char *l_buf,  FILE * o_fs)
{
	int fd;
	char s_fd[15];
	extract_rw_fd(l_buf, s_fd);	
	fd=atoi(s_fd);
	
	if(o_fs)
		fprintf(o_fs,"0 %s %lu\n", SYS_CALL_MAC[4], File_hstb[fd].oid);
	else
		printf("\nInvalid file handler...");
	return 0;
}

int handle_line_write(char *l_buf,  FILE * o_fs)
{
	int fd, count;
	char s_fd[15],  s_ct[15];
	extract_rw_fd(l_buf, s_fd);	
	fd=atoi(s_fd);
	extract_last_item(l_buf, s_ct);	
	count=atoi(s_ct);
	if(count<=0)
		return 0;
	if(o_fs)
		fprintf(o_fs,"0 %s %lu %lu %d\n", SYS_CALL_MAC[1], File_hstb[fd].oid, File_hstb[fd].cur_offset, count);
	else
		printf("\nInvalid file handler...");
	File_hstb[fd].cur_offset+=count;
	
	return 0;
}

int handle_line_path_stat(char *l_buf, struct list_head *user_list,  FILE * o_fs)
{
	int rtv=0;
	char pathname[5000], s_rt[15], tmppath[5000];
	struct user *cur_user=NULL;
	int i=0, j=0;
	int usr_id;
	char uid[10];
	
	extract_last_item(l_buf, s_rt);
	rtv=atoi(s_rt);
	if(rtv<0)		//if stat failed , just ignore this line
		return 0;

	//printf("\n\n\nin handle line stat and before extract pathname...");
	extract_path(l_buf,pathname);
	switch(pathname[0]){
	case '.':
		//printf("\nIn stat case .   ....");
		extract_no_str(l_buf, 3, uid);
		usr_id=atoi(uid);
		cur_user=user_lookup(user_list, usr_id);
		if(cur_user==NULL){
			cur_user=(struct user*)malloc(sizeof(struct user));
			cur_user->cur_path[0]='/';
			cur_user->cur_path[1]='\0';	//default current path :  "/"
			cur_user->usr_id=usr_id;
			list_add(&(cur_user->list), user_list);	//add this new user to the list
			strcpy(pathname,cur_user->cur_path);
			break;
		}

		if((strlen(pathname)>=2)&&pathname[1]=='.'){
			//printf("\nEntering .. process...");
			strcpy(tmppath,cur_user->cur_path);
			for(i=strlen(tmppath);i>0; i--)	//here we assume ../../../  will not emerge...
				if(tmppath[i]=='/'){
					tmppath[i]='\0';
					break;
				}
			for(i=0; i<strlen(pathname);i++)//delete .. from the head
				pathname[i]=pathname[i+2];
			strcat(tmppath, pathname);
			strcpy(pathname,tmppath);		//here the dir of the file is ok...
		
		}else if((strlen(pathname)>=3)&&pathname[1]=='/'){
			strcpy(tmppath,cur_user->cur_path);
			for(i=0; i<strlen(pathname);i++)//delete .. from the head
				pathname[i]=pathname[i+1];
			strcat(tmppath, pathname);
			strcpy(pathname,tmppath);		 
		}else{							//case the file type .config
			strcpy(tmppath,cur_user->cur_path);
			j=strlen(pathname);
			pathname[j]='/';
			pathname[j+1]='\0';
			strcat(tmppath, pathname);
			strcpy(pathname,tmppath);		//here the dir of the file is ok...
		}
		break;
	case '/':
		//printf("\nIn stat case /   ....");
		break;
	default:
		//printf("\nIn stat case default   ....");
		extract_no_str(l_buf, 3, uid);
		usr_id=atoi(uid);
		cur_user=user_lookup(user_list, usr_id);
		if(cur_user==NULL){
			cur_user=(struct user*)malloc(sizeof(struct user));
			cur_user->cur_path[0]='/';
			cur_user->cur_path[1]='\0';	//default current path :  "/"
			cur_user->usr_id=usr_id;
			list_add(&(cur_user->list), user_list);	//add this new user to the list
			strcpy(pathname,cur_user->cur_path);
		}else{
			strcpy(tmppath,cur_user->cur_path);
			j=strlen(pathname);
			pathname[j]='/';
			pathname[j+1]='\0';
			strcat(tmppath, pathname);
			strcpy(pathname,tmppath);		//here the dir of the file is ok...
		}
		
		break;
	}
	
	if(o_fs)
		fprintf(o_fs,"0 %s %lu\n", SYS_CALL_MAC[2], path2oid(pathname, strlen(pathname)));
	else
		printf("\nInvalid file handler...");
	
	return 0;
}

抱歉!评论已关闭.