Remove the RCSID macro
[openafs.git] / src / tsalvaged / salvsync-debug.c
1 /*
2  * Copyright 2006, Sine Nomine Associates 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 /* Main program file. Define globals. */
11 #define MAIN 1
12
13 /*
14  * salvsync debug tool
15  */
16
17
18 #include <afsconfig.h>
19 #include <afs/param.h>
20
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <dirent.h>
26 #include <sys/stat.h>
27 #include <time.h>
28 #include <errno.h>
29 #ifdef AFS_NT40_ENV
30 #include <io.h>
31 #include <WINNT/afsevent.h>
32 #else
33 #include <sys/param.h>
34 #include <sys/file.h>
35 #ifndef ITIMER_REAL
36 #include <sys/time.h>
37 #endif /* ITIMER_REAL */
38 #endif
39 #include <rx/xdr.h>
40 #include <afs/afsint.h>
41 #include <afs/assert.h>
42
43
44 #include <fcntl.h>
45
46 #ifndef AFS_NT40_ENV
47 #include <afs/osi_inode.h>
48 #endif
49
50 #include <afs/cmd.h>
51 #include <afs/afsutil.h>
52 #include <afs/fileutil.h>
53
54 #include "nfs.h"
55 #include "lwp.h"
56 #include "lock.h"
57 #include "ihandle.h"
58 #include "vnode.h"
59 #include "volume.h"
60 #include "partition.h"
61 #include "daemon_com.h"
62 #include "salvsync.h"
63 #ifdef AFS_NT40_ENV
64 #include <pthread.h>
65 #endif
66
67 int VolumeChanged; /* hack to make dir package happy */
68
69
70 #ifndef AFS_DEMAND_ATTACH_FS
71 int
72 main(int argc, char ** argv)
73 {
74     fprintf(stderr, "*** salvsync-debug is only supported for OpenAFS builds with the demand-attach fileserver extension\n");
75     return -1;
76 }
77 #else /* AFS_DEMAND_ATTACH_FS */
78
79 struct salv_state {
80     afs_uint32 prio;
81     afs_uint32 volume;
82     char partName[16];
83 };
84
85 struct state {
86     afs_int32 reason;
87     struct salv_state * sop;
88 };
89
90 static int common_prolog(struct cmd_syndesc *, struct state *);
91 static int common_salv_prolog(struct cmd_syndesc *, struct state *);
92
93 static int do_salvop(struct state *, afs_int32 command, SYNC_response * res);
94
95 static char * response_code_to_string(afs_int32);
96 static char * command_code_to_string(afs_int32);
97 static char * reason_code_to_string(afs_int32);
98 static char * program_type_to_string(afs_int32);
99 static char * state_code_to_string(afs_int32);
100
101
102 static int OpStats(struct cmd_syndesc * as, void * rock);
103 static int OpSalvage(struct cmd_syndesc * as, void * rock);
104 static int OpCancel(struct cmd_syndesc * as, void * rock);
105 static int OpCancelAll(struct cmd_syndesc * as, void * rock);
106 static int OpRaisePrio(struct cmd_syndesc * as, void * rock);
107 static int OpQuery(struct cmd_syndesc * as, void * rock);
108
109
110 #ifndef AFS_NT40_ENV
111 #include "AFS_component_version_number.c"
112 #endif
113 #define MAX_ARGS 128
114
115 #define COMMON_PARMS_OFFSET    13
116 #define COMMON_PARMS(ts) \
117     cmd_Seek(ts, COMMON_PARMS_OFFSET); \
118     cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
119     cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
120
121 #define COMMON_SALV_PARMS_OFFSET    10
122 #define COMMON_SALV_PARMS(ts) \
123     cmd_Seek(ts, COMMON_SALV_PARMS_OFFSET); \
124     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
125     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); \
126     cmd_AddParm(ts, "-priority", CMD_SINGLE, CMD_OPTIONAL, "priority")
127
128 #define SALV_PARMS_DECL(ts) \
129     COMMON_SALV_PARMS(ts); \
130     COMMON_PARMS(ts)
131
132 #define COMMON_PARMS_DECL(ts) \
133     COMMON_PARMS(ts)
134
135 int
136 main(int argc, char **argv)
137 {
138     struct cmd_syndesc *ts;
139     int err = 0;
140     int i;
141     extern char cml_version_number[];
142
143     /* Initialize directory paths */
144     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
145 #ifdef AFS_NT40_ENV
146         ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
147 #endif
148         fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
149                 argv[0]);
150         exit(2);
151     }
152
153
154     ts = cmd_CreateSyntax("stats", OpStats, NULL, "get salvageserver statistics (SALVSYNC_NOP opcode)");
155     COMMON_PARMS_DECL(ts);
156     cmd_CreateAlias(ts, "nop");
157
158     ts = cmd_CreateSyntax("salvage", OpSalvage, NULL, "schedule a salvage (SALVSYNC_SALVAGE opcode)");
159     SALV_PARMS_DECL(ts);
160
161     ts = cmd_CreateSyntax("cancel", OpCancel, NULL, "cancel a salvage (SALVSYNC_CANCEL opcode)");
162     SALV_PARMS_DECL(ts);
163
164     ts = cmd_CreateSyntax("raiseprio", OpRaisePrio, NULL, "raise a salvage priority (SALVSYNC_RAISEPRIO opcode)");
165     SALV_PARMS_DECL(ts);
166     cmd_CreateAlias(ts, "rp");
167
168     ts = cmd_CreateSyntax("query", OpQuery, NULL, "query salvage status (SALVSYNC_QUERY opcode)");
169     SALV_PARMS_DECL(ts);
170     cmd_CreateAlias(ts, "qry");
171
172     ts = cmd_CreateSyntax("kill", OpCancelAll, NULL, "cancel all scheduled salvages (SALVSYNC_CANCELALL opcode)");
173     COMMON_PARMS_DECL(ts);
174
175     err = cmd_Dispatch(argc, argv);
176     exit(err);
177 }
178
179 static int
180 common_prolog(struct cmd_syndesc * as, struct state * state)
181 {
182     register struct cmd_item *ti;
183
184 #ifdef AFS_NT40_ENV
185     if (afs_winsockInit() < 0) {
186         Exit(1);
187     }
188 #endif
189
190     VInitVolumePackage(debugUtility, 1, 1,
191                        DONT_CONNECT_FS, 0);
192     DInit(1);
193
194     if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) {  /* -reason */
195         state->reason = atoi(ti->data);
196     }
197     if ((ti = as->parms[COMMON_PARMS_OFFSET+1].items)) {        /* -programtype */
198         if (!strcmp(ti->data, "fileServer")) {
199             programType = fileServer;
200         } else if (!strcmp(ti->data, "volumeUtility")) {
201             programType = volumeUtility;
202         } else if (!strcmp(ti->data, "salvager")) {
203             programType = salvager;
204         } else if (!strcmp(ti->data, "salvageServer")) {
205             programType = salvageServer;
206         } else {
207             programType = (ProgramType) atoi(ti->data);
208         }
209     }
210
211     VConnectSALV();
212
213     return 0;
214 }
215
216 static int
217 common_salv_prolog(struct cmd_syndesc * as, struct state * state)
218 {
219     register struct cmd_item *ti;
220     char pname[100], *temp;
221
222     state->sop = (struct salv_state *) calloc(1, sizeof(struct salv_state));
223     assert(state->sop != NULL);
224
225     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET].items)) {     /* -volumeid */
226         state->sop->volume = atoi(ti->data);
227     } else {
228         fprintf(stderr, "required argument -volumeid not given\n");
229     }
230
231     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+1].items)) {   /* -partition */
232         strlcpy(state->sop->partName, ti->data, sizeof(state->sop->partName));
233     } else {
234         memset(state->sop->partName, 0, sizeof(state->sop->partName));
235     }
236
237     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+2].items)) {   /* -prio */
238         state->sop->prio = atoi(ti->data);
239     } else {
240         state->sop->prio = 0;
241     }
242
243     return 0;
244 }
245
246 static int
247 do_salvop(struct state * state, afs_int32 command, SYNC_response * res)
248 {
249     afs_int32 code;
250     SALVSYNC_response_hdr hdr_l, *hdr;
251     SYNC_response res_l;
252
253     if (!res) {
254         res = &res_l;
255         res->payload.len = sizeof(hdr_l);
256         res->payload.buf = hdr = &hdr_l;
257     } else {
258         hdr = (SALVSYNC_response_hdr *) res->payload.buf;
259     }
260
261     fprintf(stderr, "calling SALVSYNC_SalvageVolume with command code %d (%s)\n", 
262             command, command_code_to_string(command));
263
264     code = SALVSYNC_SalvageVolume(state->sop->volume,
265                                   state->sop->partName,
266                                   command,
267                                   state->reason,
268                                   state->sop->prio,
269                                   res);
270
271     switch (code) {
272     case SYNC_OK:
273     case SYNC_DENIED:
274         break;
275     default:
276         fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
277     }
278
279     fprintf(stderr, "SALVSYNC_SalvageVolume returned %d (%s)\n", code, response_code_to_string(code));
280     fprintf(stderr, "protocol response code was %d (%s)\n", 
281             res->hdr.response, response_code_to_string(res->hdr.response));
282     fprintf(stderr, "protocol reason code was %d (%s)\n", 
283             res->hdr.reason, reason_code_to_string(res->hdr.reason));
284
285     printf("state = {\n");
286     if (res->hdr.flags & SALVSYNC_FLAG_VOL_STATS_VALID) {
287         printf("\tstate = %d (%s)\n",
288                hdr->state, state_code_to_string(hdr->state));
289         printf("\tprio = %d\n", hdr->prio);
290     }
291     printf("\tsq_len = %d\n", hdr->sq_len);
292     printf("\tpq_len = %d\n", hdr->pq_len);
293     printf("}\n");
294
295     VDisconnectSALV();
296 }
297
298 static char *
299 response_code_to_string(afs_int32 response)
300 {
301     switch (response) {
302     case SYNC_OK:
303         return "SYNC_OK";
304     case SYNC_DENIED:
305         return "SYNC_DENIED";
306     case SYNC_COM_ERROR:
307         return "SYNC_COM_ERROR";
308     case SYNC_BAD_COMMAND:
309         return "SYNC_BAD_COMMAND";
310     case SYNC_FAILED:
311         return "SYNC_FAILED";
312     default:
313         return "**UNKNOWN**";
314     }
315 }
316
317 static char *
318 command_code_to_string(afs_int32 command)
319 {
320     switch (command) {
321     case SYNC_COM_CHANNEL_CLOSE:
322         return "SYNC_COM_CHANNEL_CLOSE";
323     case SALVSYNC_NOP:
324         return "SALVSYNC_NOP";
325     case SALVSYNC_SALVAGE:
326         return "SALVSYNC_SALVAGE";
327     case SALVSYNC_CANCEL:
328         return "SALVSYNC_CANCEL";
329     case SALVSYNC_RAISEPRIO:
330         return "SALVSYNC_RAISEPRIO";
331     case SALVSYNC_QUERY:
332         return "SALVSYNC_QUERY";
333     case SALVSYNC_CANCELALL:
334         return "SALVSYNC_CANCELLALL";
335     default:
336         return "**UNKNOWN**";
337     }
338 }
339
340 static char *
341 reason_code_to_string(afs_int32 reason)
342 {
343     switch (reason) {
344     case SALVSYNC_WHATEVER:
345         return "SALVSYNC_WHATEVER";
346     case SALVSYNC_ERROR:
347         return "SALVSYNC_ERROR";
348     case SALVSYNC_OPERATOR:
349         return "SALVSYNC_OPERATOR";
350     case SALVSYNC_SHUTDOWN:
351         return "SALVSYNC_SHUTDOWN";
352     case SALVSYNC_NEEDED:
353         return "SALVSYNC_NEEDED";
354     default:
355         return "**UNKNOWN**";
356     }
357 }
358
359 static char *
360 program_type_to_string(afs_int32 type)
361 {
362     switch ((ProgramType)type) {
363     case fileServer:
364         return "fileServer";
365     case volumeUtility:
366         return "volumeUtility";
367     case salvager:
368         return "salvager";
369     case salvageServer:
370         return "salvageServer";
371     default:
372         return "**UNKNOWN**";
373     }
374 }
375
376 static char *
377 state_code_to_string(afs_int32 state)
378 {
379     switch (state) {
380     case SALVSYNC_STATE_UNKNOWN:
381         return "SALVSYNC_STATE_UNKNOWN";
382     case SALVSYNC_STATE_QUEUED:
383         return "SALVSYNC_STATE_QUEUED";
384     case SALVSYNC_STATE_SALVAGING:
385         return "SALVSYNC_STATE_SALVAGING";
386     case SALVSYNC_STATE_ERROR:
387         return "SALVSYNC_STATE_ERROR";
388     case SALVSYNC_STATE_DONE:
389         return "SALVSYNC_STATE_DONE";
390     default:
391         return "**UNKNOWN**";
392     }
393 }
394
395 static int
396 OpStats(struct cmd_syndesc * as, void * rock)
397 {
398     struct state state;
399
400     common_prolog(as, &state);
401     common_salv_prolog(as, &state);
402
403     do_salvop(&state, SALVSYNC_NOP, NULL);
404
405     return 0;
406 }
407
408 static int
409 OpSalvage(struct cmd_syndesc * as, void * rock)
410 {
411     struct state state;
412
413     common_prolog(as, &state);
414     common_salv_prolog(as, &state);
415
416     do_salvop(&state, SALVSYNC_SALVAGE, NULL);
417
418     return 0;
419 }
420
421 static int
422 OpCancel(struct cmd_syndesc * as, void * rock)
423 {
424     struct state state;
425
426     common_prolog(as, &state);
427     common_salv_prolog(as, &state);
428
429     do_salvop(&state, SALVSYNC_CANCEL, NULL);
430
431     return 0;
432 }
433
434 static int
435 OpCancelAll(struct cmd_syndesc * as, void * rock)
436 {
437     struct state state;
438
439     common_prolog(as, &state);
440     common_salv_prolog(as, &state);
441
442     do_salvop(&state, SALVSYNC_CANCELALL, NULL);
443
444     return 0;
445 }
446
447 static int
448 OpRaisePrio(struct cmd_syndesc * as, void * rock)
449 {
450     struct state state;
451
452     common_prolog(as, &state);
453     common_salv_prolog(as, &state);
454
455     do_salvop(&state, SALVSYNC_RAISEPRIO, NULL);
456
457     return 0;
458 }
459
460 static int
461 OpQuery(struct cmd_syndesc * as, void * rock)
462 {
463     struct state state;
464
465     common_prolog(as, &state);
466     common_salv_prolog(as, &state);
467
468     do_salvop(&state, SALVSYNC_QUERY, NULL);
469
470     return 0;
471 }
472
473 #endif /* AFS_DEMAND_ATTACH_FS */