Expand ProgramType enumeration
[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 #include <afs/dir.h>
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 <afs/nfs.h>
55 #include <lwp.h>
56 #include <lock.h>
57 #include <afs/ihandle.h>
58 #include <afs/vnode.h>
59 #include <afs/volume.h>
60 #include <afs/partition.h>
61 #include <afs/daemon_com.h>
62 #include <afs/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 * state_code_to_string(afs_int32);
99
100
101 static int OpStats(struct cmd_syndesc * as, void * rock);
102 static int OpSalvage(struct cmd_syndesc * as, void * rock);
103 static int OpCancel(struct cmd_syndesc * as, void * rock);
104 static int OpCancelAll(struct cmd_syndesc * as, void * rock);
105 static int OpRaisePrio(struct cmd_syndesc * as, void * rock);
106 static int OpQuery(struct cmd_syndesc * as, void * rock);
107
108
109 #ifndef AFS_NT40_ENV
110 #include "AFS_component_version_number.c"
111 #endif
112 #define MAX_ARGS 128
113
114 #define COMMON_PARMS_OFFSET    13
115 #define COMMON_PARMS(ts) \
116     cmd_Seek(ts, COMMON_PARMS_OFFSET); \
117     cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
118     cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
119
120 #define COMMON_SALV_PARMS_OFFSET    10
121 #define COMMON_SALV_PARMS(ts) \
122     cmd_Seek(ts, COMMON_SALV_PARMS_OFFSET); \
123     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
124     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); \
125     cmd_AddParm(ts, "-priority", CMD_SINGLE, CMD_OPTIONAL, "priority")
126
127 #define SALV_PARMS_DECL(ts) \
128     COMMON_SALV_PARMS(ts); \
129     COMMON_PARMS(ts)
130
131 #define COMMON_PARMS_DECL(ts) \
132     COMMON_PARMS(ts)
133
134 int
135 main(int argc, char **argv)
136 {
137     struct cmd_syndesc *ts;
138     int err = 0;
139
140     /* Initialize directory paths */
141     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
142 #ifdef AFS_NT40_ENV
143         ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
144 #endif
145         fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
146                 argv[0]);
147         exit(2);
148     }
149
150
151     ts = cmd_CreateSyntax("stats", OpStats, NULL, "get salvageserver statistics (SALVSYNC_NOP opcode)");
152     COMMON_PARMS_DECL(ts);
153     cmd_CreateAlias(ts, "nop");
154
155     ts = cmd_CreateSyntax("salvage", OpSalvage, NULL, "schedule a salvage (SALVSYNC_SALVAGE opcode)");
156     SALV_PARMS_DECL(ts);
157
158     ts = cmd_CreateSyntax("cancel", OpCancel, NULL, "cancel a salvage (SALVSYNC_CANCEL opcode)");
159     SALV_PARMS_DECL(ts);
160
161     ts = cmd_CreateSyntax("raiseprio", OpRaisePrio, NULL, "raise a salvage priority (SALVSYNC_RAISEPRIO opcode)");
162     SALV_PARMS_DECL(ts);
163     cmd_CreateAlias(ts, "rp");
164
165     ts = cmd_CreateSyntax("query", OpQuery, NULL, "query salvage status (SALVSYNC_QUERY opcode)");
166     SALV_PARMS_DECL(ts);
167     cmd_CreateAlias(ts, "qry");
168
169     ts = cmd_CreateSyntax("kill", OpCancelAll, NULL, "cancel all scheduled salvages (SALVSYNC_CANCELALL opcode)");
170     COMMON_PARMS_DECL(ts);
171
172     err = cmd_Dispatch(argc, argv);
173     exit(err);
174 }
175
176 static int
177 common_prolog(struct cmd_syndesc * as, struct state * state)
178 {
179     register struct cmd_item *ti;
180     VolumePackageOptions opts;
181
182 #ifdef AFS_NT40_ENV
183     if (afs_winsockInit() < 0) {
184         Exit(1);
185     }
186 #endif
187
188     VOptDefaults(debugUtility, &opts);
189     VInitVolumePackage2(debugUtility, &opts);
190     DInit(1);
191
192     if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) {  /* -reason */
193         state->reason = atoi(ti->data);
194     }
195     if ((ti = as->parms[COMMON_PARMS_OFFSET+1].items)) {        /* -programtype */
196         if (!strcmp(ti->data, "fileServer")) {
197             programType = fileServer;
198         } else if (!strcmp(ti->data, "volumeUtility")) {
199             programType = volumeUtility;
200         } else if (!strcmp(ti->data, "salvager")) {
201             programType = salvager;
202         } else if (!strcmp(ti->data, "salvageServer")) {
203             programType = salvageServer;
204         } else if (!strcmp(ti->data, "volumeServer")) {
205             programType = volumeServer;
206         } else if (!strcmp(ti->data, "volumeSalvager")) {
207             programType = volumeSalvager;
208         } else {
209             programType = (ProgramType) atoi(ti->data);
210         }
211     }
212
213     VConnectSALV();
214
215     return 0;
216 }
217
218 static int
219 common_salv_prolog(struct cmd_syndesc * as, struct state * state)
220 {
221     register struct cmd_item *ti;
222
223     state->sop = (struct salv_state *) calloc(1, sizeof(struct salv_state));
224     assert(state->sop != NULL);
225
226     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET].items)) {     /* -volumeid */
227         state->sop->volume = atoi(ti->data);
228     } else {
229         fprintf(stderr, "required argument -volumeid not given\n");
230     }
231
232     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+1].items)) {   /* -partition */
233         strlcpy(state->sop->partName, ti->data, sizeof(state->sop->partName));
234     } else {
235         memset(state->sop->partName, 0, sizeof(state->sop->partName));
236     }
237
238     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+2].items)) {   /* -prio */
239         state->sop->prio = atoi(ti->data);
240     } else {
241         state->sop->prio = 0;
242     }
243
244     return 0;
245 }
246
247 static int
248 do_salvop(struct state * state, afs_int32 command, SYNC_response * res)
249 {
250     afs_int32 code;
251     SALVSYNC_response_hdr hdr_l, *hdr;
252     SYNC_response res_l;
253
254     if (!res) {
255         res = &res_l;
256         res->payload.len = sizeof(hdr_l);
257         res->payload.buf = hdr = &hdr_l;
258     } else {
259         hdr = (SALVSYNC_response_hdr *) res->payload.buf;
260     }
261
262     fprintf(stderr, "calling SALVSYNC_SalvageVolume with command code %d (%s)\n", 
263             command, command_code_to_string(command));
264
265     code = SALVSYNC_SalvageVolume(state->sop->volume,
266                                   state->sop->partName,
267                                   command,
268                                   state->reason,
269                                   state->sop->prio,
270                                   res);
271
272     switch (code) {
273     case SYNC_OK:
274     case SYNC_DENIED:
275         break;
276     default:
277         fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
278     }
279
280     fprintf(stderr, "SALVSYNC_SalvageVolume returned %d (%s)\n", code, response_code_to_string(code));
281     fprintf(stderr, "protocol response code was %d (%s)\n", 
282             res->hdr.response, response_code_to_string(res->hdr.response));
283     fprintf(stderr, "protocol reason code was %d (%s)\n", 
284             res->hdr.reason, reason_code_to_string(res->hdr.reason));
285
286     printf("state = {\n");
287     if (res->hdr.flags & SALVSYNC_FLAG_VOL_STATS_VALID) {
288         printf("\tstate = %d (%s)\n",
289                hdr->state, state_code_to_string(hdr->state));
290         printf("\tprio = %d\n", hdr->prio);
291     }
292     printf("\tsq_len = %d\n", hdr->sq_len);
293     printf("\tpq_len = %d\n", hdr->pq_len);
294     printf("}\n");
295
296     VDisconnectSALV();
297
298     return 0;
299 }
300
301 static char *
302 response_code_to_string(afs_int32 response)
303 {
304     switch (response) {
305     case SYNC_OK:
306         return "SYNC_OK";
307     case SYNC_DENIED:
308         return "SYNC_DENIED";
309     case SYNC_COM_ERROR:
310         return "SYNC_COM_ERROR";
311     case SYNC_BAD_COMMAND:
312         return "SYNC_BAD_COMMAND";
313     case SYNC_FAILED:
314         return "SYNC_FAILED";
315     default:
316         return "**UNKNOWN**";
317     }
318 }
319
320 static char *
321 command_code_to_string(afs_int32 command)
322 {
323     switch (command) {
324     case SYNC_COM_CHANNEL_CLOSE:
325         return "SYNC_COM_CHANNEL_CLOSE";
326     case SALVSYNC_NOP:
327         return "SALVSYNC_NOP";
328     case SALVSYNC_SALVAGE:
329         return "SALVSYNC_SALVAGE";
330     case SALVSYNC_CANCEL:
331         return "SALVSYNC_CANCEL";
332     case SALVSYNC_RAISEPRIO:
333         return "SALVSYNC_RAISEPRIO";
334     case SALVSYNC_QUERY:
335         return "SALVSYNC_QUERY";
336     case SALVSYNC_CANCELALL:
337         return "SALVSYNC_CANCELLALL";
338     default:
339         return "**UNKNOWN**";
340     }
341 }
342
343 static char *
344 reason_code_to_string(afs_int32 reason)
345 {
346     switch (reason) {
347     case SALVSYNC_WHATEVER:
348         return "SALVSYNC_WHATEVER";
349     case SALVSYNC_ERROR:
350         return "SALVSYNC_ERROR";
351     case SALVSYNC_OPERATOR:
352         return "SALVSYNC_OPERATOR";
353     case SALVSYNC_SHUTDOWN:
354         return "SALVSYNC_SHUTDOWN";
355     case SALVSYNC_NEEDED:
356         return "SALVSYNC_NEEDED";
357     default:
358         return "**UNKNOWN**";
359     }
360 }
361
362 #if 0
363 static char *
364 program_type_to_string(afs_int32 type)
365 {
366     switch ((ProgramType)type) {
367     case fileServer:
368         return "fileServer";
369     case volumeUtility:
370         return "volumeUtility";
371     case salvager:
372         return "salvager";
373     case salvageServer:
374         return "salvageServer";
375     default:
376         return "**UNKNOWN**";
377     }
378 }
379 #endif
380
381 static char *
382 state_code_to_string(afs_int32 state)
383 {
384     switch (state) {
385     case SALVSYNC_STATE_UNKNOWN:
386         return "SALVSYNC_STATE_UNKNOWN";
387     case SALVSYNC_STATE_QUEUED:
388         return "SALVSYNC_STATE_QUEUED";
389     case SALVSYNC_STATE_SALVAGING:
390         return "SALVSYNC_STATE_SALVAGING";
391     case SALVSYNC_STATE_ERROR:
392         return "SALVSYNC_STATE_ERROR";
393     case SALVSYNC_STATE_DONE:
394         return "SALVSYNC_STATE_DONE";
395     default:
396         return "**UNKNOWN**";
397     }
398 }
399
400 static int
401 OpStats(struct cmd_syndesc * as, void * rock)
402 {
403     struct state state;
404
405     common_prolog(as, &state);
406     common_salv_prolog(as, &state);
407
408     do_salvop(&state, SALVSYNC_NOP, NULL);
409
410     return 0;
411 }
412
413 static int
414 OpSalvage(struct cmd_syndesc * as, void * rock)
415 {
416     struct state state;
417
418     common_prolog(as, &state);
419     common_salv_prolog(as, &state);
420
421     do_salvop(&state, SALVSYNC_SALVAGE, NULL);
422
423     return 0;
424 }
425
426 static int
427 OpCancel(struct cmd_syndesc * as, void * rock)
428 {
429     struct state state;
430
431     common_prolog(as, &state);
432     common_salv_prolog(as, &state);
433
434     do_salvop(&state, SALVSYNC_CANCEL, NULL);
435
436     return 0;
437 }
438
439 static int
440 OpCancelAll(struct cmd_syndesc * as, void * rock)
441 {
442     struct state state;
443
444     common_prolog(as, &state);
445     common_salv_prolog(as, &state);
446
447     do_salvop(&state, SALVSYNC_CANCELALL, NULL);
448
449     return 0;
450 }
451
452 static int
453 OpRaisePrio(struct cmd_syndesc * as, void * rock)
454 {
455     struct state state;
456
457     common_prolog(as, &state);
458     common_salv_prolog(as, &state);
459
460     do_salvop(&state, SALVSYNC_RAISEPRIO, NULL);
461
462     return 0;
463 }
464
465 static int
466 OpQuery(struct cmd_syndesc * as, void * rock)
467 {
468     struct state state;
469
470     common_prolog(as, &state);
471     common_salv_prolog(as, &state);
472
473     do_salvop(&state, SALVSYNC_QUERY, NULL);
474
475     return 0;
476 }
477
478 #endif /* AFS_DEMAND_ATTACH_FS */