Commit | Line | Data |
---|---|---|
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 | ||
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 | #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 | ||
198 | afs_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 | ||
286 | afs_int32 | |
287 | rpc_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 | ||
301 | afs_int32 | |
302 | rpc_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) | |
316 | afs_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 | ||
329 | afs_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 | ||
342 | afs_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 | ||
353 | afs_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 | ||
365 | afs_int32 | |
366 | destroy_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 | ||
382 | void | |
383 | rpc_test_PkgShutdown(void) | |
384 | { | |
385 | } /* rpc_test_PkgShutdown */ |