Project

General

Profile

Bug #5509 » nfsauth_perf.c

Marcel Telka, 2015-01-07 04:30 PM

 
1
#include <sys/types.h>
2
#include <unistd.h>
3
#include <stdio.h>
4
#include <stdio_ext.h>
5
#include <stdlib.h>
6

    
7
#include <rpc/rpc.h>
8
#include <nfs/nfs.h>
9

    
10
#include <rpc/xdr.h>
11

    
12
#include <rpcsvc/mount.h>
13

    
14
static bool_t
15
xdr_GETATTR3args(XDR *xdrs, GETATTR3args *objp)
16
{
17
	char *d = objp->object.fh3_u.data;
18
	return xdr_bytes(xdrs, &d, &objp->object.fh3_length, NFS3_FHSIZE);
19
}
20

    
21
static const char *
22
test_opts(void)
23
{
24
	return NULL;
25
}
26

    
27
static int
28
init(int argc, char **argv)
29
{
30
	struct rlimit rl;
31

    
32
	if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
33
		printf("getrlimit failed\n");
34
	} else {
35
		rl.rlim_cur = rl.rlim_max;
36
		if (setrlimit(RLIMIT_NOFILE, &rl) != 0)
37
			printf("setrlimit failed\n");
38
	}
39
	(void) enable_extended_FILE_stdio(-1, -1);
40

    
41
	if (argc == 3)
42
		return 0;
43

    
44
	printf("Too much parameters.\n");
45

    
46
	return -1;
47
}
48

    
49
struct test_data {
50
	CLIENT *mnt;
51
	CLIENT *nfs;
52
	nfs_fh3 fh3;
53
};
54

    
55
const char *path = "/tmp";
56
const char *server = "localhost";
57
const char *me = "me";
58

    
59
static int
60
test_init(int id, void **d)
61
{
62
	struct test_data *td;
63

    
64
	enum clnt_stat s;
65
	mountres3 res3;
66

    
67
	struct timeval timeout = {25, 0};
68

    
69
	td = calloc(1, sizeof *td);
70
	if (td == NULL) {
71
		printf("malloc() failed\n");
72
		return -1;
73
	}
74

    
75
	/* MOUNT */
76

    
77
	td->mnt = clnt_create(server, MOUNTPROG, MOUNTVERS3, "circuit_v");
78
	if (td->mnt == NULL) {
79
		clnt_pcreateerror("clnt_create() for MOUNT failed");
80

    
81
		goto fail;
82
	}
83

    
84
	(void) memset(&res3, '\0', sizeof res3);
85

    
86
	s = clnt_call(td->mnt, MOUNTPROC_MNT, xdr_dirpath, (caddr_t)&path,
87
	    xdr_mountres3, (caddr_t)&res3, timeout);
88

    
89
	if (s != RPC_SUCCESS) {
90
		printf("clnt_call() for MNT failed\n");
91

    
92
		goto fail;
93
	}
94

    
95
	if (res3.fhs_status != MNT_OK) {
96
		printf("MNT failed\n");
97

    
98
		goto fail;
99
	}
100

    
101
	td->fh3.fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
102
	memcpy(td->fh3.fh3_u.data,
103
	    res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
104
	    td->fh3.fh3_length);
105

    
106
	if (!clnt_freeres(td->mnt, xdr_mountres3, (caddr_t)&res3)) {
107
		printf("clnt_freeres failed\n");
108

    
109
		/* The clnt_freeres() failure is not fatal */
110
	}
111

    
112
	/* NFS */
113

    
114
	td->nfs = clnt_create(server, NFS3_PROGRAM, NFS_V3, "circuit_v");
115
	if (td->nfs == NULL) {
116
		clnt_pcreateerror("clnt_create() for NFS failed");
117

    
118
		goto fail;
119
	}
120

    
121
	td->nfs->cl_auth = authsys_create(me, id, id, 0, NULL);
122
	if (td->nfs->cl_auth == NULL) {
123
		printf("authsys_create failed\n");
124

    
125
		goto fail;
126
	}
127

    
128
	*(struct test_data **)d = td;
129

    
130
	return 0;
131

    
132
fail:
133
	if (td->nfs != NULL)
134
		clnt_destroy(td->nfs);
135

    
136
	if (td->mnt != NULL) {
137
		s = clnt_call(td->mnt, MOUNTPROC_UMNT, xdr_dirpath,
138
		    (caddr_t)&path, xdr_void, NULL, timeout);
139
		if (s != RPC_SUCCESS) {
140
			printf("clnt_call() for UMNT failed\n");
141
		}
142

    
143
		clnt_destroy(td->mnt);
144
	}
145

    
146
	free(td);
147

    
148
	return -1;
149
}
150

    
151
static int
152
test(void *d)
153
{
154
	struct test_data *td = (struct test_data *)d;
155

    
156
	enum clnt_stat s;
157
	struct timeval timeout = {25, 0};
158

    
159
	s = clnt_call(td->nfs, NFSPROC3_GETATTR, xdr_GETATTR3args,
160
	    (caddr_t)&td->fh3, xdr_void, NULL, timeout);
161

    
162
	if (s != RPC_SUCCESS)
163
		return -1;
164

    
165
	return 0;
166
}
167

    
168
static void
169
test_fini(void *d)
170
{
171
	struct test_data *td = (struct test_data *)d;
172
	struct timeval timeout = {25, 0};
173
	enum clnt_stat s;
174

    
175
	auth_destroy(td->nfs->cl_auth);
176
	clnt_destroy(td->nfs);
177

    
178
	s = clnt_call(td->mnt, MOUNTPROC_UMNT, xdr_dirpath, (caddr_t)&path,
179
	    xdr_void, NULL, timeout);
180
	if (s != RPC_SUCCESS) {
181
		printf("clnt_call() for UMNT failed\n");
182
	}
183

    
184
	clnt_destroy(td->mnt);
185
}
186

    
187

    
188

    
189

    
190

    
191

    
192

    
193

    
194

    
195
#include <stdio.h>
196
#include <unistd.h>
197
#include <stdlib.h>
198

    
199
#include <thread.h>
200
#include <atomic.h>
201
#include <synch.h>
202

    
203
volatile int run = 0;
204
volatile int stop = 0;
205
volatile uint_t success = 0;
206
volatile uint_t fail = 0;
207
volatile uint_t init_fail = 0;
208
volatile int t = 0;
209
volatile int lim;
210

    
211
mutex_t lock = DEFAULTMUTEX;
212
cond_t cv = DEFAULTCV;
213
cond_t start = DEFAULTCV;
214

    
215
struct thr_data {
216
	int id;
217
	int (*f)(void *);
218
};
219

    
220
static void
221
fnc(struct thr_data *td)
222
{
223
	void *d;
224
	uint_t lf = 0;
225
	uint_t ls = 0;
226

    
227
	int ir = test_init(td->id, &d);
228

    
229
	mutex_lock(&lock);
230
	t++;
231
	if (t == lim)
232
		cond_signal(&cv);
233
	while (run == 0)
234
		cond_wait(&start, &lock);
235
	mutex_unlock(&lock);
236

    
237
	if (ir == 0) {
238
		while (!stop) {
239
			if (td->f(d)) {
240
				atomic_inc_uint(&fail);
241
				lf++;
242
			} else {
243
				atomic_inc_uint(&success);
244
				ls++;
245
			}
246
		}
247

    
248
		test_fini(d);
249
	} else {
250
		atomic_inc_uint(&init_fail);
251
	}
252

    
253
	printf("thread %d: %d/%d\n", td->id, ls, lf);
254

    
255
	mutex_lock(&lock);
256
	t--;
257
	if (t == 0)
258
		cond_signal(&cv);
259
	mutex_unlock(&lock);
260

    
261
	free(td);
262
}
263

    
264
int
265
main(int argc, char **argv)
266
{
267
	int i;
268

    
269
	if (argc < 3) {
270
		const char *to = test_opts();
271

    
272
		printf("Parameter missing.\n");
273
		printf("Usage: %s NTHREADS SECS%s\n", argv[0],
274
		    to != NULL ? to : "");
275

    
276
		return -1;
277
	}
278

    
279
	lim = atoi(argv[1]);
280
	for (i = 0; i < lim; i++) {
281
		struct thr_data *td = malloc(sizeof *td);
282

    
283
		if (td == NULL) {
284
			printf("malloc() failed\n");
285

    
286
			return -1;
287
		}
288

    
289
		td->id = i;
290
		td->f = test;
291

    
292
		if (thr_create(NULL, 32 * 1024, (void *(*)(void *))fnc, td,
293
		    THR_DETACHED, NULL) != 0) {
294
			printf("Thread creation failed. Exiting.\n");
295

    
296
			free(td);
297

    
298
			return -1;
299
		}
300
	}
301

    
302
	if (init(argc, argv)) {
303
		printf("Test initialization failed.\n");
304
		return -1;
305
	}
306

    
307
	mutex_lock(&lock);
308
	while (t < lim)
309
		cond_wait(&cv, &lock);
310
	run = 1;
311
	cond_broadcast(&start);
312
	mutex_unlock(&lock);
313

    
314
	sleep(atoi(argv[2]));
315
	stop = 1;
316

    
317
	mutex_lock(&lock);
318
	while (t > 0)
319
		cond_wait(&cv, &lock);
320
	mutex_unlock(&lock);
321

    
322
	printf("%d/%d/%d\n", success, fail, init_fail);
323

    
324
	return 0;
325
}
(3-3/4)