2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #include <afs/com_err.h>
17 #include <afs/bubasics.h>
18 #include <afs/tcdata.h>
20 #include <afs/budb_client.h>
21 #include <afs/bucoord_prototypes.h>
23 #include "butc_internal.h"
24 #include "error_macros.h"
25 #include "butc_xbsa.h"
26 #include "afs/audit.h"
28 /* tape coordinator - task status management */
29 extern afs_int32 xbsaType
;
32 struct Lock statusQueueLock
;
33 struct Lock cmdLineLock
;
35 static afs_int32
SGetStatus(struct rx_call
*call
, afs_uint32 taskId
,
36 struct tciStatusS
*statusPtr
);
37 static afs_int32
SEndStatus(struct rx_call
*call
, afs_uint32 taskId
);
38 static afs_int32
SRequestAbort(struct rx_call
*call
, afs_uint32 taskId
);
39 static afs_int32
SScanStatus(struct rx_call
*call
, afs_uint32
*taskId
,
40 struct tciStatusS
*statusPtr
, afs_uint32
*flags
);
43 * get the status of a task
45 * taskId - task for which status required
47 * statusPtr - filled in with task status
51 STC_GetStatus(struct rx_call
*call
, afs_uint32 taskId
,
52 struct tciStatusS
*status
)
56 code
= SGetStatus(call
, taskId
, status
);
57 osi_auditU(call
, TC_GetStatusEvent
, code
,
58 AUD_INT
, taskId
, AUD_TSTT
, status
, AUD_END
);
63 SGetStatus(struct rx_call
*call
, afs_uint32 taskId
,
64 struct tciStatusS
*statusPtr
)
69 memset(statusPtr
, 0, sizeof(*statusPtr
));
70 if (callPermitted(call
) == 0)
71 return (TC_NOTPERMITTED
);
74 ptr
= findStatus(taskId
);
76 strcpy(statusPtr
->taskName
, ptr
->taskName
);
77 strcpy(statusPtr
->volumeName
, ptr
->volumeName
);
78 statusPtr
->taskId
= ptr
->taskId
;
79 statusPtr
->flags
= ptr
->flags
;
80 statusPtr
->nKBytes
= ptr
->nKBytes
;
81 statusPtr
->dbDumpId
= ptr
->dbDumpId
;
82 statusPtr
->lastPolled
= ptr
->lastPolled
;
83 statusPtr
->volsFailed
= ptr
->volsFailed
;
84 ptr
->lastPolled
= time(0);
86 retval
= TC_NODENOTFOUND
;
93 STC_EndStatus(struct rx_call
*call
, afs_uint32 taskId
)
97 code
= SEndStatus(call
, taskId
);
98 osi_auditU(call
, TC_EndStatusEvent
, code
, AUD_INT
, taskId
, AUD_END
);
103 SEndStatus(struct rx_call
*call
, afs_uint32 taskId
)
108 if (callPermitted(call
) == 0)
109 return (TC_NOTPERMITTED
);
112 ptr
= findStatus(taskId
);
116 deleteStatusNode(ptr
);
118 retval
= TC_NODENOTFOUND
;
124 STC_RequestAbort(struct rx_call
*call
, afs_uint32 taskId
)
128 code
= SRequestAbort(call
, taskId
);
129 osi_auditU(call
, TC_RequestAbortEvent
, code
, AUD_INT
, taskId
, AUD_END
);
134 SRequestAbort(struct rx_call
*call
, afs_uint32 taskId
)
139 if (callPermitted(call
) == 0)
140 return (TC_NOTPERMITTED
);
143 ptr
= findStatus(taskId
);
145 ptr
->flags
|= ABORT_REQUEST
;
147 retval
= TC_NODENOTFOUND
;
153 * Get status of all tasks on the butc, successively. Initial call
154 * should come in with TSK_STAT_FIRST flag set to initialize the
157 * taskId - specifies the task whose status is to be returned
158 * (unless TSK_STAT_FIRST set in which case it is ignored)
160 * taskId - id of next task in the list
161 * flags - TSK_STAT_END will be set when one reaches the end of
162 * the task list. taskId is not updated in this case.
165 * TC_NOTASKS - no tasks active
169 STC_ScanStatus(struct rx_call
*call
, afs_uint32
*taskId
,
170 struct tciStatusS
*status
, afs_uint32
*flags
)
174 code
= SScanStatus(call
, taskId
, status
, flags
);
175 osi_auditU(call
, TC_ScanStatusEvent
, code
,
176 AUD_INT
, *taskId
, AUD_TSTT
, status
, AUD_INT
, *flags
, AUD_END
);
181 SScanStatus(struct rx_call
*call
, afs_uint32
*taskId
,
182 struct tciStatusS
*statusPtr
, afs_uint32
*flags
)
187 memset(statusPtr
, 0, sizeof(*statusPtr
));
188 if (callPermitted(call
) == 0)
189 return (TC_NOTPERMITTED
);
194 *flags
|= TSK_STAT_XBSA
;
195 if (xbsaType
== XBSA_SERVER_TYPE_ADSM
)
196 *flags
|= TSK_STAT_ADSM
;
198 if (*flags
& TSK_STAT_FIRST
) {
199 /* find first status node */
200 dlqPtr
= statusHead
.dlq_next
;
201 if (dlqPtr
== &statusHead
) {
202 /* no status nodes */
203 *flags
|= (TSK_STAT_NOTFOUND
| TSK_STAT_END
);
207 ptr
= (statusP
) dlqPtr
;
209 ptr
= findStatus(*taskId
);
211 /* in the event that the set of tasks has changed, just
212 * finish, letting the caller retry
215 *flags
|= (TSK_STAT_NOTFOUND
| TSK_STAT_END
);
221 /* ptr is now set to the status node we wish to return. Determine
222 * what the next node will be
225 if (ptr
->link
.dlq_next
== &statusHead
)
226 *flags
|= TSK_STAT_END
;
228 *taskId
= ((statusP
) ptr
->link
.dlq_next
)->taskId
;
230 strcpy(statusPtr
->taskName
, ptr
->taskName
);
231 strcpy(statusPtr
->volumeName
, ptr
->volumeName
);
232 statusPtr
->taskId
= ptr
->taskId
;
233 statusPtr
->flags
= ptr
->flags
;
234 statusPtr
->nKBytes
= ptr
->nKBytes
;
235 statusPtr
->lastPolled
= ptr
->lastPolled
;
242 /* ---------------------------------
243 * misc. status management routines
244 * ---------------------------------
247 /* checkAbortByTaskId
250 * n - abort requested
254 checkAbortByTaskId(afs_uint32 taskId
)
260 statusPtr
= findStatus(taskId
);
262 retval
= statusPtr
->flags
& ABORT_REQUEST
;
269 * For backwards compatibility. Queries flag status
276 getStatusFlag(afs_uint32 taskId
, afs_uint32 flag
)
282 statusPtr
= findStatus(taskId
);
284 retval
= statusPtr
->flags
& flag
;