libroken: Build on windows
[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 #include <roken.h>
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 <string.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 <afs/budb_client.h>
33 #include <afs/bucoord_prototypes.h>
34 #include "butc_internal.h"
35
36 #include "error_macros.h"
37 #include "butc_xbsa.h"
38 /* tape coordinator - task status management */
39 extern afs_int32 xbsaType;
40
41 dlqlinkT statusHead;
42 struct Lock statusQueueLock;
43 struct Lock cmdLineLock;
44
45 /* STC_GetStatus
46  *      get the status of a task
47  * entry:
48  *      taskId - task for which status required
49  * exit:
50  *      statusPtr - filled in with task status
51  */
52
53 afs_int32
54 STC_GetStatus(struct rx_call *call, 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(struct rx_call *call, afs_uint32 taskId)
86 {
87     statusP ptr;
88     int retval = 0;
89
90     if (callPermitted(call) == 0)
91         return (TC_NOTPERMITTED);
92
93     lock_Status();
94     ptr = findStatus(taskId);
95     unlock_Status();
96
97     if (ptr)
98         deleteStatusNode(ptr);
99     else
100         retval = TC_NODENOTFOUND;
101
102     return (retval);
103 }
104
105 afs_int32
106 STC_RequestAbort(struct rx_call *call, 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 afs_int32
141 STC_ScanStatus(struct rx_call *call, afs_uint32 *taskId,
142                struct tciStatusS *statusPtr, afs_uint32 *flags)
143 {
144     statusP ptr = 0;
145     dlqlinkP dlqPtr;
146
147     if (callPermitted(call) == 0)
148         return (TC_NOTPERMITTED);
149
150     lock_Status();
151
152     if (CONF_XBSA)
153         *flags |= TSK_STAT_XBSA;
154     if (xbsaType == XBSA_SERVER_TYPE_ADSM)
155         *flags |= TSK_STAT_ADSM;
156
157     if (*flags & TSK_STAT_FIRST) {
158         /* find first status node */
159         dlqPtr = statusHead.dlq_next;
160         if (dlqPtr == &statusHead) {
161             /* no status nodes */
162             *flags |= (TSK_STAT_NOTFOUND | TSK_STAT_END);
163             unlock_Status();
164             return (0);
165         }
166         ptr = (statusP) dlqPtr;
167     } else {
168         ptr = findStatus(*taskId);
169         if (ptr == 0) {
170             /* in the event that the set of tasks has changed, just
171              * finish, letting the caller retry
172              */
173
174             *flags |= (TSK_STAT_NOTFOUND | TSK_STAT_END);
175             unlock_Status();
176             return (0);
177         }
178     }
179
180     /* ptr is now set to the status node we wish to return. Determine
181      * what the next node will be
182      */
183
184     if (ptr->link.dlq_next == &statusHead)
185         *flags |= TSK_STAT_END;
186     else
187         *taskId = ((statusP) ptr->link.dlq_next)->taskId;
188
189     strcpy(statusPtr->taskName, ptr->taskName);
190     strcpy(statusPtr->volumeName, ptr->volumeName);
191     statusPtr->taskId = ptr->taskId;
192     statusPtr->flags = ptr->flags;
193     statusPtr->nKBytes = ptr->nKBytes;
194     statusPtr->lastPolled = ptr->lastPolled;
195
196     unlock_Status();
197     return (0);
198 }
199
200
201 /* ---------------------------------
202  * misc. status management routines
203  * ---------------------------------
204  */
205
206 /* checkAbortByTaskId
207  * exit:
208  *      0 - continue
209  *      n - abort requested
210  */
211
212 int
213 checkAbortByTaskId(afs_uint32 taskId)
214 {
215     statusP statusPtr;
216     int retval = 0;
217
218     lock_Status();
219     statusPtr = findStatus(taskId);
220     if (statusPtr) {
221         retval = statusPtr->flags & ABORT_REQUEST;
222     }
223     unlock_Status();
224     return (retval);
225 }
226
227 /* getStatusFlag
228  *      For backwards compatibility. Queries flag status
229  * exit:
230  *      0 - flag clear
231  *      n - flag set
232  */
233
234 afs_uint32
235 getStatusFlag(afs_uint32 taskId, afs_uint32 flag)
236 {
237     statusP statusPtr;
238     int retval = 0;
239
240     lock_Status();
241     statusPtr = findStatus(taskId);
242     if (statusPtr) {
243         retval = statusPtr->flags & flag;
244     }
245     unlock_Status();
246     return (retval);
247 }