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