一名默默挣扎在研发前线的女程序猿
分类: LINUX
2013-06-17 11:56:12
disksim是一个高效、准确、高度可配置的磁盘系统模拟器,用以支持对各种存储体系的方方面面的性能的研究,它由c编写且开源。它具有多种模块,配置多样,已在许多存储系统效率及性能的研究中应用,被证明能很很真实的模拟存储系统的工作情况。
disksim能够模拟并且报告与存储子系统相关的性能相关项,其仅能够对磁盘子系统的性能相关项进行建模,而不能存储与恢复每一个请求的真实数据。
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节 |
command |
|
component |
需要重写参数的组件名称。一般为磁盘名称,若有多个磁盘disk0~disk5,有以下两种书写方式:disk[0~5] or disk*(其中,*表示0或多个数字字符) |
parameter |
表示要被重写的参数标示符(在parameter file中使用的变量名)。若要引用子组件的参数,例如scheduler的参数,可写成:Schduler:parameter |
new value |
指定给参数的新值 |
说明 |
参数重写在参数文件读取完毕之后进行,但是在内部配置开始之前。任何在parameter 文件中定义的参数都可以使用命令行进行重写。 |
参数文件可以为各种存储子系统建模。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) 拓扑规范
其中,每个参数文件必须包含Global和Stats块。然后再定义一些bus(总线)、controller(控制器)以及一个(iodriver)输入输出驱动,然后定义或引入一些存储设备的描述,之后将其实例化,最后以一种拓扑规范定义这些组件之间的联系。磁盘阵列以logorg block来描述,必须在parfile中定义至少一个logorg block;设备的轮转同步可选地在syncet block中描述;调整trace中的时间规模和和映射请求可在iosim block中描述。若使用synthetic trace generater则必须包含Proc和Synthio块。
? 前三个总量
格式 |
|
context |
静态分析的上下文 |
statname |
statdefs文件的索引名称 |
type |
集合类型,average, std.dev, maximun |
value |
具体的值 |
? 之后的部分由输入样式决定。
disksim支持的trace格式有默认格式(ASCII)、验证格式(validate)、原始格式(RAW)。默认格式为普通的ascii流或者文件,每一行包括五个参数的值(以空格隔开)以描述一个磁盘请求。这5个参数为:
1) 请求到达时间(Float型,表示从模拟开始0.0到请求发生的时间,必需按时间顺序);
2) 设备号码(int 型);
3) block号(int型,表示请求的设备地址,其值为逻辑设备的可访问单元);
4) 请求大小(int型,请求的大小,单位为blocks);
5) 请求选项(十进制int型,每一位是0或1表示一个选项是否开启,每一位的定义见disksim_global.h)
模型可以配置一定范围的synthetic workloads, 均与磁盘位置访问和请求到达时间相关。其中,每一个合成器以一个处于系统态的进程,在一定的“思考时间”后发出io请求,然后等待io请求完成。
【说明】 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. 应用SSD的patch
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
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~disk16的Segment Size(inblks)替换成64,所有disk*的Scheduler:Scheduling policy(调度算法参数)替换成4 |