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