Pull in patch that properly includes stdint.h
[pkg-k5-afs_openafs.git] / tests / rpctestlib / rpc_test_procs.c
blobb47e816e0f919665fe91807c6efeb388cc629f56
1 /*
2 * Copyright (c) 2010, Linux Box Corporation.
3 * All Rights Reserved.
5 * Portions Copyright (c) 2007, Hartmut Reuter,
6 * RZG, Max-Planck-Institut f. Plasmaphysik.
7 * All Rights Reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
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.
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.
31 #include <afsconfig.h>
32 #include <afs/param.h>
33 #include <afs/stds.h>
35 #include "rpc_test_procs.h"
37 #include <stdio.h>
38 #include <sys/types.h>
39 #include <string.h>
41 #ifdef AFS_NT40_ENV
42 #else
43 #include <sys/param.h>
44 #include <sys/file.h>
45 #include <sys/ioctl.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <netdb.h>
50 #endif
52 #include <string.h>
53 #include <fcntl.h>
54 #ifdef AFS_NT40_ENV
55 #include <io.h>
56 #include <windows.h>
57 #include <WINNT/afsevent.h>
58 #else
59 #include <pwd.h>
60 #include <afs/venus.h>
61 #include <sys/time.h>
62 #include <netdb.h>
63 #endif
64 #include <afs/afsint.h>
65 #define FSINT_COMMON_XG 1
66 #include <sys/stat.h>
67 #include <errno.h>
68 #include <signal.h>
69 #include <afs/vice.h>
70 #include <afs/cmd.h>
71 #include <afs/auth.h>
72 #include <afs/cellconfig.h>
74 #include <afs/com_err.h>
75 #ifdef HAVE_DIRENT_H
76 #include <dirent.h>
77 #endif
78 #ifdef HAVE_DIRECT_H
79 #include <direct.h>
80 #endif
81 #ifdef AFS_DARWIN_ENV
82 #include <sys/malloc.h>
83 #else
84 #include <malloc.h>
85 #endif
86 #include <afs/errors.h>
87 #include <afs/sys_prototypes.h>
88 #include <rx/rx_prototypes.h>
89 #ifdef AFS_PTHREAD_ENV
90 #include <assert.h>
91 #endif
93 extern const char *prog;
94 const int ctx_key = 1;
96 #if 1
97 #define RPC_TEST_GLOBAL_RX_INIT 1
98 #else
99 #undef RPC_TEST_GLOBAL_RX_INIT
100 #endif
102 const afs_uint32 fs_port = 7000;
104 typedef struct rpc_test_pkg_params {
105 pthread_mutex_t mtx;
106 pthread_mutexattr_t mtx_attrs;
107 afs_uint32 cb_next_port;
108 afs_uint32 next_cno;
109 } rpc_test_pkg_params;
110 static rpc_test_pkg_params rpc_test_params;
112 afs_int32 rpc_test_PkgInit()
114 afs_int32 code = 0;
115 static afs_uint32 rpc_test_initialized = 0; /* once */
117 if (!rpc_test_initialized) {
118 rpc_test_initialized = 1;
119 } else {
120 printf("%s: rpc_test_PkgInit: package already initialized\n");
121 exit(1);
124 #ifndef AFS_NT40_ENV
125 code = pthread_mutexattr_init(&rpc_test_params.mtx_attrs);
126 if (code) {
127 printf("%s: rpc_test_PkgInit: pthread_mutexattr_init failed\n", prog);
128 exit(1);
130 code = pthread_mutex_init(&rpc_test_params.mtx, &rpc_test_params.mtx_attrs);
131 if (code) {
132 printf("%s: rpc_test_PkgInit: pthread_mutex_init failed\n", prog);
133 exit(1);
135 #endif
137 /* start connection sequence */
138 rpc_test_params.next_cno = 1;
140 /* set the starting port in sequence */
141 rpc_test_params.cb_next_port = 7105;
143 #if defined(RPC_TEST_GLOBAL_RX_INIT)
144 rx_Init(0);
145 #endif
147 return (code);
149 } /* rpc_test_PkgInit */
151 static void *
152 init_callback_service_lwp(void *arg)
154 struct rx_securityClass *sc;
155 struct rx_service *svc;
156 afs_int32 code = 0;
158 rpc_test_request_ctx *ctx = (rpc_test_request_ctx *) arg;
160 printf("%s: init_callback_service_lwp: listen_addr: %s "
161 "(%d) cb_port: %d\n",
162 prog, ctx->cb_listen_addr_s, ctx->cb_listen_addr.addr_in[0],
163 ctx->cb_port);
165 sc = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
166 if (!sc) {
167 fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback "
168 "service\n");
169 exit(1);
172 #if defined(RPC_TEST_GLOBAL_RX_INIT)
173 svc = rx_NewServiceHost(htonl(INADDR_ANY), htons(ctx->cb_port), 1,
174 ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
175 #else
176 svc = rx_NewService(0, 1, ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
177 #endif
178 /* stash context */
179 rx_SetServiceSpecific(svc, ctx_key, ctx);
181 if (!svc) {
182 fprintf(stderr,"rx_NewServiceHost failed for callback service\n");
183 exit(1);
186 /* XXX stash service so we can hijack its rx_socket when inititiating
187 * RPC calls */
188 ctx->svc = svc;
190 /* release pkg mutex before entering rx processing loop */
191 pthread_mutex_unlock(&rpc_test_params.mtx);
193 rx_StartServer(1);
195 printf("%s: init_callback_service_lwp: finished");
197 return (NULL);
199 } /* callback_service_lwp */
201 afs_int32 init_callback_service(rpc_test_request_ctx *ctx)
203 pthread_t tid;
204 pthread_attr_t tattr;
205 afs_int32 code = 0;
207 afs_uuid_create(&(ctx->cb_listen_addr.uuid));
209 #if !defined(RPC_TEST_GLOBAL_RX_INIT)
210 #if 0
211 code = rx_InitHost(ctx->cb_listen_addr.addr_in[0],
212 (int) htons(ctx->cb_port));
213 #else
214 code = rx_Init((int) htons(ctx->cb_port));
215 #endif
216 #endif /* RPC_TEST_GLOBAL_RX_INIT */
218 assert(pthread_attr_init(&tattr) == 0);
219 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
220 assert(pthread_create(&tid, &tattr, init_callback_service_lwp, ctx) == 0);
222 return (code);
224 } /* init_callback_service */
226 afs_int32 init_fs_channel(rpc_test_request_ctx **octx, char *cb_if,
227 char *listen_addr_s, char *prefix, char *fs_addr_s,
228 afs_uint32 flags)
230 char cmd[512];
231 rpc_test_request_ctx *ctx;
232 afs_int32 code = 0;
233 #ifdef AFS_NT40_ENV
234 afs_int32 sslen = sizeof(struct sockaddr);
235 #endif
237 ctx = *octx = (rpc_test_request_ctx *) malloc(sizeof(rpc_test_request_ctx));
238 memset(ctx, 0, sizeof(rpc_test_request_ctx));
240 /* initialize a local mutex */
241 code = pthread_mutex_init(&ctx->mtx, &rpc_test_params.mtx_attrs);
243 /* lock package before rx setup--which has global deps, atm */
244 pthread_mutex_lock(&rpc_test_params.mtx);
246 ctx->cno = rpc_test_params.next_cno++;
247 ctx->flags = flags;
249 /* afscbint (server) */
250 sprintf(ctx->cb_svc_name, "cb_%d", ctx->cno);
251 sprintf(ctx->cb_if_s, cb_if);
252 sprintf(ctx->cb_listen_addr_s, listen_addr_s);
253 sprintf(ctx->cb_prefix_s, prefix);
254 sprintf(ctx->fs_addr_s, fs_addr_s);
256 #if defined(RPC_TEST_ADD_ADDRESSES)
257 #if defined(AFS_LINUX26_ENV)
258 sprintf(cmd, "ip addr add %s/%s dev %s label %s", listen_addr_s, prefix,
259 cb_if, cb_if);
260 code = system(cmd);
261 #endif
262 #endif /* RPC_TEST_ADD_ADDRESSES */
264 /* lock this */
265 pthread_mutex_lock(&ctx->mtx);
267 /* set up rx */
268 ctx->cb_port = rpc_test_params.cb_next_port++;
269 ctx->cb_listen_addr.numberOfInterfaces = 1;
271 #ifdef AFS_NT40_ENV
272 code = WSAStringToAddressA(listen_addr_s, AF_INET, NULL,
273 (struct sockaddr*) &(ctx->cb_listen_addr), &sslen);
274 #else
275 code = inet_pton(AF_INET, listen_addr_s,
276 (void*) &(ctx->cb_listen_addr.addr_in[0]));
277 #endif
279 code = init_callback_service(ctx /* LOCKED, && rpc_test_params->mtx LOCKED */);
281 /* fsint (client) */
283 #ifdef AFS_NT40_ENV
284 code = WSAStringToAddressA(fs_addr_s, AF_INET, NULL,
285 (struct sockaddr*) &(ctx->fs_addr.addr_in[0]), &sslen);
286 #else
287 code = inet_pton(AF_INET, fs_addr_s, (void*) &(ctx->fs_addr.addr_in[0]));
288 #endif
289 ctx->sc = rxnull_NewClientSecurityObject();
290 ctx->sc_index = RX_SECIDX_NULL;
291 ctx->conn = rx_NewConnection(ctx->fs_addr.addr_in[0], (int) htons(fs_port),
292 1, ctx->sc, ctx->sc_index);
294 /* unlock this */
295 pthread_mutex_unlock(&ctx->mtx);
297 out:
298 return (code);
300 } /* init_fs_channel */
302 /* XXX use the pkg lock to protect the state of rx_socket for
303 * the duration of the call, switching it out for the stashed
304 * rx_socket created by rx_NewService for this channel */
305 #define RXCALL_WITH_SOCK(code, ctx, call) \
306 do { \
307 osi_socket prev_rx_socket; \
308 pthread_mutex_lock(&rpc_test_params.mtx); \
309 prev_rx_socket = rx_socket; \
310 rx_socket = ctx->svc->socket; \
311 code = call; \
312 rx_socket = prev_rx_socket; \
313 pthread_mutex_unlock(&rpc_test_params.mtx); \
314 } while(0);
316 afs_int32
317 rpc_test_afs_fetch_status(rpc_test_request_ctx *ctx, AFSFid *fid,
318 AFSFetchStatus *outstatus)
320 struct rx_call *tcall;
321 struct AFSVolSync tsync;
322 struct AFSCallBack tcb;
323 afs_int32 code = 0;
325 RXCALL_WITH_SOCK(code, ctx,
326 (RXAFS_FetchStatus(ctx->conn, fid, outstatus, &tcb, &tsync)));
328 return (code);
330 } /* rpc_test_afs_fetch_status */
332 afs_int32
333 rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid,
334 AFSStoreStatus *instatus, AFSFetchStatus *outstatus)
336 struct rx_call *tcall;
337 struct AFSVolSync tsync;
338 afs_int32 code = 0;
340 RXCALL_WITH_SOCK(code, ctx,
341 (RXAFS_StoreStatus(ctx->conn, fid, instatus, outstatus, &tsync)));
343 return (code);
345 } /* rpc_test_afs_fetch_status */
347 #if defined(AFS_BYTE_RANGE_FLOCKS)
348 afs_int32 rpc_test_afs_set_byterangelock(rpc_test_request_ctx *ctx,
349 AFSByteRangeLock * lock)
351 struct rx_call *tcall;
352 afs_int32 code = 0;
354 RXCALL_WITH_SOCK(code, ctx,
355 (RXAFS_SetByteRangeLock(ctx->conn, lock)));
357 return (code);
359 } /* rpc_test_afs_set_byterangelock */
361 afs_int32 rpc_test_afs_release_byterangelock(rpc_test_request_ctx *ctx,
362 AFSByteRangeLock * lock)
364 struct rx_call *tcall;
365 afs_int32 code = 0;
367 RXCALL_WITH_SOCK(code, ctx,
368 (RXAFS_ReleaseByteRangeLock(ctx->conn, lock)));
370 return (code);
372 } /* rpc_test_afs_release_byterangelock */
374 afs_int32 rpc_test_afs_upgrade_byterangelock(rpc_test_request_ctx *ctx,
375 AFSByteRangeLock * lock)
377 afs_int32 code = 0;
379 /* TODO: implement */
381 return (code);
383 } /* rpc_test_afs_upgrade_byterangelock */
385 afs_int32 rpc_test_afs_downgrade_byterangelock(rpc_test_request_ctx *ctx,
386 AFSByteRangeLock * Lock)
388 afs_int32 code = 0;
390 /* TODO: implement */
392 return (code);
394 } /* rpc_test_afs_downgrade_byterangelock */
395 #endif /* AFS_BYTE_RANGE_FLOCKS */
397 afs_int32
398 destroy_fs_channel(rpc_test_request_ctx *ctx)
400 char cmd[512];
401 afs_int32 code = 0;
402 #if defined(RPC_TEST_ADD_ADDRESSES)
403 #if defined(AFS_LINUX26_ENV)
404 sprintf(cmd, "ip addr del %s/%s dev %s label %s", ctx->cb_listen_addr_s,
405 ctx->cb_prefix_s, ctx->cb_if_s, ctx->cb_if_s);
406 code = system(cmd);
407 #endif
408 #endif /* RPC_TEST_ADD_ADDRESSES */
409 assert(ctx);
410 free(ctx);
411 return (code);
413 } /* destroy_fs_channel */
415 void
416 rpc_test_PkgShutdown()
418 afs_int32 code = 0;
420 } /* rpc_test_PkgShutdown */