Revision ee638823 xseg/peers/user/bench-xseg.c

b/xseg/peers/user/bench-xseg.c
5 5
 * without modification, are permitted provided that the following
6 6
 * conditions are met:
7 7
 *
8
*   1. Redistributions of source code must retain the above
9
*      copyright notice, this list of conditions and the following
10
*      disclaimer.
11
*   2. Redistributions in binary form must reproduce the above
12
*      copyright notice, this list of conditions and the following
13
*      disclaimer in the documentation and/or other materials
14
*      provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
* POSSIBILITY OF SUCH DAMAGE.
28
*
29
* The views and conclusions contained in the software and
30
* documentation are those of the authors and should not be
31
* interpreted as representing official policies, either expressed
32
* or implied, of GRNET S.A.
33
*/
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *   2. Redistributions in binary form must reproduce the above
12
 *      copyright notice, this list of conditions and the following
13
 *      disclaimer in the documentation and/or other materials
14
 *      provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * The views and conclusions contained in the software and
30
 * documentation are those of the authors and should not be
31
 * interpreted as representing official policies, either expressed
32
 * or implied, of GRNET S.A.
33
 */
34 34

  
35 35
#define _GNU_SOURCE
36 36
#include <stdio.h>
......
48 48

  
49 49
void custom_peer_usage()
50 50
{
51
fprintf(stderr, "Custom peer options: \n"
52
	"  --------------------------------------------\n"
53
	"    -op       | None    | XSEG operation [read|write|info|delete]\n"
54
	"    --pattern | None    | I/O pattern [sync|rand]\n"
55
	"    -ts       | None    | Total I/O size\n"
56
	"    -os       | 4M      | Object size\n"
57
	"    -bs       | 4k      | Block size\n"
58
	"    -dp       | None    | Destination port\n"
59
	"    --iodepth | 1       | Number of in-flight I/O requests\n"
60
	"\n");
51
	fprintf(stderr, "Custom peer options: \n"
52
			"  --------------------------------------------\n"
53
			"    -op       | None    | XSEG operation [read|write|info|delete]\n"
54
			"    --pattern | None    | I/O pattern [sync|rand]\n"
55
			"    -ts       | None    | Total I/O size\n"
56
			"    -os       | 4M      | Object size\n"
57
			"    -bs       | 4k      | Block size\n"
58
			"    -dp       | None    | Destination port\n"
59
			"    --iodepth | 1       | Number of in-flight I/O requests\n"
60
			"    --verify  | no      | Verify written requests [no|meta|hash]"
61
			"\n");
61 62
}
62 63

  
63 64
int custom_peer_init(struct peerd *peer, int argc, char *argv[])
64 65
{
65
struct bench *prefs;
66
char total_size[MAX_ARG_LEN + 1];
67
char object_size[MAX_ARG_LEN + 1];
68
char block_size[MAX_ARG_LEN + 1];
69
char op[MAX_ARG_LEN + 1];
70
char pattern[MAX_ARG_LEN + 1];
71
struct xseg *xseg = peer->xseg;
72
unsigned int xseg_page_size = 1 << xseg->config.page_shift;
73
long dst_port = -1;
74
int r;
75

  
76
op[0] = 0;
77
pattern[0] = 0;
78
total_size[0] = 0;
79
block_size[0] = 0;
80
object_size[0] = 0;
66
	struct bench *prefs;
67
	char total_size[MAX_ARG_LEN + 1];
68
	char object_size[MAX_ARG_LEN + 1];
69
	char block_size[MAX_ARG_LEN + 1];
70
	char op[MAX_ARG_LEN + 1];
71
	char pattern[MAX_ARG_LEN + 1];
72
	struct xseg *xseg = peer->xseg;
73
	unsigned int xseg_page_size = 1 << xseg->config.page_shift;
74
	long dst_port = -1;
75
	int r;
76

  
77
	op[0] = 0;
78
	pattern[0] = 0;
79
	total_size[0] = 0;
80
	block_size[0] = 0;
81
	object_size[0] = 0;
81 82

  
82 83
#ifdef MT
83
for (i = 0; i < nr_threads; i++) {
84
	prefs = peer->thread[i]->priv;
84
	for (i = 0; i < nr_threads; i++) {
85
		prefs = peer->thread[i]->priv;
86
		prefs = malloc(sizeof(struct bench));
87
		if (!prefs) {
88
			perror("malloc");
89
			return -1;
90
		}
91
	}
92
#endif
85 93
	prefs = malloc(sizeof(struct bench));
86 94
	if (!prefs) {
87 95
		perror("malloc");
88 96
		return -1;
89 97
	}
90
}
91
#endif
92
prefs = malloc(sizeof(struct bench));
93
if (!prefs) {
94
	perror("malloc");
95
	return -1;
96
}
97
prefs->flags = 0;
98

  
99
//Begin reading the benchmark-specific arguments
100
BEGIN_READ_ARGS(argc, argv);
101
READ_ARG_STRING("-op", op, MAX_ARG_LEN);
102
READ_ARG_STRING("--pattern", pattern, MAX_ARG_LEN);
103
READ_ARG_STRING("-ts", total_size, MAX_ARG_LEN);
104
READ_ARG_STRING("-os", object_size, MAX_ARG_LEN);
105
READ_ARG_STRING("-bs", block_size, MAX_ARG_LEN);
106
READ_ARG_ULONG("--iodepth", prefs->iodepth);
107
READ_ARG_ULONG("-dp", dst_port);
108
END_READ_ARGS();
109

  
110
/*****************************\
111
 * Check I/O type parameters *
112
\*****************************/
113

  
114
if (!op[0]) {
115
	XSEGLOG2(&lc, E, "xseg operation needs to be supplied\n");
116
	goto arg_fail;
117
}
118
r = read_op(op);
119
if (r < 0) {
120
	XSEGLOG2(&lc, E, "Invalid syntax: -op %s\n", op);
121
	goto arg_fail;
122
}
123
prefs->op = r;
98
	prefs->flags = 0;
99

  
100
	//Begin reading the benchmark-specific arguments
101
	BEGIN_READ_ARGS(argc, argv);
102
	READ_ARG_STRING("-op", op, MAX_ARG_LEN);
103
	READ_ARG_STRING("--pattern", pattern, MAX_ARG_LEN);
104
	READ_ARG_STRING("-ts", total_size, MAX_ARG_LEN);
105
	READ_ARG_STRING("-os", object_size, MAX_ARG_LEN);
106
	READ_ARG_STRING("-bs", block_size, MAX_ARG_LEN);
107
	READ_ARG_ULONG("--iodepth", prefs->iodepth);
108
	READ_ARG_ULONG("-dp", dst_port);
109
	END_READ_ARGS();
110

  
111
	/*****************************\
112
	 * Check I/O type parameters *
113
	 \*****************************/
114

  
115
	if (!op[0]) {
116
		XSEGLOG2(&lc, E, "xseg operation needs to be supplied\n");
117
		goto arg_fail;
118
	}
119
	r = read_op(op);
120
	if (r < 0) {
121
		XSEGLOG2(&lc, E, "Invalid syntax: -op %s\n", op);
122
		goto arg_fail;
123
	}
124
	prefs->op = r;
124 125

  
125
if (!pattern[0]) {
126
	XSEGLOG2(&lc, E, "I/O pattern needs to be supplied\n");
127
	goto arg_fail;
128
}
129
r = read_pattern(pattern);
130
if (r < 0) {
131
	XSEGLOG2(&lc, E, "Invalid syntax: --pattern %s\n", pattern);
132
	goto arg_fail;
133
}
134
prefs->flags |= (uint8_t)r;
135

  
136
/*************************
137
 * Check size parameters *
138
 *************************/
139

  
140
//Block size (bs): Defaults to 4K.
141
//It must be a number followed by one of these characters: [k|K|m|M|g|G].
142
//If not, it will be considered as size in bytes.
143
//Must be integer multiple of segment's page size (typically 4k).
144
if (!block_size[0])
145
	strcpy(block_size,"4k");
146

  
147
if (!prefs->iodepth)
148
	prefs->iodepth = 1;
149

  
150
prefs->bs = str2num(block_size);
151
if (!prefs->bs) {
152
	XSEGLOG2(&lc, E, "Invalid syntax: -bs %s\n", block_size);
153
	goto arg_fail;
154
} else if (prefs->bs % xseg_page_size) {
155
	XSEGLOG2(&lc, E, "Misaligned block size: %s\n", block_size);
156
	goto arg_fail;
157
}
126
	if (!pattern[0]) {
127
		XSEGLOG2(&lc, E, "I/O pattern needs to be supplied\n");
128
		goto arg_fail;
129
	}
130
	r = read_pattern(pattern);
131
	if (r < 0) {
132
		XSEGLOG2(&lc, E, "Invalid syntax: --pattern %s\n", pattern);
133
		goto arg_fail;
134
	}
135
	prefs->flags |= (uint8_t)r;
136

  
137
	/*************************
138
	 * Check size parameters *
139
	 *************************/
140

  
141
	//Block size (bs): Defaults to 4K.
142
	//It must be a number followed by one of these characters: [k|K|m|M|g|G].
143
	//If not, it will be considered as size in bytes.
144
	//Must be integer multiple of segment's page size (typically 4k).
145
	if (!block_size[0])
146
		strcpy(block_size,"4k");
147

  
148
	if (!prefs->iodepth)
149
		prefs->iodepth = 1;
150

  
151
	prefs->bs = str2num(block_size);
152
	if (!prefs->bs) {
153
		XSEGLOG2(&lc, E, "Invalid syntax: -bs %s\n", block_size);
154
		goto arg_fail;
155
	} else if (prefs->bs % xseg_page_size) {
156
		XSEGLOG2(&lc, E, "Misaligned block size: %s\n", block_size);
157
		goto arg_fail;
158
	}
158 159

  
159
//Total I/O size (ts): Must be supplied by user.
160
//Must have the same format as "total size"
161
//Must be integer multiple of "block size"
162
if (!total_size[0]) {
163
	XSEGLOG2(&lc, E, "Total I/O size needs to be supplied\n");
164
	goto arg_fail;
165
}
160
	//Total I/O size (ts): Must be supplied by user.
161
	//Must have the same format as "total size"
162
	//Must be integer multiple of "block size"
163
	if (!total_size[0]) {
164
		XSEGLOG2(&lc, E, "Total I/O size needs to be supplied\n");
165
		goto arg_fail;
166
	}
166 167

  
167
prefs->ts = str2num(total_size);
168
if (!prefs->ts) {
169
	XSEGLOG2(&lc, E, "Invalid syntax: -ts %s\n", total_size);
170
	goto arg_fail;
171
} else if (prefs->ts % prefs->bs) {
172
	XSEGLOG2(&lc, E, "Misaligned total I/O size: %s\n", total_size);
173
	goto arg_fail;
174
} else if (prefs->ts > xseg->segment_size) {
175
	XSEGLOG2(&lc, E, "Total I/O size exceeds segment size\n", total_size);
176
	goto arg_fail;
177
}
168
	prefs->ts = str2num(total_size);
169
	if (!prefs->ts) {
170
		XSEGLOG2(&lc, E, "Invalid syntax: -ts %s\n", total_size);
171
		goto arg_fail;
172
	} else if (prefs->ts % prefs->bs) {
173
		XSEGLOG2(&lc, E, "Misaligned total I/O size: %s\n", total_size);
174
		goto arg_fail;
175
	} else if (prefs->ts > xseg->segment_size) {
176
		XSEGLOG2(&lc, E, "Total I/O size exceeds segment size\n", total_size);
177
		goto arg_fail;
178
	}
178 179

  
179
//Object size (os): Defaults to 4M.
180
//Must have the same format as "total size"
181
//Must be integer multiple of "block size"
182
if (!object_size[0])
183
	strcpy(object_size,"4M");
184

  
185
prefs->os = str2num(object_size);
186
if (!prefs->os) {
187
	XSEGLOG2(&lc, E, "Invalid syntax: -os %s\n", object_size);
188
	goto arg_fail;
189
} else if (prefs->os % prefs->bs) {
190
	XSEGLOG2(&lc, E, "Misaligned object size: %s\n", object_size);
191
	goto arg_fail;
192
}
180
	//Object size (os): Defaults to 4M.
181
	//Must have the same format as "total size"
182
	//Must be integer multiple of "block size"
183
	if (!object_size[0])
184
		strcpy(object_size,"4M");
185

  
186
	prefs->os = str2num(object_size);
187
	if (!prefs->os) {
188
		XSEGLOG2(&lc, E, "Invalid syntax: -os %s\n", object_size);
189
		goto arg_fail;
190
	} else if (prefs->os % prefs->bs) {
191
		XSEGLOG2(&lc, E, "Misaligned object size: %s\n", object_size);
192
		goto arg_fail;
193
	}
193 194

  
194
/*************************
195
 * Check port parameters *
196
 *************************/
195
	/*************************
196
	 * Check port parameters *
197
	 *************************/
197 198

  
198
if (dst_port < 0){
199
	XSEGLOG2(&lc, E, "Destination port needs to be supplied\n");
200
	goto arg_fail;
201
}
199
	if (dst_port < 0){
200
		XSEGLOG2(&lc, E, "Destination port needs to be supplied\n");
201
		goto arg_fail;
202
	}
202 203

  
203
prefs->src_port = peer->portno_start; //TODO: allow user to change this
204
prefs->dst_port = (xport) dst_port;
204
	prefs->src_port = peer->portno_start; //TODO: allow user to change this
205
	prefs->dst_port = (xport) dst_port;
205 206

  
206
/*********************************
207
 * Create timers for all metrics *
208
 *********************************/
207
	/*********************************
208
	 * Create timers for all metrics *
209
	 *********************************/
209 210

  
210
if (init_timer(&prefs->total_tm, TM_SANE))
211
	goto tm_fail;
212
if (init_timer(&prefs->sub_tm, TM_MANIC))
213
	goto tm_fail;
214
if (init_timer(&prefs->get_tm, TM_PARANOID))
215
	goto tm_fail;
216
if (init_timer(&prefs->rec_tm, TM_ECCENTRIC))
217
	goto tm_fail;
211
	if (init_timer(&prefs->total_tm, TM_SANE))
212
		goto tm_fail;
213
	if (init_timer(&prefs->sub_tm, TM_MANIC))
214
		goto tm_fail;
215
	if (init_timer(&prefs->get_tm, TM_PARANOID))
216
		goto tm_fail;
217
	if (init_timer(&prefs->rec_tm, TM_ECCENTRIC))
218
		goto tm_fail;
218 219

  
219
/**************************
220
 * Customize struct peerd *
221
 **************************/
220
	/**************************
221
	 * Customize struct peerd *
222
	 **************************/
222 223

  
223
peer->peerd_loop = custom_peerd_loop;
224
peer->priv = (void *) prefs;
225
return 0;
224
	peer->peerd_loop = custom_peerd_loop;
225
	peer->priv = (void *) prefs;
226
	return 0;
226 227

  
227 228
arg_fail:
228
custom_peer_usage();
229
	custom_peer_usage();
229 230
tm_fail:
230
free(prefs->total_tm);
231
free(prefs->sub_tm);
232
free(prefs->get_tm);
233
free(prefs->rec_tm);
234
free(prefs);
235
return -1;
231
	free(prefs->total_tm);
232
	free(prefs->sub_tm);
233
	free(prefs->get_tm);
234
	free(prefs->rec_tm);
235
	free(prefs);
236
	return -1;
236 237
}
237 238

  
238 239

  
239 240
static int send_request(struct peerd *peer, struct bench *prefs)
240 241
{
241
struct xseg_request *req;
242
struct xseg *xseg = peer->xseg;
243
struct peer_req *pr;
244
xport srcport = prefs->src_port;
245
xport dstport = prefs->dst_port;
246
xport p;
242
	struct xseg_request *req;
243
	struct xseg *xseg = peer->xseg;
244
	struct peer_req *pr;
245
	xport srcport = prefs->src_port;
246
	xport dstport = prefs->dst_port;
247
	xport p;
247 248

  
248
int r;
249
uint64_t new;
250
uint64_t size = prefs->bs;
249
	int r;
250
	uint64_t new;
251
	uint64_t size = prefs->bs;
251 252

  
252 253
	//srcport and dstport must already be provided by the user.
253 254
	//returns struct xseg_request with basic initializations
......
265 266
	r = xseg_prep_request(xseg, req, TARGETLEN, size);
266 267
	if (r < 0) {
267 268
		XSEGLOG2(&lc, W, "Cannot prepare request! (%lu, %llu)\n",
268
			TARGETLEN, (unsigned long long)size);
269
				TARGETLEN, (unsigned long long)size);
269 270
		goto put_xseg_request;
270 271
	}
271 272

  
272 273
	/************PROPOSED************/
274
	//Determine what the next target/chunk will be, based on I/O pattern
273 275
	new = determine_next(prefs);
276
	//Create a target of this format: "bench-<obj_no>"
274 277
	create_target(prefs, req, new);
275 278

  
276 279
	if(prefs->op == X_WRITE || prefs->op == X_READ) {

Also available in: Unified diff