backport to buster
[hcoop/debian/openafs.git] / tests / rpctestlib / rpc_test_procs.c
CommitLineData
805e021f
CE
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
66extern const char *prog;
67const 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
75const afs_uint32 fs_port = 7000;
76
77typedef 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;
83static rpc_test_pkg_params rpc_test_params;
84
85afs_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
124static void *
125init_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
173afs_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#if 0
183 code = rx_InitHost(ctx->cb_listen_addr.addr_in[0],
184 (int) htons(ctx->cb_port));
185#else
186 code = rx_Init((int) htons(ctx->cb_port));
187#endif
188#endif /* RPC_TEST_GLOBAL_RX_INIT */
189
190 assert(pthread_attr_init(&tattr) == 0);
191 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
192 assert(pthread_create(&tid, &tattr, init_callback_service_lwp, ctx) == 0);
193
194 return (code);
195
196} /* init_callback_service */
197
198afs_int32 init_fs_channel(rpc_test_request_ctx **octx, char *cb_if,
199 char *listen_addr_s, char *prefix, char *fs_addr_s,
200 afs_uint32 flags)
201{
202 rpc_test_request_ctx *ctx;
203 afs_int32 code = 0;
204#ifdef AFS_NT40_ENV
205 afs_int32 sslen = sizeof(struct sockaddr);
206#endif
207
208 ctx = *octx = (rpc_test_request_ctx *) malloc(sizeof(rpc_test_request_ctx));
209 memset(ctx, 0, sizeof(rpc_test_request_ctx));
210
211 /* initialize a local mutex */
212 code = pthread_mutex_init(&ctx->mtx, &rpc_test_params.mtx_attrs);
213
214 /* lock package before rx setup--which has global deps, atm */
215 pthread_mutex_lock(&rpc_test_params.mtx);
216
217 ctx->cno = rpc_test_params.next_cno++;
218 ctx->flags = flags;
219
220 /* afscbint (server) */
221 sprintf(ctx->cb_svc_name, "cb_%d", ctx->cno);
222 sprintf(ctx->cb_if_s, "%s", cb_if);
223 sprintf(ctx->cb_listen_addr_s, "%s", listen_addr_s);
224 sprintf(ctx->cb_prefix_s, "%s", prefix);
225 sprintf(ctx->fs_addr_s, "%s", fs_addr_s);
226
227#if defined(RPC_TEST_ADD_ADDRESSES)
228#if defined(AFS_LINUX26_ENV)
229 sprintf(cmd, "ip addr add %s/%s dev %s label %s", listen_addr_s, prefix,
230 cb_if, cb_if);
231 code = system(cmd);
232#endif
233#endif /* RPC_TEST_ADD_ADDRESSES */
234
235 /* lock this */
236 pthread_mutex_lock(&ctx->mtx);
237
238 /* set up rx */
239 ctx->cb_port = rpc_test_params.cb_next_port++;
240 ctx->cb_listen_addr.numberOfInterfaces = 1;
241
242#ifdef AFS_NT40_ENV
243 code = WSAStringToAddressA(listen_addr_s, AF_INET, NULL,
244 (struct sockaddr*) &(ctx->cb_listen_addr), &sslen);
245#else
246 code = inet_pton(AF_INET, listen_addr_s,
247 (void*) &(ctx->cb_listen_addr.addr_in[0]));
248#endif
249
250 code = init_callback_service(ctx /* LOCKED, && rpc_test_params->mtx LOCKED */);
251
252 /* fsint (client) */
253
254#ifdef AFS_NT40_ENV
255 code = WSAStringToAddressA(fs_addr_s, AF_INET, NULL,
256 (struct sockaddr*) &(ctx->fs_addr.addr_in[0]), &sslen);
257#else
258 code = inet_pton(AF_INET, fs_addr_s, (void*) &(ctx->fs_addr.addr_in[0]));
259#endif
260 ctx->sc = rxnull_NewClientSecurityObject();
261 ctx->sc_index = RX_SECIDX_NULL;
262 ctx->conn = rx_NewConnection(ctx->fs_addr.addr_in[0], (int) htons(fs_port),
263 1, ctx->sc, ctx->sc_index);
264
265 /* unlock this */
266 pthread_mutex_unlock(&ctx->mtx);
267
268 return (code);
269
270} /* init_fs_channel */
271
272/* XXX use the pkg lock to protect the state of rx_socket for
273 * the duration of the call, switching it out for the stashed
274 * rx_socket created by rx_NewService for this channel */
275#define RXCALL_WITH_SOCK(code, ctx, call) \
276 do { \
277 osi_socket prev_rx_socket; \
278 pthread_mutex_lock(&rpc_test_params.mtx); \
279 prev_rx_socket = rx_socket; \
280 rx_socket = ctx->svc->socket; \
281 code = call; \
282 rx_socket = prev_rx_socket; \
283 pthread_mutex_unlock(&rpc_test_params.mtx); \
284} while(0);
285
286afs_int32
287rpc_test_afs_fetch_status(rpc_test_request_ctx *ctx, AFSFid *fid,
288 AFSFetchStatus *outstatus)
289{
290 struct AFSVolSync tsync;
291 struct AFSCallBack tcb;
292 afs_int32 code = 0;
293
294 RXCALL_WITH_SOCK(code, ctx,
295 (RXAFS_FetchStatus(ctx->conn, fid, outstatus, &tcb, &tsync)));
296
297 return (code);
298
299} /* rpc_test_afs_fetch_status */
300
301afs_int32
302rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid,
303 AFSStoreStatus *instatus, AFSFetchStatus *outstatus)
304{
305 struct AFSVolSync tsync;
306 afs_int32 code = 0;
307
308 RXCALL_WITH_SOCK(code, ctx,
309 (RXAFS_StoreStatus(ctx->conn, fid, instatus, outstatus, &tsync)));
310
311 return (code);
312
313} /* rpc_test_afs_fetch_status */
314
315#if defined(AFS_BYTE_RANGE_FLOCKS)
316afs_int32 rpc_test_afs_set_byterangelock(rpc_test_request_ctx *ctx,
317 AFSByteRangeLock * lock)
318{
319 struct rx_call *tcall;
320 afs_int32 code = 0;
321
322 RXCALL_WITH_SOCK(code, ctx,
323 (RXAFS_SetByteRangeLock(ctx->conn, lock)));
324
325 return (code);
326
327} /* rpc_test_afs_set_byterangelock */
328
329afs_int32 rpc_test_afs_release_byterangelock(rpc_test_request_ctx *ctx,
330 AFSByteRangeLock * lock)
331{
332 struct rx_call *tcall;
333 afs_int32 code = 0;
334
335 RXCALL_WITH_SOCK(code, ctx,
336 (RXAFS_ReleaseByteRangeLock(ctx->conn, lock)));
337
338 return (code);
339
340} /* rpc_test_afs_release_byterangelock */
341
342afs_int32 rpc_test_afs_upgrade_byterangelock(rpc_test_request_ctx *ctx,
343 AFSByteRangeLock * lock)
344{
345 afs_int32 code = 0;
346
347 /* TODO: implement */
348
349 return (code);
350
351} /* rpc_test_afs_upgrade_byterangelock */
352
353afs_int32 rpc_test_afs_downgrade_byterangelock(rpc_test_request_ctx *ctx,
354 AFSByteRangeLock * Lock)
355{
356 afs_int32 code = 0;
357
358 /* TODO: implement */
359
360 return (code);
361
362} /* rpc_test_afs_downgrade_byterangelock */
363#endif /* AFS_BYTE_RANGE_FLOCKS */
364
365afs_int32
366destroy_fs_channel(rpc_test_request_ctx *ctx)
367{
368 afs_int32 code = 0;
369#if defined(RPC_TEST_ADD_ADDRESSES)
370#if defined(AFS_LINUX26_ENV)
371 sprintf(cmd, "ip addr del %s/%s dev %s label %s", ctx->cb_listen_addr_s,
372 ctx->cb_prefix_s, ctx->cb_if_s, ctx->cb_if_s);
373 code = system(cmd);
374#endif
375#endif /* RPC_TEST_ADD_ADDRESSES */
376 assert(ctx);
377 free(ctx);
378 return (code);
379
380} /* destroy_fs_channel */
381
382void
383rpc_test_PkgShutdown(void)
384{
385} /* rpc_test_PkgShutdown */