build: Add rpm target
[openafs.git] / tests / rpctestlib / rpc_test_procs.c
1 /*
2  * Copyright (c) 2010, Linux Box Corporation.
3  * All Rights Reserved.
4  *
5  * Portions Copyright (c) 2007, Hartmut Reuter,
6  * RZG, Max-Planck-Institut f. Plasmaphysik.
7  * All Rights Reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  *   1. Redistributions of source code must retain the above copyright
13  *      notice, this list of conditions and the following disclaimer.
14  *   2. Redistributions in binary form must reproduce the above copyright
15  *      notice, this list of conditions and the following disclaimer in
16  *      the documentation and/or other materials provided with the
17  *      distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <afsconfig.h>
32 #include <afs/param.h>
33
34 #include <roken.h>
35
36 #include <afs/stds.h>
37
38 #include "rpc_test_procs.h"
39
40 #ifdef AFS_NT40_ENV
41 #include <windows.h>
42 #include <WINNT/afsevent.h>
43 #else
44 #include <sys/file.h>
45 #include <afs/venus.h>
46 #include <sys/time.h>
47 #endif
48 #include <afs/afsint.h>
49 #define FSINT_COMMON_XG 1
50 #include <afs/vice.h>
51 #include <afs/cmd.h>
52 #include <afs/auth.h>
53 #include <afs/cellconfig.h>
54
55 #include <afs/com_err.h>
56 #ifdef HAVE_DIRECT_H
57 #include <direct.h>
58 #endif
59 #include <afs/errors.h>
60 #include <afs/sys_prototypes.h>
61 #include <rx/rx_prototypes.h>
62 #ifdef AFS_PTHREAD_ENV
63 #include <assert.h>
64 #endif
65
66 extern const char *prog;
67 const int ctx_key = 1;
68
69 #if 1
70 #define RPC_TEST_GLOBAL_RX_INIT 1
71 #else
72 #undef RPC_TEST_GLOBAL_RX_INIT
73 #endif
74
75 const afs_uint32 fs_port = 7000;
76
77 typedef struct rpc_test_pkg_params {
78     pthread_mutex_t mtx;
79     pthread_mutexattr_t mtx_attrs;
80     afs_uint32 cb_next_port;
81     afs_uint32 next_cno;
82 } rpc_test_pkg_params;
83 static rpc_test_pkg_params rpc_test_params;
84
85 afs_int32 rpc_test_PkgInit(void)
86 {
87     afs_int32 code = 0;
88     static afs_uint32 rpc_test_initialized = 0; /* once */
89
90     if (!rpc_test_initialized) {
91         rpc_test_initialized = 1;
92     } else {
93         printf("%s: rpc_test_PkgInit: package already initialized\n", prog);
94         exit(1);
95     }
96
97 #ifndef AFS_NT40_ENV
98     code = pthread_mutexattr_init(&rpc_test_params.mtx_attrs);
99     if (code) {
100         printf("%s: rpc_test_PkgInit: pthread_mutexattr_init failed\n", prog);
101         exit(1);
102     }
103     code = pthread_mutex_init(&rpc_test_params.mtx, &rpc_test_params.mtx_attrs);
104     if (code) {
105         printf("%s: rpc_test_PkgInit: pthread_mutex_init failed\n", prog);
106         exit(1);
107     }
108 #endif
109
110     /* start connection sequence */
111     rpc_test_params.next_cno = 1;
112
113     /* set the starting port in sequence */
114     rpc_test_params.cb_next_port = 7105;
115
116 #if defined(RPC_TEST_GLOBAL_RX_INIT)
117     rx_Init(0);
118 #endif
119
120     return (code);
121
122 }        /* rpc_test_PkgInit */
123
124 static void *
125 init_callback_service_lwp(void *arg)
126 {
127     struct rx_securityClass *sc;
128     struct rx_service *svc;
129
130     rpc_test_request_ctx *ctx = (rpc_test_request_ctx *) arg;
131
132     printf("%s: init_callback_service_lwp: listen_addr: %s "
133            "(%d) cb_port: %d\n",
134            prog, ctx->cb_listen_addr_s, ctx->cb_listen_addr.addr_in[0],
135            ctx->cb_port);
136
137     sc = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
138     if (!sc) {
139         fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback "
140                 "service\n");
141         exit(1);
142     }
143
144 #if defined(RPC_TEST_GLOBAL_RX_INIT)
145     svc = rx_NewServiceHost(htonl(INADDR_ANY), htons(ctx->cb_port), 1,
146                             ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
147 #else
148     svc = rx_NewService(0, 1, ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
149 #endif
150     /* stash context */
151     rx_SetServiceSpecific(svc, ctx_key, ctx);
152
153     if (!svc) {
154         fprintf(stderr,"rx_NewServiceHost failed for callback service\n");
155         exit(1);
156     }
157
158     /* XXX stash service so we can hijack its rx_socket when inititiating
159      * RPC calls */
160     ctx->svc = svc;
161
162     /* release pkg mutex before entering rx processing loop */
163     pthread_mutex_unlock(&rpc_test_params.mtx);
164
165     rx_StartServer(1);
166
167     printf("%s: init_callback_service_lwp: finished", prog);
168
169     return (NULL);
170
171 }        /* callback_service_lwp */
172
173 afs_int32 init_callback_service(rpc_test_request_ctx *ctx)
174 {
175     pthread_t tid;
176     pthread_attr_t tattr;
177     afs_int32 code = 0;
178
179     afs_uuid_create(&(ctx->cb_listen_addr.uuid));
180
181 #if !defined(RPC_TEST_GLOBAL_RX_INIT)
182     code = rx_Init((int) htons(ctx->cb_port));
183 #endif /* RPC_TEST_GLOBAL_RX_INIT */
184
185     assert(pthread_attr_init(&tattr) == 0);
186     assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
187     assert(pthread_create(&tid, &tattr, init_callback_service_lwp, ctx) == 0);
188
189     return (code);
190
191 }        /* init_callback_service */
192
193 afs_int32 init_fs_channel(rpc_test_request_ctx **octx, char *cb_if,
194                           char *listen_addr_s, char *prefix, char *fs_addr_s,
195                           afs_uint32 flags)
196 {
197     rpc_test_request_ctx *ctx;
198     afs_int32 code = 0;
199 #ifdef AFS_NT40_ENV
200     afs_int32 sslen = sizeof(struct sockaddr);
201 #endif
202
203     ctx = *octx = (rpc_test_request_ctx *) malloc(sizeof(rpc_test_request_ctx));
204     memset(ctx, 0, sizeof(rpc_test_request_ctx));
205
206     /* initialize a local mutex */
207     code = pthread_mutex_init(&ctx->mtx, &rpc_test_params.mtx_attrs);
208
209     /* lock package before rx setup--which has global deps, atm */
210     pthread_mutex_lock(&rpc_test_params.mtx);
211
212     ctx->cno = rpc_test_params.next_cno++;
213     ctx->flags = flags;
214
215     /* afscbint (server) */
216     sprintf(ctx->cb_svc_name, "cb_%d", ctx->cno);
217     sprintf(ctx->cb_if_s, "%s", cb_if);
218     sprintf(ctx->cb_listen_addr_s, "%s", listen_addr_s);
219     sprintf(ctx->cb_prefix_s, "%s", prefix);
220     sprintf(ctx->fs_addr_s, "%s", fs_addr_s);
221
222 #if defined(RPC_TEST_ADD_ADDRESSES)
223 #if defined(AFS_LINUX26_ENV)
224     sprintf(cmd, "ip addr add %s/%s dev %s label %s", listen_addr_s, prefix,
225             cb_if, cb_if);
226     code = system(cmd);
227 #endif
228 #endif /* RPC_TEST_ADD_ADDRESSES */
229
230     /* lock this */
231     pthread_mutex_lock(&ctx->mtx);
232
233     /* set up rx */
234     ctx->cb_port = rpc_test_params.cb_next_port++;
235     ctx->cb_listen_addr.numberOfInterfaces = 1;
236
237 #ifdef AFS_NT40_ENV
238     code = WSAStringToAddressA(listen_addr_s, AF_INET, NULL,
239               (struct sockaddr*) &(ctx->cb_listen_addr), &sslen);
240 #else
241     code = inet_pton(AF_INET, listen_addr_s,
242                      (void*) &(ctx->cb_listen_addr.addr_in[0]));
243 #endif
244
245     code = init_callback_service(ctx /* LOCKED, && rpc_test_params->mtx LOCKED */);
246
247     /* fsint (client) */
248
249 #ifdef AFS_NT40_ENV
250     code = WSAStringToAddressA(fs_addr_s, AF_INET, NULL,
251               (struct sockaddr*) &(ctx->fs_addr.addr_in[0]), &sslen);
252 #else
253     code = inet_pton(AF_INET, fs_addr_s, (void*) &(ctx->fs_addr.addr_in[0]));
254 #endif
255     ctx->sc = rxnull_NewClientSecurityObject();
256     ctx->sc_index = RX_SECIDX_NULL;
257     ctx->conn = rx_NewConnection(ctx->fs_addr.addr_in[0], (int) htons(fs_port),
258                                  1, ctx->sc, ctx->sc_index);
259
260     /* unlock this */
261     pthread_mutex_unlock(&ctx->mtx);
262
263     return (code);
264
265 }        /* init_fs_channel */
266
267 /* XXX use the pkg lock to protect the state of rx_socket for
268  * the duration of the call, switching it out for the stashed
269  * rx_socket created by rx_NewService for this channel */
270 #define RXCALL_WITH_SOCK(code, ctx, call) \
271     do { \
272         osi_socket prev_rx_socket; \
273         pthread_mutex_lock(&rpc_test_params.mtx); \
274         prev_rx_socket = rx_socket; \
275         rx_socket = ctx->svc->socket; \
276         code = call; \
277         rx_socket = prev_rx_socket; \
278         pthread_mutex_unlock(&rpc_test_params.mtx); \
279 } while(0);
280
281 afs_int32
282 rpc_test_afs_fetch_status(rpc_test_request_ctx *ctx, AFSFid *fid,
283                               AFSFetchStatus *outstatus)
284 {
285     struct AFSVolSync tsync;
286     struct AFSCallBack tcb;
287     afs_int32 code = 0;
288
289     RXCALL_WITH_SOCK(code, ctx,
290        (RXAFS_FetchStatus(ctx->conn, fid, outstatus, &tcb, &tsync)));
291
292     return (code);
293
294 }        /* rpc_test_afs_fetch_status */
295
296 afs_int32
297 rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid,
298                     AFSStoreStatus *instatus, AFSFetchStatus *outstatus)
299 {
300     struct AFSVolSync tsync;
301     afs_int32 code = 0;
302
303     RXCALL_WITH_SOCK(code, ctx,
304        (RXAFS_StoreStatus(ctx->conn, fid, instatus, outstatus, &tsync)));
305
306     return (code);
307
308 }        /* rpc_test_afs_fetch_status */
309
310 #if defined(AFS_BYTE_RANGE_FLOCKS)
311 afs_int32 rpc_test_afs_set_byterangelock(rpc_test_request_ctx *ctx,
312     AFSByteRangeLock * lock)
313 {
314     struct rx_call *tcall;
315     afs_int32 code = 0;
316
317     RXCALL_WITH_SOCK(code, ctx,
318        (RXAFS_SetByteRangeLock(ctx->conn, lock)));
319
320     return (code);
321
322 }        /* rpc_test_afs_set_byterangelock */
323
324 afs_int32 rpc_test_afs_release_byterangelock(rpc_test_request_ctx *ctx,
325     AFSByteRangeLock * lock)
326 {
327     struct rx_call *tcall;
328     afs_int32 code = 0;
329
330     RXCALL_WITH_SOCK(code, ctx,
331        (RXAFS_ReleaseByteRangeLock(ctx->conn, lock)));
332
333     return (code);
334
335 }        /* rpc_test_afs_release_byterangelock */
336
337 afs_int32 rpc_test_afs_upgrade_byterangelock(rpc_test_request_ctx *ctx,
338     AFSByteRangeLock * lock)
339 {
340     afs_int32 code = 0;
341
342     /* TODO:  implement */
343
344     return (code);
345
346 }        /* rpc_test_afs_upgrade_byterangelock */
347
348 afs_int32 rpc_test_afs_downgrade_byterangelock(rpc_test_request_ctx *ctx,
349     AFSByteRangeLock * Lock)
350 {
351     afs_int32 code = 0;
352
353     /* TODO:  implement */
354
355     return (code);
356
357 }        /* rpc_test_afs_downgrade_byterangelock */
358 #endif /* AFS_BYTE_RANGE_FLOCKS */
359
360 afs_int32
361 destroy_fs_channel(rpc_test_request_ctx *ctx)
362 {
363     afs_int32 code = 0;
364 #if defined(RPC_TEST_ADD_ADDRESSES)
365 #if defined(AFS_LINUX26_ENV)
366     sprintf(cmd, "ip addr del %s/%s dev %s label %s", ctx->cb_listen_addr_s,
367             ctx->cb_prefix_s, ctx->cb_if_s, ctx->cb_if_s);
368     code = system(cmd);
369 #endif
370 #endif /* RPC_TEST_ADD_ADDRESSES */
371     assert(ctx);
372     free(ctx);
373     return (code);
374
375 }        /* destroy_fs_channel */
376
377 void
378 rpc_test_PkgShutdown(void)
379 {
380 }        /* rpc_test_PkgShutdown */