Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / butc / butc_xbsa.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #ifdef xbsa
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14 #include <afs/stds.h>
15
16 #include <roken.h>
17
18 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
19 #include <dlfcn.h>
20 #endif
21
22 #include <afs/tcdata.h>
23 #include "butc_xbsa.h"
24 #include <afs/butx.h>
25 #include <afs/bubasics.h>
26
27 #include "butc_internal.h"
28 #include "error_macros.h"
29
30 extern int debugLevel;
31
32
33 char resourceType[20] = "LFS FILE SYSTEM";
34 #define GOODSTR(s) ((s)?(s):"<NULL>")
35
36 #ifdef NEW_XBSA
37 BSA_Int16 (*XBSAInit)(long *, SecurityToken *, ObjectOwner *, char **);
38 BSA_Int16 (*XBSABeginTxn)(long);
39 BSA_Int16 (*XBSAEndTxn)(long, Vote);
40 BSA_Int16 (*XBSATerminate)(long);
41 BSA_Int16 (*XBSAQueryObject)(long, QueryDescriptor *, ObjectDescriptor *);
42 BSA_Int16 (*XBSAGetObject)(long, ObjectDescriptor *, DataBlock *);
43 BSA_Int16 (*XBSAEndData)(long);
44 BSA_Int16 (*XBSACreateObject)(long, ObjectDescriptor *, DataBlock *);
45 BSA_Int16 (*XBSADeleteObject)(long, CopyType, ObjectName *, CopyId *);
46 BSA_Int16 (*XBSAMarkObjectInactive)(long, ObjectName *);
47 BSA_Int16 (*XBSASendData)(long, DataBlock *);
48 BSA_Int16 (*XBSAGetData)(long, DataBlock *);
49 void (*XBSAQueryApiVersion)(ApiVersion *);
50 BSA_Int16 (*XBSAGetEnvironment)(long, ObjectOwner *, char **);
51 #else
52 BSA_Int16(*XBSAInit) (BSA_UInt32 *, SecurityToken *, ObjectOwner *, char **);
53 BSA_Int16(*XBSABeginTxn) (BSA_UInt32);
54 BSA_Int16(*XBSAEndTxn) (BSA_UInt32, Vote);
55 BSA_Int16(*XBSATerminate) (BSA_UInt32);
56 BSA_Int16(*XBSAQueryObject) (BSA_UInt32, QueryDescriptor *,
57 ObjectDescriptor *);
58 BSA_Int16(*XBSAGetObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
59 BSA_Int16(*XBSAEndData) (BSA_UInt32);
60 BSA_Int16(*XBSACreateObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
61 BSA_Int16(*XBSADeleteObject) (BSA_UInt32, CopyType, ObjectName *, CopyId *);
62 BSA_Int16(*XBSAMarkObjectInactive) (BSA_UInt32, ObjectName *);
63 BSA_Int16(*XBSASendData) (BSA_UInt32, DataBlock *);
64 BSA_Int16(*XBSAGetData) (BSA_UInt32, DataBlock *);
65 BSA_Int16(*XBSAQueryApiVersion) (ApiVersion *);
66 BSA_Int16(*XBSAGetEnvironment) (BSA_UInt32, ObjectOwner *, char **);
67 #endif
68
69 void
70 xbsa_error(int rc, struct butx_transactionInfo *info)
71 {
72 switch (rc) {
73 case BSA_RC_AUTHENTICATION_FAILURE:
74 ELog(0, " XBSA: Authentication failure\n");
75 break;
76 case BSA_RC_INVALID_KEYWORD:
77 ELog(0, " XBSA: A specified keyword is invalid\n");
78 break;
79 case BSA_RC_TOKEN_EXPIRED:
80 ELog(0, " XBSA: The security token has expired\n");
81 break;
82 case ADSM_RC_PSWD_GEN:
83 if (XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM) {
84 ELog(0, " XBSA: Password generation is not supported\n");
85 }
86 break;
87 case BSA_RC_BAD_HANDLE:
88 ELog(0, " XBSA: The handle is invalid, %d\n", info->bsaHandle);
89 break;
90 case BSA_RC_NO_MATCH:
91 ELog(0,
92 " XBSA: There were no matches found for the specified object\n");
93 break;
94 case BSA_RC_MORE_DATA:
95 ELog(0, " XBSA: There were more matches found than expected\n");
96 break;
97 case BSA_RC_NULL_OBJNAME:
98 ELog(0, " XBSA: The object name is null\n");
99 break;
100 case BSA_RC_OBJNAME_TOO_LONG:
101 ELog(0, " XBSA: The object name was longer than expected\n");
102 break;
103 case BSA_RC_DESC_TOO_LONG:
104 ELog(0,
105 " XBSA: The description string was longer than expected\n");
106 break;
107 case BSA_RC_OBJINFO_TOO_LONG:
108 ELog(0,
109 " XBSA: The object info string was longer than expected\n");
110 break;
111 case BSA_RC_ABORT_ACTIVE_NOT_FOUND:
112 ELog(0, " XBSA: The specified object was not found\n");
113 break;
114 case BSA_RC_NULL_DATABLKPTR:
115 ELog(0, " XBSA: The dataBlockPtr is null\n");
116 break;
117 case BSA_RC_INVALID_VOTE:
118 ELog(0, " XBSA: The vote variable is invalid\n");
119 break;
120 }
121 }
122
123 /*
124 * Hook into the correct XBSA shared library.
125 * Set up the function pointers.
126 * Get the library version.
127 * XBSAQueryApiVersion
128 */
129 afs_int32
130 xbsa_MountLibrary(struct butx_transactionInfo *info, afs_int32 serverType)
131 {
132 #ifndef NEW_XBSA
133 void *dynlib;
134 #endif
135
136 if (debugLevel > 98) {
137 printf("\nxbsa_MountLibraray\n");
138 }
139
140 switch (serverType) {
141 case XBSA_SERVER_TYPE_ADSM:
142 #ifndef NEW_XBSA
143 #if defined(AFS_AIX_ENV)
144 dynlib =
145 dlopen("/usr/lib/libXApi.a(bsashr10.o)",
146 RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
147 if (dynlib == NULL) {
148 dynlib =
149 dlopen("/usr/lib/libXApi.a(xbsa.o)",
150 RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
151 }
152 #elif defined(AFS_SUN5_ENV)
153 dlopen ("/usr/lib/libCstd.so.1", RTLD_NOW | RTLD_GLOBAL);
154 dynlib = dlopen("/usr/lib/libXApi.so", RTLD_NOW | RTLD_GLOBAL);
155 #else
156 dynlib = NULL;
157 #endif
158 #endif
159 break;
160 default:
161 ELog(0, "xbsa_MountLibrary: The serverType %d is not recognized\n",
162 serverType);
163 return (BUTX_INVALIDSERVERTYPE);
164 break;
165 }
166
167 #ifndef NEW_XBSA
168 if (dynlib == NULL) {
169 ELog(0,
170 "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
171 return (BUTX_NOLIBRARY);
172 }
173 #endif
174
175 memset(info, 0, sizeof(struct butx_transactionInfo));
176 XBSA_SET_SERVER_TYPE(info->serverType, serverType);
177
178 #ifndef NEW_XBSA
179 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
180 XBSAInit = (BSA_Int16(*)
181 (BSA_UInt32 *, SecurityToken *, ObjectOwner *,
182 char **))dlsym((void *)dynlib, "BSAInit");
183 XBSABeginTxn =
184 (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSABeginTxn");
185 XBSAEndTxn =
186 (BSA_Int16(*)(BSA_UInt32, Vote)) dlsym((void *)dynlib, "BSAEndTxn");
187 XBSATerminate =
188 (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSATerminate");
189 XBSAQueryObject =
190 (BSA_Int16(*)(BSA_UInt32, QueryDescriptor *, ObjectDescriptor *))
191 dlsym((void *)dynlib, "BSAQueryObject");
192 XBSAGetObject =
193 (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
194 dlsym((void *)dynlib, "BSAGetObject");
195 XBSAEndData =
196 (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSAEndData");
197 XBSACreateObject =
198 (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
199 dlsym((void *)dynlib, "BSACreateObject");
200 XBSAMarkObjectInactive =
201 (BSA_Int16(*)(BSA_UInt32, ObjectName *)) dlsym((void *)dynlib,
202 "BSAMarkObjectInactive");
203 XBSADeleteObject =
204 (BSA_Int16(*)(BSA_UInt32, CopyType, ObjectName *, CopyId *))
205 dlsym((void *)dynlib, "BSADeleteObject");
206 XBSASendData =
207 (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
208 "BSASendData");
209 XBSAGetData =
210 (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
211 "BSAGetData");
212 XBSAQueryApiVersion =
213 (BSA_Int16(*)(ApiVersion *)) dlsym((void *)dynlib,
214 "BSAQueryApiVersion");
215 XBSAGetEnvironment =
216 (BSA_Int16(*)(BSA_UInt32, ObjectOwner *, char **))dlsym((void *)
217 dynlib,
218 "BSAGetEnvironment");
219
220 if (!XBSAInit || !XBSABeginTxn || !XBSAEndTxn || !XBSATerminate
221 || !XBSAQueryObject || !XBSAGetObject || !XBSAEndData
222 || !XBSACreateObject || !XBSADeleteObject || !XBSAMarkObjectInactive
223 || !XBSASendData || !XBSAGetData || !XBSAQueryApiVersion
224 || !XBSAGetEnvironment) {
225 ELog(0,
226 "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
227 return (BUTX_NOLIBRARY);
228 }
229 XBSAQueryApiVersion(&(info->apiVersion));
230 #endif
231 #else
232 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
233 XBSAInit = BSAInit;
234 XBSABeginTxn = BSABeginTxn;
235 XBSAEndTxn = BSAEndTxn;
236 XBSATerminate = BSATerminate;
237 XBSAQueryObject = BSAQueryObject;
238 XBSAGetObject = BSAGetObject;
239 XBSAEndData = BSAEndData;
240 XBSACreateObject = BSACreateObject;
241 XBSAMarkObjectInactive = BSAMarkObjectInactive;
242 XBSADeleteObject = BSADeleteObject;
243 XBSASendData = BSASendData;
244 XBSAGetData = BSAGetData;
245 XBSAQueryApiVersion = BSAQueryApiVersion;
246 XBSAGetEnvironment = BSAGetEnvironment;
247
248 if (!XBSAInit || !XBSABeginTxn || !XBSAEndTxn || !XBSATerminate ||
249 !XBSAQueryObject || !XBSAGetObject || !XBSAEndData ||
250 !XBSACreateObject || !XBSADeleteObject || !XBSAMarkObjectInactive ||
251 !XBSASendData || !XBSAGetData || !XBSAQueryApiVersion ||
252 !XBSAGetEnvironment) {
253 ELog(0,"xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
254 return(BUTX_NOLIBRARY);
255 }
256 XBSAQueryApiVersion(&(info->apiVersion));
257 #endif
258 #endif
259
260 #ifdef DEBUG_BUTC
261 printf("xbsa_MountLibrary : XBSA function Pointers initialised. \n");
262 #endif
263 /*
264 * Verify the API version
265 */
266 if ((info->apiVersion.version == XBSA_TS_VERSION)
267 && (info->apiVersion.release == XBSA_TS_RELEASE)) {
268 /* XOPEN Techincal Standard Level!
269 * We are coded to the Preliminary Spec! Time to go boom!
270 */
271 ELog(0,
272 "xbsa_MountLibrary: The XBSAQueryApiVersion call returned an incompatible version, %d %d %d\n",
273 info->apiVersion.version, info->apiVersion.release,
274 info->apiVersion.level);
275 return (BUTX_INVALIDVERSION);
276 }
277
278 switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
279 case XBSA_SERVER_TYPE_ADSM:
280 if ((info->apiVersion.version > XBSA_ADSM_NO_MULT_SERVER_VERSION)
281 || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
282 && info->apiVersion.release >
283 XBSA_ADSM_NO_MULT_SERVER_RELEASE)
284 || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
285 && info->apiVersion.release ==
286 XBSA_ADSM_NO_MULT_SERVER_RELEASE
287 && info->apiVersion.level > XBSA_ADSM_NO_MULT_SERVER_LEVEL)) {
288
289 /* This version contains the fixes to allow multiple servers */
290 info->serverType |= XBSA_SERVER_FLAG_MULTIPLE;
291 } else {
292 /* This is an older version of ADSM prior to the fix to
293 * allow multiple servers.
294 */
295 info->serverType |= XBSA_SERVER_FLAG_NONE;
296 }
297 break;
298 }
299
300 return (XBSA_SUCCESS);
301
302 }
303
304 /*
305 * Set up the connection to the XBSA Server.
306 * BSAInit
307 * BSAGetEnvironment
308 */
309 afs_int32
310 xbsa_Initialize(struct butx_transactionInfo * info, char *bsaObjectOwner,
311 char *appObjectOwner, char *secToken, char *serverName)
312 {
313 char envStrs[XBSA_NUM_ENV_STRS][BSA_MAX_DESC];
314 char *envP[XBSA_NUM_ENV_STRS + 1];
315 char *ADSMMaxObject = "TSMMAXOBJ=";
316 char *ADSMServer = "TSMSRVR=";
317 char *tempStrPtr;
318 int i;
319 int rc;
320
321 if (debugLevel > 98) {
322 printf("\nxbsa_Initialize bsaObjectOwner='%s' appObjectOwner='%s' "
323 "secToken=xxxxxx servername='%s'\n", GOODSTR(bsaObjectOwner),
324 GOODSTR(appObjectOwner), GOODSTR(serverName));
325 }
326
327 if (info->bsaHandle != 0) {
328 /* We already have a handle */
329 ELog(0,
330 "xbsa_Initialize: The dlopen call to load the XBSA shared library failed\n");
331 return (BUTX_ILLEGALINIT);
332 }
333
334 /*
335 * The XBSAGetEnvironment function is supposed to return the
336 * the serverName to use. However, it is returning the tcpserveraddress
337 * instead. So, we can't count on this function to properly fill it
338 * in. So, until that get fixed. The serverName will have to be filled
339 * in by the callers of this function (butc).
340 */
341
342 /* Initialize the environment strings */
343 for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
344 envP[i] = envStrs[i];
345 envP[XBSA_NUM_ENV_STRS] = NULL;
346
347 /* The environment variables are specific to the server type */
348 switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
349 case XBSA_SERVER_TYPE_ADSM:
350 if (serverName) {
351 if (strlen(serverName) >= BSA_MAX_DESC) {
352 ELog(0,
353 "xbsa_Initialize: The serverName was not specified\n");
354 return (BUTX_INVALIDSERVERNAME);
355 }
356 strcpy(info->serverName, serverName);
357 strcpy(envP[0], ADSMServer);
358 tempStrPtr = envP[0];
359 tempStrPtr = tempStrPtr + strlen(ADSMServer);
360 strcat(tempStrPtr, serverName);
361 envP[1] = NULL;
362 envP[0] = NULL; /* Hack for TSM V5 */
363 } else {
364 envP[0] = NULL;
365 ELog(0, "xbsa_Initialize: The serverName was not specified\n");
366 return (BUTX_INVALIDSERVERNAME);
367 }
368 break;
369 default:
370 ELog(0, "xbsa_Initialize: The serverType %d is not recognized\n",
371 XBSA_GET_SERVER_TYPE(info->serverType));
372 return (BUTX_INVALIDSERVERTYPE);
373 break;
374 }
375
376 if (bsaObjectOwner) {
377 if (strlen(bsaObjectOwner) >= BSA_MAX_BSAOBJECT_OWNER) {
378 ELog(0,
379 "xbsa_Initialize: The bsaObjectOwner is too long; size = %d; name = %s\n",
380 strlen(bsaObjectOwner), bsaObjectOwner);
381 return (BUTX_INVALIDBSANAME);
382 }
383 strcpy(info->objOwner.bsaObjectOwner, bsaObjectOwner);
384 } else {
385 info->objOwner.bsaObjectOwner[0] = '\0';
386 }
387
388 if (appObjectOwner) {
389 if (strlen(appObjectOwner) >= BSA_MAX_APPOBJECT_OWNER) {
390 ELog(0,
391 "xbsa_Initialize: The appObjectOwner is too long; size = %d; name = %s\n",
392 strlen(appObjectOwner), appObjectOwner);
393 return (BUTX_INVALIDAPPNAME);
394 }
395 strcpy(info->objOwner.appObjectOwner, appObjectOwner);
396 } else {
397 info->objOwner.appObjectOwner[0] = '\0';
398 }
399
400 if (secToken) {
401 if (strlen(secToken) >= BSA_MAX_TOKEN_SIZE) {
402 ELog(0,
403 "xbsa_Initialize: The secToken is too long; size = %d; name = %s\n",
404 strlen(secToken), secToken);
405 return (BUTX_INVALIDSECTOKEN);
406 }
407 strcpy(info->secToken, secToken);
408 } else {
409 info->secToken[0] = '\0';
410 }
411
412 rc = (int)XBSAInit(&(info->bsaHandle), &(info->secToken),
413 &(info->objOwner), envP);
414 if (rc != BSA_RC_SUCCESS) {
415 ELog(0, "xbsa_Initialize: The XBSAInit call failed with %d\n", rc);
416 xbsa_error(rc, info);
417 return (BUTX_INITFAIL);
418 }
419
420 /* Initialize the environment strings */
421 for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
422 envP[i] = envStrs[i];
423 envP[XBSA_NUM_ENV_STRS] = NULL;
424
425 rc = (int)XBSAGetEnvironment(info->bsaHandle, &info->objOwner, envP);
426 if (rc != BSA_RC_SUCCESS) {
427 ELog(0,
428 "xbsa_Initialize: The XBSAGetEnvironment call failed with %d\n",
429 rc);
430 xbsa_error(rc, info);
431 return (BUTX_GETENVFAIL);
432 }
433
434 info->maxObjects = 255; /* Hack for ADSM V5: unclear what this actually means... */
435
436 switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
437 case XBSA_SERVER_TYPE_ADSM:
438 for (i = 0; i < XBSA_NUM_ENV_STRS; i++) {
439 if (strncmp(envP[i], ADSMMaxObject, strlen(ADSMMaxObject)) == 0) {
440 tempStrPtr = envP[i];
441 tempStrPtr = tempStrPtr + strlen(ADSMMaxObject);
442 info->maxObjects = strtol(tempStrPtr, NULL, 10);
443 if (info->maxObjects <= 0) {
444 ELog(0,
445 "xbsa_Initialize: The XBSAGetEnvironment call returned an invalid value for MAXOBJ %d\n",
446 info->maxObjects);
447 return (BUTX_GETENVFAIL);
448 }
449 }
450 }
451 if (info->maxObjects == 0) {
452 ELog(0,
453 "xbsa_Initialize: The XBSAGetEnvironment call failed to return the MAXOBJ string\n");
454 return (BUTX_GETENVFAIL);
455 }
456 break;
457 }
458
459 return (XBSA_SUCCESS);
460 }
461
462 /*
463 * Create a transaction
464 * BSABeginTxn
465 */
466 afs_int32
467 xbsa_BeginTrans(struct butx_transactionInfo * info)
468 {
469 int rc;
470
471 if (debugLevel > 98) {
472 printf("\nxbsa_BeginTrans\n");
473 printf
474 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
475 GOODSTR(info->serverName),
476 GOODSTR(info->objOwner.bsaObjectOwner),
477 GOODSTR(info->objOwner.appObjectOwner));
478 }
479
480 if (info->bsaHandle == 0) {
481 /* We haven't initialized yet! */
482 ELog(0, "xbsa_BeginTrans: No current handle, butx not initialized\n");
483 return (BUTX_NOHANDLE);
484 }
485
486 rc = (int)XBSABeginTxn(info->bsaHandle);
487 if (rc != BSA_RC_SUCCESS) {
488 ELog(0, "xbsa_BeginTrans: The XBSABeginTxn call failed with %d\n",
489 rc);
490 xbsa_error(rc, info);
491 return (BUTX_BEGINTXNFAIL);
492 }
493
494 info->numObjects = 0;
495 return (XBSA_SUCCESS);
496 }
497
498 /*
499 * End the current transaction
500 * BSAEndTxn
501 */
502 afs_int32
503 xbsa_EndTrans(struct butx_transactionInfo * info)
504 {
505 int rc;
506
507 if (debugLevel > 98) {
508 printf("\nxbsa_EndTrans\n");
509 printf
510 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
511 GOODSTR(info->serverName),
512 GOODSTR(info->objOwner.bsaObjectOwner),
513 GOODSTR(info->objOwner.appObjectOwner));
514 }
515
516 if (info->bsaHandle == 0) {
517 /* We haven't initialized yet! */
518 ELog(0, "xbsa_EndTrans: No current handle, butx not initialized\n");
519 return (BUTX_NOHANDLE);
520 }
521
522 /* terminate the transaction */
523 rc = (int)XBSAEndTxn(info->bsaHandle, BSAVote_COMMIT);
524 if (rc != BSA_RC_SUCCESS) {
525 ELog(0, "xbsa_EndTrans: The XBSAEndTxn call failed with %d\n", rc);
526 xbsa_error(rc, info);
527 return (BUTX_ENDTXNFAIL);
528 }
529 return (XBSA_SUCCESS);
530 }
531
532 /*
533 * Terminate the connection to the XBSA Server.
534 * End the transaction.
535 * BSATerminate
536 */
537 afs_int32
538 xbsa_Finalize(struct butx_transactionInfo * info)
539 {
540 int rc;
541
542 if (debugLevel > 98) {
543 printf("\nxbsa_Finalize\n");
544 printf
545 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
546 GOODSTR(info->serverName),
547 GOODSTR(info->objOwner.bsaObjectOwner),
548 GOODSTR(info->objOwner.appObjectOwner));
549 }
550
551 if (info->bsaHandle == 0) {
552 /* We haven't initialized yet! */
553 ELog(0, "xbsa_Finalize: No current handle, butx not initialized\n");
554 return (BUTX_NOHANDLE);
555 }
556
557 /* terminate the session */
558 rc = (int)XBSATerminate(info->bsaHandle);
559 if (rc != BSA_RC_SUCCESS) {
560 ELog(0, "The XBSATerminate call failed with %d\n", rc);
561 xbsa_error(rc, info);
562 return (BUTX_TERMFAIL);
563 }
564
565 info->bsaHandle = 0;
566 return (XBSA_SUCCESS);
567 }
568
569 /*
570 * Query for the object we are looking for.
571 * BSAQueryObject
572 */
573 afs_int32
574 xbsa_QueryObject(struct butx_transactionInfo * info, char *objectSpaceName,
575 char *pathName)
576 {
577 int rc;
578 QueryDescriptor queryDescriptor;
579
580 if (debugLevel > 98) {
581 printf("\nxbsa_QueryObject objectSpaceName='%s' pathnName='%s'\n",
582 GOODSTR(objectSpaceName), GOODSTR(pathName));
583 printf
584 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
585 GOODSTR(info->serverName),
586 GOODSTR(info->objOwner.bsaObjectOwner),
587 GOODSTR(info->objOwner.appObjectOwner));
588 }
589
590 if (info->bsaHandle == 0) {
591 /* We haven't initialized yet! */
592 ELog(0,
593 "xbsa_QueryObject: No current handle, butx not initialized\n");
594 return (BUTX_NOHANDLE);
595 }
596
597 /* Initialize the query for our dump name */
598
599 if (objectSpaceName) {
600 if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
601 ELog(0,
602 "xbsa_QueryObject: The objectSpaceName is too long; size = %d; name = %s\n",
603 strlen(objectSpaceName), objectSpaceName);
604 return (BUTX_INVALIDOBJECTSPNAME);
605 }
606 strcpy(queryDescriptor.objName.objectSpaceName, objectSpaceName);
607 } else {
608 queryDescriptor.objName.objectSpaceName[0] = '\0';
609 }
610
611 if (pathName) {
612 if (strlen(pathName) >= BSA_MAX_PATHNAME) {
613 ELog(0,
614 "xbsa_QueryObject: The pathName is too long; size = %d; name = %s\n",
615 strlen(pathName), pathName);
616 return (BUTX_INVALIDPATHNAME);
617 }
618 strcpy(queryDescriptor.objName.pathName, pathName);
619 } else {
620 queryDescriptor.objName.pathName[0] = '\0';
621 }
622
623 queryDescriptor.owner = info->objOwner;
624 queryDescriptor.copyType = BSACopyType_BACKUP;
625 strcpy(queryDescriptor.lGName, "");
626 strcpy(queryDescriptor.cGName, "");
627 strcpy(queryDescriptor.resourceType, "");
628 queryDescriptor.objectType = BSAObjectType_FILE;
629 queryDescriptor.status = BSAObjectStatus_ACTIVE;
630 strcpy(queryDescriptor.desc, "");
631
632 rc = (int)XBSAQueryObject(info->bsaHandle, &queryDescriptor,
633 &info->curObject);
634 if (rc == BSA_RC_NO_MORE_DATA)
635 rc = BSA_RC_SUCCESS; /* This is actually a success! */
636 if (rc != BSA_RC_SUCCESS) {
637 ELog(0, "xbsa_QueryObject: The xBSAQueryObject call failed with %d\n",
638 rc);
639 xbsa_error(rc, info);
640 return (BUTX_QUERYFAIL);
641 }
642 return (XBSA_SUCCESS);
643 }
644
645 /*
646 * Locate the correct object on the server and then make the call to
647 * get the object descriptor so we can begin the transfer of data.
648 * BSAGetObject
649 */
650 afs_int32
651 xbsa_ReadObjectBegin(struct butx_transactionInfo * info, char *dataBuffer,
652 afs_int32 bufferSize, afs_int32 * count,
653 afs_int32 * endOfData)
654 {
655 int rc;
656 DataBlock dataBlock;
657
658 if (debugLevel > 98) {
659 printf("\nxbsa_ReadObjectBegin %d Bytes\n", bufferSize);
660 printf
661 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
662 GOODSTR(info->serverName),
663 GOODSTR(info->objOwner.bsaObjectOwner),
664 GOODSTR(info->objOwner.appObjectOwner));
665 }
666
667 if (info->bsaHandle == 0) {
668 /* We haven't initialized yet! */
669 ELog(0,
670 "xbsa_ReadObjectBegin: No current handle, butx not initialized\n");
671 return (BUTX_NOHANDLE);
672 }
673
674 if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
675 ELog(0, "xbsa_ReadObjectBegin: The bufferSize %d is invalid\n",
676 bufferSize);
677 return (BUTX_INVALIDBUFFERSIZE);
678 }
679
680 if (dataBuffer == NULL) {
681 ELog(0, "xbsa_ReadObjectBegin: The dataBuffer is NULL\n");
682 return (BUTX_INVALIDDATABUFFER);
683 }
684
685 dataBlock.bufferLen = (BSA_UInt16) bufferSize;
686 dataBlock.numBytes = (BSA_UInt16) 0;
687 dataBlock.bufferPtr = dataBuffer;
688 *endOfData = 0;
689
690 rc = (int)XBSAGetObject(info->bsaHandle, &info->curObject, &dataBlock);
691 if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
692 ELog(0,
693 "xbsa_ReadObjectBegin: The XBSAGetObject call failed with %d\n",
694 rc);
695 xbsa_error(rc, info);
696 return (BUTX_GETOBJFAIL);
697 }
698 *count = dataBlock.numBytes;
699 if (rc == BSA_RC_NO_MORE_DATA)
700 *endOfData = 1;
701 return (XBSA_SUCCESS);
702 }
703
704
705 /*
706 * Tell the XBSA Server that this is the end of Data for this object.
707 * BSAEndData()
708 */
709 afs_int32
710 xbsa_ReadObjectEnd(struct butx_transactionInfo * info)
711 {
712 int rc;
713
714 if (debugLevel > 98) {
715 printf("\nxbsa_ReadObjectEnd\n");
716 printf
717 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
718 GOODSTR(info->serverName),
719 GOODSTR(info->objOwner.bsaObjectOwner),
720 GOODSTR(info->objOwner.appObjectOwner));
721 }
722
723 if (info->bsaHandle == 0) {
724 /* We haven't initialized yet! */
725 ELog(0,
726 "xbsa_ReadObjectEnd: No current handle, butx not initialized\n");
727 return (BUTX_NOHANDLE);
728 }
729 rc = (int)XBSAEndData(info->bsaHandle);
730 if (rc != BSA_RC_SUCCESS) {
731 ELog(0, "xbsa_ReadObjectEnd: XBSAEndData call failed with %d\n", rc);
732 xbsa_error(rc, info);
733 return (BUTX_ENDDATAFAIL);
734 }
735 return (XBSA_SUCCESS);
736 }
737
738
739 /*
740 * Create the XBSA Backup Copy Object.
741 * BSACreateObject
742 */
743 afs_int32
744 xbsa_WriteObjectBegin(struct butx_transactionInfo * info,
745 char *objectSpaceName, char *pathName, char *lGName,
746 afs_hyper_t estimatedSize, char *objectDescription,
747 char *objectInfo)
748 {
749 int rc;
750 DataBlock dataBlock;
751
752 if (debugLevel > 98) {
753 printf
754 ("\nxbsa_WriteObjectBegin objectSpacename='%s' pathName='%s' lGName='%s' "
755 "estimatesSize='0x%x%08x objectDescription='%s' objectInfo='%s'\n",
756 GOODSTR(objectSpaceName), GOODSTR(pathName), GOODSTR(lGName),
757 hgethi(estimatedSize), hgetlo(estimatedSize),
758 GOODSTR(objectDescription), GOODSTR(objectInfo));
759 printf
760 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
761 GOODSTR(info->serverName),
762 GOODSTR(info->objOwner.bsaObjectOwner),
763 GOODSTR(info->objOwner.appObjectOwner));
764 }
765
766 if (info->bsaHandle == 0) {
767 /* We haven't initialized yet! */
768 ELog(0,
769 "xbsa_WriteObjectBegin: No current handle, butx not initialized\n");
770 return (BUTX_NOHANDLE);
771 }
772
773 if (objectSpaceName) {
774 if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
775 ELog(0,
776 "xbsa_WriteObjectBegin: The objectSpaceName is too long; size = %d; name = %s\n",
777 strlen(objectSpaceName), objectSpaceName);
778 return (BUTX_INVALIDOBJECTSPNAME);
779 }
780 strcpy(info->curObject.objName.objectSpaceName, objectSpaceName);
781 } else {
782 info->curObject.objName.objectSpaceName[0] = '\0';
783 }
784
785 if (pathName) {
786 if (strlen(pathName) >= BSA_MAX_PATHNAME) {
787 ELog(0,
788 "xbsa_WriteObjectBegin: The pathName is too long; size = %d; name = %s\n",
789 strlen(pathName), pathName);
790 return (BUTX_INVALIDPATHNAME);
791 }
792 strcpy(info->curObject.objName.pathName, pathName);
793 } else {
794 info->curObject.objName.pathName[0] = '\0';
795 }
796
797 if (lGName) {
798 if (strlen(lGName) >= BSA_MAX_LG_NAME) {
799 ELog(0,
800 "xbsa_WriteObjectBegin: The lGName is too long; size = %d; name = %s\n",
801 strlen(lGName), lGName);
802 return (BUTX_INVALIDLGNAME);
803 }
804 strcpy(info->curObject.lGName, lGName);
805 } else {
806 info->curObject.lGName[0] = '\0';
807 }
808
809 if (objectDescription) {
810 if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
811 && (strlen(objectDescription) >= ADSM_MAX_DESC))
812 ||
813 ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
814 && (strlen(objectDescription) >= BSA_MAX_DESC))) {
815 ELog(0,
816 "xbsa_WriteObjectBegin: The objectDescription is too long; size = %d; name = %s\n",
817 strlen(objectDescription), objectDescription);
818 return (BUTX_INVALIDOBJDESC);
819 }
820 strcpy(info->curObject.desc, objectDescription);
821 } else {
822 info->curObject.desc[0] = '\0';
823 }
824
825 if (objectInfo) {
826 if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
827 && (strlen(objectInfo) >= ADSM_MAX_OBJINFO))
828 ||
829 ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
830 && (strlen(objectInfo) >= BSA_MAX_OBJINFO))) {
831 ELog(0,
832 "xbsa_WriteObjectBegin: The objectInfo is too long; size = %d; name = %s\n",
833 strlen(objectInfo), objectInfo);
834 return (BUTX_INVALIDOBJINFO);
835 }
836 strcpy(info->curObject.objectInfo, objectInfo);
837 } else {
838 info->curObject.objectInfo[0] = '\0';
839 }
840
841 if (info->numObjects == info->maxObjects) {
842 /* If we've used up Max Objects we must start a new transaction. */
843 rc = (int)xbsa_EndTrans(info);
844 if (rc != XBSA_SUCCESS) {
845 return (rc);
846 }
847 rc = (int)xbsa_BeginTrans(info);
848 if (rc != XBSA_SUCCESS) {
849 return (rc);
850 }
851 }
852
853 dataBlock.bufferLen = (BSA_UInt16) 0;
854 dataBlock.numBytes = (BSA_UInt16) 0;
855 dataBlock.bufferPtr = 0;
856
857 info->curObject.Owner = info->objOwner;
858 info->curObject.copyType = BSACopyType_BACKUP;
859 info->curObject.size.left = hgethi(estimatedSize);
860 info->curObject.size.right = hgetlo(estimatedSize);
861 info->curObject.objectType = BSAObjectType_FILE;
862 strcpy(info->curObject.resourceType, resourceType);
863
864 rc = (int)XBSACreateObject(info->bsaHandle, &info->curObject, &dataBlock);
865 if (rc != BSA_RC_SUCCESS) {
866 ELog(0,
867 "xbsa_WriteObjectBegin: The XBSACreateObject call failed with %d\n",
868 rc);
869 xbsa_error(rc, info);
870 return (BUTX_CREATEOBJFAIL);
871 }
872
873 info->numObjects++;
874
875 return (XBSA_SUCCESS);
876 }
877
878 /*
879 * Delete a backup object from the server
880 * BSAMarkObjectInactive()
881 * BSADeleteObject()
882 */
883 afs_int32
884 xbsa_DeleteObject(struct butx_transactionInfo * info, char *objectSpaceName,
885 char *pathName)
886 {
887 int rc;
888 ObjectName objectName;
889
890 if (debugLevel > 98) {
891 printf("\nxbsa_DeleteObject objectSpacename='%s' pathName='%s'\n",
892 GOODSTR(objectSpaceName), GOODSTR(pathName));
893 printf
894 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
895 GOODSTR(info->serverName),
896 GOODSTR(info->objOwner.bsaObjectOwner),
897 GOODSTR(info->objOwner.appObjectOwner));
898 }
899
900 if (info->bsaHandle == 0) {
901 /* We haven't initialized yet! */
902 ELog(0,
903 "xbsa_DeleteObject: No current handle, butx not initialized\n");
904 return (BUTX_NOHANDLE);
905 }
906
907 if (objectSpaceName) {
908 if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
909 ELog(0,
910 "xbsa_DeleteObject: The objectSpaceName is too long; size = %d; name = %s\n",
911 strlen(objectSpaceName), objectSpaceName);
912 return (BUTX_INVALIDOBJECTSPNAME);
913 }
914 strcpy(objectName.objectSpaceName, objectSpaceName);
915 } else {
916 objectName.objectSpaceName[0] = '\0';
917 }
918
919 if (pathName) {
920 if (strlen(pathName) >= BSA_MAX_PATHNAME) {
921 ELog(0, "xbsa_DeleteObject: strlen(pathName), pathName\n",
922 strlen(pathName), pathName);
923 return (BUTX_INVALIDPATHNAME);
924 }
925 strcpy(objectName.pathName, pathName);
926 } else {
927 objectName.pathName[0] = '\0';
928 }
929
930 rc = (int)XBSAMarkObjectInactive(info->bsaHandle, &objectName);
931 if (rc != BSA_RC_SUCCESS) {
932 ELog(0,
933 "xbsa_DeleteObject: XBSAMarkObjectInactive call failed with %d\n",
934 rc);
935 xbsa_error(rc, info);
936 return ((rc ==
937 BSA_RC_ABORT_ACTIVE_NOT_FOUND) ? BUTX_DELETENOVOL :
938 BUTX_DELETEOBJFAIL);
939 }
940
941 return (XBSA_SUCCESS);
942 }
943
944 /*
945 * Tell the XBSA Server that this is the end of Data for this object.
946 * BSAEndData()
947 */
948 afs_int32
949 xbsa_WriteObjectEnd(struct butx_transactionInfo * info)
950 {
951 int rc;
952
953 if (debugLevel > 98) {
954 printf("\nxbsa_WriteObjectEnd\n");
955 printf
956 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
957 GOODSTR(info->serverName),
958 GOODSTR(info->objOwner.bsaObjectOwner),
959 GOODSTR(info->objOwner.appObjectOwner));
960 }
961
962 if (info->bsaHandle == 0) {
963 /* We haven't initialized yet! */
964 ELog(0,
965 "xbsa_WriteObjectEnd: No current handle, butx not initialized\n");
966 return (BUTX_NOHANDLE);
967 }
968 rc = (int)XBSAEndData(info->bsaHandle);
969 if (rc != BSA_RC_SUCCESS) {
970 ELog(0, "xbsa_WriteObjectEnd: XBSAEndData call failed with %d\n", rc);
971 xbsa_error(rc, info);
972 return (BUTX_ENDDATAFAIL);
973 }
974
975 return (XBSA_SUCCESS);
976 }
977
978
979 /*
980 * Write the fileset data to the XBSA server
981 * BSASendData
982 */
983 afs_int32
984 xbsa_WriteObjectData(struct butx_transactionInfo * info, char *dataBuffer,
985 afs_int32 bufferSize, afs_int32 * count)
986 {
987 int rc;
988 DataBlock dataBlock;
989
990 if (debugLevel > 98) {
991 printf("\nxbsa_WriteObjectData %d Bytes\n", bufferSize);
992 printf
993 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
994 GOODSTR(info->serverName),
995 GOODSTR(info->objOwner.bsaObjectOwner),
996 GOODSTR(info->objOwner.appObjectOwner));
997 }
998
999 if (info->bsaHandle == 0) {
1000 /* We haven't initialized yet! */
1001 ELog(0,
1002 "xbsa_WriteObjectData: No current handle, butx not initialized\n");
1003 return (BUTX_NOHANDLE);
1004 }
1005
1006 if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
1007 ELog(0, "xbsa_WriteObjectData: The bufferSize %d is invalid\n",
1008 bufferSize);
1009 return (BUTX_INVALIDBUFFERSIZE);
1010 }
1011
1012 if (dataBuffer == NULL) {
1013 ELog(0, "xbsa_WriteObjectData: The dataBuffer is NULL\n");
1014 return (BUTX_INVALIDDATABUFFER);
1015 }
1016
1017 dataBlock.bufferPtr = dataBuffer;
1018 dataBlock.bufferLen = (BSA_UInt16) bufferSize;
1019 dataBlock.numBytes = (BSA_UInt16) 0;
1020
1021 rc = (int)XBSASendData(info->bsaHandle, &dataBlock);
1022 if (rc != BSA_RC_SUCCESS) {
1023 ELog(0, "xbsa_WriteObjectData: XBSAEndData call failed with %d\n",
1024 rc);
1025 xbsa_error(rc, info);
1026 return (BUTX_SENDDATAFAIL);
1027 }
1028 *count = dataBlock.numBytes;
1029 return (XBSA_SUCCESS);
1030 }
1031
1032
1033 /*
1034 * Read the fileset data from the XBSA server
1035 * BSAGetData
1036 */
1037 afs_int32
1038 xbsa_ReadObjectData(struct butx_transactionInfo * info, char *dataBuffer,
1039 afs_int32 bufferSize, afs_int32 * count,
1040 afs_int32 * endOfData)
1041 {
1042 int rc;
1043 DataBlock dataBlock;
1044
1045 if (debugLevel > 98) {
1046 printf("\nxbsa_ReadObjectData %d Bytes\n", bufferSize);
1047 printf
1048 ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
1049 GOODSTR(info->serverName),
1050 GOODSTR(info->objOwner.bsaObjectOwner),
1051 GOODSTR(info->objOwner.appObjectOwner));
1052 }
1053
1054 if (info->bsaHandle == 0) {
1055 /* We haven't initialized yet! */
1056 ELog(0,
1057 "xbsa_ReadObjectData: No current handle, butx not initialized\n");
1058 return (BUTX_NOHANDLE);
1059 }
1060
1061 if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
1062 ELog(0, "xbsa_ReadObjectData: The bufferSize %d is invalid\n",
1063 bufferSize);
1064 return (BUTX_INVALIDBUFFERSIZE);
1065 }
1066
1067 if (dataBuffer == NULL) {
1068 ELog(0, "xbsa_ReadObjectData: The dataBuffer is NULL\n");
1069 return (BUTX_INVALIDDATABUFFER);
1070 }
1071
1072 dataBlock.bufferLen = (BSA_UInt16) bufferSize;
1073 dataBlock.numBytes = (BSA_UInt16) 0;
1074 dataBlock.bufferPtr = dataBuffer;
1075 *endOfData = 0;
1076
1077 rc = (int)XBSAGetData(info->bsaHandle, &dataBlock);
1078 if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
1079 ELog(0, "xbsa_ReadObjectData: XBSAGetData call failed with %d\n", rc);
1080 xbsa_error(rc, info);
1081 return (BUTX_GETDATAFAIL);
1082 }
1083 *count = dataBlock.numBytes;
1084 if (rc == BSA_RC_NO_MORE_DATA)
1085 *endOfData = 1;
1086 return (XBSA_SUCCESS);
1087 }
1088 #endif /*xbsa */