Chinaunix首页 | 论坛 | 博客
  • 博客访问: 186575
  • 博文数量: 12
  • 博客积分: 247
  • 博客等级: 二等列兵
  • 技术积分: 286
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 10:24
个人简介

一名默默挣扎在研发前线的女程序猿

文章分类

全部博文(12)

文章存档

2013年(4)

2012年(8)

我的朋友

分类: LINUX

2013-06-17 11:56:12

1 工具简介

1.1 概述

     disksim是一个高效、准确、高度可配置的磁盘系统模拟器,用以支持对各种存储体系的方方面面的性能的研究,它由c编写且开源。它具有多种模块,配置多样,已在许多存储系统效率及性能的研究中应用,被证明能很很真实的模拟存储系统的工作情况。

     disksim能够模拟并且报告与存储子系统相关的性能相关项,其仅能够对磁盘子系统的性能相关项进行建模,而不能存储与恢复每一个请求的真实数据。

1.2 命令

command

disksim

disksim

可执行程序的名称。【注】disksim是无需安装的,直接编译之后运行可执行文件即可

parfile

运行参数文件(按照特定的格式,具体参考2.1节)

outfile

输出文件。output file的项目内容及大小可以在parafile中设置,以去掉一些不感兴趣的内容。(按照特定的格式,具体参考2.2节)

tracetype

确定输入trace的格式(具体参考2.3节)

tracefile

标识用作输入的trace文件

synthen

决定合成负载部分的模拟器是否打开。其中:0表示关闭;除0以外的数表示开启。parameter file设置了负载合成器的数量和合成负载的格式。【注】综合生成器由参数文件中的值进行配置,具体参考2.4节。其中,不能同时使用tracefile和内部产生的综合负载同时作为输入

par_override

允许默认参数值或者parfile文件中的参数值替代命令行指定的值。具体参考1.3

1.3 参数重写

command

component

需要重写参数的组件名称。一般为磁盘名称,若有多个磁盘disk0~disk5,有以下两种书写方式:disk[0~5] or disk*(其中,*表示0或多个数字字符)

parameter

表示要被重写的参数标示符(在parameter file中使用的变量名)。若要引用子组件的参数,例如scheduler的参数,可写成:Schduler:parameter

new value

指定给参数的新值

说明

参数重写在参数文件读取完毕之后进行,但是在内部配置开始之前。任何在parameter 文件中定义的参数都可以使用命令行进行重写。

 

2 格式说明

2.1 参数文件格式

  参数文件可以为各种存储子系统建模。disksim通过libparam来输入参数文件。一个参数文件由以下三部分组成:

1)    程序块,由{}界定

  由“name = value”赋值语句组成。

例如:

disksim_global Global {

Init Seed = 42,

Real Seed = 42,

# Statistic warm-up period = 0.0 seconds,

Stat definition file = statdefs

}

2)    实体

3)    拓扑规范

  其中,每个参数文件必须包含GlobalStats块。然后再定义一些bus(总线)、controller(控制器)以及一个(iodriver)输入输出驱动,然后定义或引入一些存储设备的描述,之后将其实例化,最后以一种拓扑规范定义这些组件之间的联系。磁盘阵列以logorg block来描述,必须在parfile中定义至少一个logorg block;设备的轮转同步可选地在syncet block中描述;调整trace中的时间规模和和映射请求可在iosim block中描述。若使用synthetic trace generater则必须包含ProcSynthio块。

2.2 输出文件格式

2.2.1   Simulation result

前三个总量

格式

:

context

静态分析的上下文

statname

statdefs文件的索引名称

type

集合类型,average, std.dev, maximun

value

具体的值

?  之后的部分由输入样式决定。

2.3 tracetype类型

disksim支持的trace格式有默认格式(ASCII)、验证格式(validate)、原始格式(RAW)。默认格式为普通的ascii流或者文件,每一行包括五个参数的值(以空格隔开)以描述一个磁盘请求。这5个参数为:                                                                 

1)        请求到达时间Float型,表示从模拟开始0.0到请求发生的时间,必需按时间顺序);

2)        设备号码int 型);

3)        blockint型,表示请求的设备地址,其值为逻辑设备的可访问单元);

4)        请求大小int型,请求的大小,单位为blocks);

5)        请求选项(十进制int型,每一位是01表示一个选项是否开启,每一位的定义见disksim_global.h

2.4 Synthetic workloads

       模型可以配置一定范围的synthetic workloads, 均与磁盘位置访问和请求到达时间相关。其中,每一个合成器以一个处于系统态的进程,在一定的思考时间后发出io请求,然后等待io请求完成。

 

3 工具安装

【说明】 disksim 只适合于在32位系统上运行,在64位的系统中就算是编译通过,runvalid的时候也会报错。为了让disksim能够在64位系统上运行,需要按照以下步骤进行编译。

Step 1.              获取软件:

【参考svn路径】

软件

Step 2.              将软件拷贝到虚拟机的任意路径下,本例中拷贝到/work/softwore

Step 3.              安装基本插件:

yum install bison flex

Step 4.              解压软件

tar xfz disksim-4.0-with-dixtrac.tar.gz

cd disksim-4.0

unzip ../ssd-add-on.zip

Step 5.              应用SSDpatch

patch -p1 < ssdmodel/ssd-patch

Step 6.              ssd model库的路径添加到dixtrac

vim dixtrac/.paths

# path to ssdmodel

export SSDMODEL_PREFIX=../ssdmodel

export SSDMODEL_INCL=$(SSDMODEL_PREFIX)/include

export SSDMODEL_CFLAGS=-I$(SSDMODEL_INCL)

export SSDMODEL_LDPATH=$(SSDMODEL_PREFIX)/lib

export SSDMODEL_LDFLAGS=-L$(SSDMODEL_LDPATH) -lssdmodel

修改dixtrac/Makefile

$(LIBDISKSIM_LDFLAGS) \

$(MEMSMODEL_LDFLAGS) \

$(DISKMODEL_LDFLAGS) \

$(SSDMODEL_LDFLAGS) \

$(LIBPARAM_LDFLAGS) \

$(LIBDDBG_LDFLAGS) \

$(ST_LDFLAGS)

CFLAGS = -Wall -g -MD -I. $(DEFINES) -I$(STHREADS) $(DMINCLUDES) \

$(LIBDISKSIM_CFLAGS) \

$(DISKMODEL_CFLAGS) $(LIBPARAM_CFLAGS) $(LIBDDBG_CFLAGS) \

$(SSDMODEL_CFLAGS)

Step 7.              遇到的错误处理

1)        duplicate case value

       这个错误的意思是switch语句里面,两个case使用了相同的值。出错的代码在src/disksim_iosim.c:712,代码很有意思:

StaticAssert (sizeof(ioreq_event) <= DISKSIM_EVENT_SIZE);

将该行注释就行。

2)        segment fault

程序编译成功之后,若运行valid会遇到很多段错误,解决方案是打patch。pacth文件参考附件

由于打了ssd-patch之后,行号发生了变化,因此该patch直接运行有误。故而应该采用人工打patch的方法。
patch信息如下:
diff -urN disksim-4.0/diskmodel/layout_g1.c disksim-4.0.x86_64/diskmodel/layout_g1.c
--- disksim-4.0/diskmodel/layout_g1.c 2009-12-29 20:56:51.141949420 +0900
+++ disksim-4.0.x86_64/diskmodel/layout_g1.c 2009-12-29 19:46:03.834085354 +0900
@@ -1939,10 +1939,10 @@
      struct dm_layout_zone *result)
 {
   struct dm_layout_g1 *l = (struct dm_layout_g1 *)d->layout;
-  struct dm_layout_g1_band *z;
+  struct dm_layout_g1_band *z = calloc(sizeof(struct dm_layout_g1_band), 1);


   // check args  
-  if(z == 0) { return -1; }
+  if(z == NULL) { return -1; }
   if(n < 0 || n >= l->bands_len) { return -1; }


   z = &l->bands[n];
diff -urN disksim-4.0/diskmodel/layout_g2.c disksim-4.0.x86_64/diskmodel/layout_g2.c
--- disksim-4.0/diskmodel/layout_g2.c 2007-01-09 13:58:48.000000000 +0900
+++ disksim-4.0.x86_64/diskmodel/layout_g2.c 2009-12-29 19:46:03.835085497 +0900
@@ -248,13 +248,13 @@


   // return st for the nearest (lower) zone if this cyl is unmapped
   while(!(z = find_zone_pbn(d, &p2)) && p2.cyl >= 0) { p2.cyl--; }
-  ddbg_assert(z);
+  ddbg_assert(z != NULL);


   return z->st;
 }


-static void
+static dm_ptol_result_t
 track_boundaries(struct dm_disk_if *d,
    struct dm_pbn *p,
    int *l1,
@@ -283,6 +283,7 @@
       *l2 = d->layout->dm_translate_ptol(d, &p2, remapsector);
     } while((*l2 == DM_NX) && p2.sector);
   }
+  return DM_OK;
 }


 static dm_angle_t
diff -urN disksim-4.0/dixtrac/.paths disksim-4.0.x86_64/dixtrac/.paths
--- disksim-4.0/dixtrac/.paths 2009-12-29 20:57:46.518830693 +0900
+++ disksim-4.0.x86_64/dixtrac/.paths 2009-12-29 19:46:22.429960003 +0900
@@ -39,3 +39,10 @@
 export MEMSMODEL_CFLAGS=-I$(MEMSMODEL_INCL)
 export MEMSMODEL_LDPATH=$(MEMSMODEL_PREFIX)/lib
 export MEMSMODEL_LDFLAGS=-L$(MEMSMODEL_LDPATH) -lmemsmodel
+
+# path to ssdmodel
+export SSDMODEL_PREFIX=../ssdmodel
+export SSDMODEL_INCL=$(SSDMODEL_PREFIX)/include
+export SSDMODEL_CFLAGS=-I$(SSDMODEL_INCL)
+export SSDMODEL_LDPATH=$(SSDMODEL_PREFIX)/lib
+export SSDMODEL_LDFLAGS=-L$(SSDMODEL_LDPATH) -lssdmodel
diff -urN disksim-4.0/dixtrac/Makefile disksim-4.0.x86_64/dixtrac/Makefile
--- disksim-4.0/dixtrac/Makefile 2008-05-15 15:37:34.000000000 +0900
+++ disksim-4.0.x86_64/dixtrac/Makefile 2009-12-29 20:17:39.857941323 +0900
@@ -57,13 +57,15 @@
  $(LIBDISKSIM_LDFLAGS) 
  $(MEMSMODEL_LDFLAGS) 
  $(DISKMODEL_LDFLAGS) 
+ $(SSDMODEL_LDFLAGS) 
  $(LIBPARAM_LDFLAGS) 
  $(LIBDDBG_LDFLAGS) 
  $(ST_LDFLAGS)


 CFLAGS   = -Wall -g -MD -I. $(DEFINES) -I$(STHREADS) $(DMINCLUDES) 
  $(LIBDISKSIM_CFLAGS) 
- $(DISKMODEL_CFLAGS) $(LIBPARAM_CFLAGS) $(LIBDDBG_CFLAGS) 
+ $(DISKMODEL_CFLAGS) $(LIBPARAM_CFLAGS) $(LIBDDBG_CFLAGS) 
+ $(SSDMODEL_CFLAGS)


 all: all-redirect
diff -urN disksim-4.0/libparam/myutil.c disksim-4.0.x86_64/libparam/myutil.c
--- disksim-4.0/libparam/myutil.c 2008-05-12 07:09:29.000000000 +0900
+++ disksim-4.0.x86_64/libparam/myutil.c 2009-12-29 20:23:44.199835151 +0900
@@ -150,7 +150,7 @@
 {
   struct lp_param *result = calloc(1, sizeof(struct lp_param));
   result->source_file = source;
-  result->name = name;
+  result->name = strdup(name);
   result->v = v;


diff -urN disksim-4.0/libparam/util.c disksim-4.0.x86_64/libparam/util.c
--- disksim-4.0/libparam/util.c 2009-12-29 20:56:51.143862773 +0900
+++ disksim-4.0.x86_64/libparam/util.c 2009-12-29 20:34:08.735171314 +0900
@@ -47,7 +47,7 @@


 #include 


-//#include 
+#include 


 #include "libparam.h"
 #include "bitvector.h"
@@ -941,12 +941,15 @@
       (*b)[c] = p;
       break;
     }
+    printf("%d: name = %sn", c, (*b)[c]->name);
   }
-  if(c == *plen) {
+  fflush(stdout);
+  if(c == *plen) { // BONK
     /* didn't find a free slot -- double the array */
     int newlen = 2 * (*plen) + 1;
-    (*b) = realloc((*b), newlen * sizeof(int *));
-    bzero((int *)(*b) + *plen, ((*plen) + 1) * sizeof(int*));
+    struct lp_param **new = calloc(newlen, sizeof(struct lp_param *));
+    memcpy(new, *b, (*plen) * sizeof(struct lp_param *));
+    (*b) = new;
     (*b)[(*plen)] = p;
     *plen = newlen;
   }
@@ -986,7 +989,7 @@


   for(c = 0; c < lp_max_mod; c++) {


-    lp_typetbl[c] = malloc(sizeof(struct lp_subtype));
+    lp_typetbl[c] = calloc(sizeof(struct lp_subtype),1);
     bzero(lp_typetbl[c], sizeof(struct lp_subtype));
     lp_typetbl[c]->sub = strdup(lp_modules[c]->name);
   }
@@ -1395,20 +1398,22 @@
   int i;


 #ifndef _WIN32
-  if(name[0] == '/')
+  if(name[0] == '/'){
     if(stat(name, &s))
       goto fail;
     else
       goto succ;
+  }


   snprintf(cand, LP_PATH_MAX, "%s/%s", cwd, name);


 #else
-  if(name[0] == '\')
+  if(name[0] == '\'){
     if(stat(name, &s))
       goto fail;
     else
       goto succ;
+  }


   if (strcmp(cwd, "") == 0)
       cwd = ".";
diff -urN disksim-4.0/src/disksim_device.c disksim-4.0.x86_64/src/disksim_device.c
--- disksim-4.0/src/disksim_device.c 2009-12-29 20:56:51.145831412 +0900
+++ disksim-4.0.x86_64/src/disksim_device.c 2009-12-29 19:46:03.836085835 +0900
@@ -143,32 +143,24 @@
   /* note that numdisks must be equal to diskinfo->disks_len */
   newlen = numdevices ? (2 * numdevices) : 2;
   zerocnt = (newlen == 2) ? 2 : (newlen/2);
-  disksim->deviceinfo->devicenames = 
-    realloc(disksim->deviceinfo->devicenames, newlen * sizeof(char *));
-  bzero(disksim->deviceinfo->devicenames + c, zerocnt * sizeof(char *));
-
-  devicenos = realloc(devicenos, newlen*sizeof(int));
-#ifndef WIN32
-  bzero(devicenos + c, zerocnt * sizeof(int));
-#else
-  bzero(devicenos + c, zerocnt * sizeof(*(devicenos)));
-#endif
-
-  devicetypes = realloc(devicetypes, newlen*sizeof(int));
-#ifndef WIN32
-  bzero(devicetypes + c, zerocnt * sizeof(int));
-#else
-  bzero(devicetypes + c, zerocnt * sizeof(*(devicetypes)));
-#endif
-
-  disksim->deviceinfo->devices = realloc(disksim->deviceinfo->devices, 
-      newlen*sizeof(int));
-#ifndef WIN32
-  bzero(disksim->deviceinfo->devices + c, zerocnt * sizeof(int));
-#else
-  bzero(disksim->deviceinfo->devices + c, zerocnt * sizeof(*(disksim->deviceinfo->devices)));
-#endif


+  char **tmpdevname = calloc(newlen, sizeof(char *));
+  int *newdevnos    = calloc(newlen, sizeof(int));
+  int *newdevtypes  = calloc(newlen, sizeof(int));
+  struct deviceheader **newdevs = calloc(newlen, sizeof(struct deviceheader *));
+
+  if (numdevices){
+    memcpy(tmpdevname, disksim->deviceinfo->devicenames, numdevices * sizeof(char*));
+    memcpy(newdevnos, devicenos, numdevices * sizeof(int));
+    memcpy(newdevtypes, devicetypes, numdevices * sizeof(int));
+    memcpy(newdevs, disksim->deviceinfo->devices,
+    numdevices * sizeof(struct deviceheader *));
+  }
+
+  disksim->deviceinfo->devicenames = tmpdevname;
+  devicenos = newdevnos;
+  devicetypes = newdevtypes;
+  disksim->deviceinfo->devices = newdevs;
   disksim->deviceinfo->devs_len = newlen;


  foundslot:
diff -urN disksim-4.0/src/disksim_global.h disksim-4.0.x86_64/src/disksim_global.h
--- disksim-4.0/src/disksim_global.h 2009-12-29 20:56:51.157895353 +0900
+++ disksim-4.0.x86_64/src/disksim_global.h 2009-12-29 19:46:03.836085835 +0900
@@ -253,7 +253,7 @@
    int    temp;
 } foo;


-#define DISKSIM_EVENT_SIZE 128
+#define DISKSIM_EVENT_SIZE 200
 #define DISKSIM_EVENT_SPACESIZE (DISKSIM_EVENT_SIZE - sizeof(struct foo))


 typedef struct ev {
diff -urN disksim-4.0/src/disksim_iosim.c disksim-4.0.x86_64/src/disksim_iosim.c
--- disksim-4.0/src/disksim_iosim.c 2009-12-29 20:56:51.157895353 +0900
+++ disksim-4.0.x86_64/src/disksim_iosim.c 2009-12-29 20:34:30.740046410 +0900
@@ -353,10 +353,7 @@
    slotpath->byte[depth] = (inslotno & 0x0F) | (outslotno << 4);
 }


-
-
-
-static int iosim_load_map(struct lp_block *b, int n) {
+static int iosim_load_map(struct lp_block *b, int64_t n) {
   int c;
   int i = 0;
   char *s = 0; 
diff -urN disksim-4.0/ssdmodel/include/ssdmodel/ssd.h disksim-4.0.x86_64/ssdmodel/include/ssdmodel/ssd.h
--- disksim-4.0/ssdmodel/include/ssdmodel/ssd.h 2008-09-12 14:20:00.000000000 +0900
+++ disksim-4.0.x86_64/ssdmodel/include/ssdmodel/ssd.h 2009-12-29 20:24:10.100271314 +0900
@@ -127,7 +127,7 @@
     int *lba_table;                 // a table mapping the lba to the physical pages
                                     // on the chip.


-    char *free_blocks;              // each bit indicates whether a block in the
+    unsigned char *free_blocks;              // each bit indicates whether a block in the
                                     // ssd_element is free or in use. number of bits
                                     // in free_blocks is given by
                                     // (struct ssd*)->params.blocks_per_element
diff -urN disksim-4.0/ssdmodel/ssd.h disksim-4.0.x86_64/ssdmodel/ssd.h
--- disksim-4.0/ssdmodel/ssd.h 2008-08-14 19:05:52.000000000 +0900
+++ disksim-4.0.x86_64/ssdmodel/ssd.h 2009-12-29 19:46:03.836085835 +0900
@@ -127,7 +127,7 @@
     int *lba_table;                 // a table mapping the lba to the physical pages
                                     // on the chip.


-    char *free_blocks;              // each bit indicates whether a block in the
+    unsigned char *free_blocks;              // each bit indicates whether a block in the
                                     // ssd_element is free or in use. number of bits
                                     // in free_blocks is given by
                                     // (struct ssd*)->params.blocks_per_element
diff -urN disksim-4.0/ssdmodel/ssd_init.c disksim-4.0.x86_64/ssdmodel/ssd_init.c
--- disksim-4.0/ssdmodel/ssd_init.c 2008-08-16 14:10:34.000000000 +0900
+++ disksim-4.0.x86_64/ssdmodel/ssd_init.c 2009-12-29 20:34:43.724920839 +0900
@@ -445,7 +445,7 @@


 void ssd_initialize (void)
 {
-    static print1 = 1;
+//    static print1 = 1;
    int i, j;


    if (disksim->ssdinfo == NULL) {


Step 8.              编译

make

Step 9.              检查是否成功

cd valid; ./runvalid

运行效果如下:

chmod a+x runvalid

./runvalid

4 工具使用

Example 1

命令

disksim data.parv data.out validate data.trace 0

功能

使用data.parv作为参数文件,data.trace做为tarce文件的输入,来模拟获得性能输出到data.out

 

Example 2

命令

disksim parms.1B stdout ascii t.Jan6 0 "disk1 .. disk16" "Segment size (inblks)" 64 "disk*" "Scheduler:Scheduling policy" 4

功能

parms.1B文件中读取数据,输出到标准输出端,读取的ascii trace文件为t.Jan6,当前没有开启综合产生器。参数替换如下:将disk1~disk16Segment Size(inblks)替换成64,所有disk*Scheduler:Scheduling policy(调度算法参数)替换成4

 

阅读(13951) | 评论(1) | 转发(2) |
给主人留下些什么吧!~~

xiaoyue262015-03-23 21:40:48

人工打Path那段不理解!楼主能解释一下吗?末尾居然是一个'{' ,没有‘}’?