79c0c536584a13416b04d43cfc7a228d067d096f
[openafs.git] / src / butc / tcstatus.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 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID
14     ("$Header$");
15
16 #include <sys/types.h>
17 #ifdef AFS_NT40_ENV
18 #include <winsock2.h>
19 #else
20 #include <netinet/in.h>
21 #include <netdb.h>
22 #include <sys/socket.h>
23 #include <sys/time.h>
24 #include <strings.h>
25 #endif
26 #include <stdio.h>
27 #include <afs/com_err.h>
28 #include <lock.h>
29 #include <afs/bubasics.h>
30 #include <afs/tcdata.h>
31 #include <afs/butc.h>
32 #include "error_macros.h"
33 #include "butc_xbsa.h"
34
35 /* tape coordinator - task status management */
36 extern statusP findStatus();
37 extern afs_int32 xbsaType;
38
39 dlqlinkT statusHead;
40 struct Lock statusQueueLock;
41 struct Lock cmdLineLock;
42
43 /* STC_GetStatus
44  *      get the status of a task
45  * entry:
46  *      taskId - task for which status required
47  * exit:
48  *      statusPtr - filled in with task status
49  */
50
51 afs_int32
52 STC_GetStatus(call, taskId, statusPtr)
53      struct rx_call *call;
54      afs_uint32 taskId;
55      struct tciStatusS *statusPtr;
56 {
57     statusP ptr;
58     int retval = 0;
59
60     if (callPermitted(call) == 0)
61         return (TC_NOTPERMITTED);
62
63     lock_Status();
64     ptr = findStatus(taskId);
65     if (ptr) {
66         /* strcpy(statusPtr->status, ptr->status); */
67
68         strcpy(statusPtr->taskName, ptr->taskName);
69         strcpy(statusPtr->volumeName, ptr->volumeName);
70         statusPtr->taskId = ptr->taskId;
71         statusPtr->flags = ptr->flags;
72         statusPtr->nKBytes = ptr->nKBytes;
73         statusPtr->dbDumpId = ptr->dbDumpId;
74         statusPtr->lastPolled = ptr->lastPolled;
75         statusPtr->volsFailed = ptr->volsFailed;
76         ptr->lastPolled = time(0);
77     } else
78         retval = TC_NODENOTFOUND;
79     unlock_Status();
80
81     return (retval);
82 }
83
84 afs_int32
85 STC_EndStatus(call, taskId)
86      struct rx_call *call;
87      afs_uint32 taskId;
88 {
89     statusP ptr;
90     int retval = 0;
91
92     if (callPermitted(call) == 0)
93         return (TC_NOTPERMITTED);
94
95     lock_Status();
96     ptr = findStatus(taskId);
97     unlock_Status();
98
99     if (ptr)
100         deleteStatusNode(ptr);
101     else
102         retval = TC_NODENOTFOUND;
103
104     return (retval);
105 }
106
107 afs_int32
108 STC_RequestAbort(call, taskId)
109      struct rx_call *call;
110      afs_uint32 taskId;
111 {
112     statusP ptr;
113     int retval = 0;
114
115     if (callPermitted(call) == 0)
116         return (TC_NOTPERMITTED);
117
118     lock_Status();
119     ptr = findStatus(taskId);
120     if (ptr)
121         ptr->flags |= ABORT_REQUEST;
122     else
123         retval = TC_NODENOTFOUND;
124     unlock_Status();
125     return (retval);
126 }
127
128 /* STC_ScanStatus
129  *      Get status of all tasks on the butc, successively. Initial call
130  *      should come in with TSK_STAT_FIRST flag set to initialize the
131  *      scan.
132  * entry:
133  *      taskId - specifies the task whose status is to be returned
134  *              (unless TSK_STAT_FIRST set in which case it is ignored)
135  * exit:
136  *      taskId - id of next task in the list
137  *      flags - TSK_STAT_END will be set when one reaches the end of
138  *              the task list. taskId is not updated in this case.
139  * return values:
140  *      0 - normal
141  *      TC_NOTASKS - no tasks active
142  */
143
144 afs_int32
145 STC_ScanStatus(call, taskId, statusPtr, flags)
146      struct rx_call *call;
147      afs_uint32 *taskId;
148      struct tciStatusS *statusPtr;
149      afs_uint32 *flags;
150 {
151     statusP ptr = 0;
152     statusP nextPtr = 0;
153     dlqlinkP dlqPtr;
154
155     if (callPermitted(call) == 0)
156         return (TC_NOTPERMITTED);
157
158     lock_Status();
159
160     if (CONF_XBSA)
161         *flags |= TSK_STAT_XBSA;
162     if (xbsaType == XBSA_SERVER_TYPE_ADSM)
163         *flags |= TSK_STAT_ADSM;
164
165     if (*flags & TSK_STAT_FIRST) {
166         /* find first status node */
167         dlqPtr = statusHead.dlq_next;
168         if (dlqPtr == &statusHead) {
169             /* no status nodes */
170             *flags |= (TSK_STAT_NOTFOUND | TSK_STAT_END);
171             unlock_Status();
172             return (0);
173         }
174         ptr = (statusP) dlqPtr;
175     } else {
176         ptr = findStatus(*taskId);
177         if (ptr == 0) {
178             /* in the event that the set of tasks has changed, just
179              * finish, letting the caller retry
180              */
181
182             *flags |= (TSK_STAT_NOTFOUND | TSK_STAT_END);
183             unlock_Status();
184             return (0);
185         }
186     }
187
188     /* ptr is now set to the status node we wish to return. Determine
189      * what the next node will be
190      */
191
192     if (ptr->link.dlq_next == &statusHead)
193         *flags |= TSK_STAT_END;
194     else
195         *taskId = ((statusP) ptr->link.dlq_next)->taskId;
196
197     strcpy(statusPtr->taskName, ptr->taskName);
198     strcpy(statusPtr->volumeName, ptr->volumeName);
199     statusPtr->taskId = ptr->taskId;
200     statusPtr->flags = ptr->flags;
201     statusPtr->nKBytes = ptr->nKBytes;
202     statusPtr->lastPolled = ptr->lastPolled;
203
204     unlock_Status();
205     return (0);
206 }
207
208
209 /* ---------------------------------
210  * misc. status management routines
211  * ---------------------------------
212  */
213
214 /* checkAbortByTaskId
215  * exit:
216  *      0 - continue
217  *      n - abort requested
218  */
219
220 checkAbortByTaskId(taskId)
221      afs_uint32 taskId;
222 {
223     statusP statusPtr;
224     int retval = 0;
225
226     extern statusP findStatus();
227
228     lock_Status();
229     statusPtr = findStatus(taskId);
230     if (statusPtr) {
231         retval = statusPtr->flags & ABORT_REQUEST;
232     }
233     unlock_Status();
234     return (retval);
235 }
236
237 /* getStatusFlag
238  *      For backwards compatibility. Queries flag status
239  * exit:
240  *      0 - flag clear
241  *      n - flag set
242  */
243
244 afs_uint32
245 getStatusFlag(taskId, flag)
246      afs_uint32 taskId;
247      afs_uint32 flag;
248 {
249     statusP statusPtr;
250     int retval = 0;
251     extern statusP findStatus();
252
253     lock_Status();
254     statusPtr = findStatus(taskId);
255     if (statusPtr) {
256         retval = statusPtr->flags & flag;
257     }
258     unlock_Status();
259     return (retval);
260 }