Remove NINTERFACE define
[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 #include <roken.h>
22
23 #ifdef AFS_NT40_ENV
24 #include <WINNT/afsevent.h>
25 #endif
26
27 #include <rx/xdr.h>
28 #include <afs/afsint.h>
29 #include <afs/afs_assert.h>
30 #include <afs/dir.h>
31
32 #ifndef AFS_NT40_ENV
33 #include <afs/osi_inode.h>
34 #endif
35
36 #include <afs/cmd.h>
37 #include <afs/afsutil.h>
38 #include <afs/fileutil.h>
39
40 #include <afs/nfs.h>
41 #include <lwp.h>
42 #include <lock.h>
43 #include <afs/ihandle.h>
44 #include <afs/vnode.h>
45 #include <afs/volume.h>
46 #include <afs/partition.h>
47 #include <afs/daemon_com.h>
48 #include <afs/salvsync.h>
49 #ifdef AFS_NT40_ENV
50 #include <pthread.h>
51 #endif
52
53 int VolumeChanged; /* hack to make dir package happy */
54
55
56 #ifndef AFS_DEMAND_ATTACH_FS
57 int
58 main(int argc, char ** argv)
59 {
60     fprintf(stderr, "*** salvsync-debug is only supported for OpenAFS builds with the demand-attach fileserver extension\n");
61     return -1;
62 }
63 #else /* AFS_DEMAND_ATTACH_FS */
64
65 struct salv_state {
66     afs_uint32 prio;
67     afs_uint32 volume;
68     char partName[16];
69 };
70
71 struct fssync_state {
72     afs_int32 reason;
73     struct salv_state * sop;
74 };
75
76 static int common_prolog(struct cmd_syndesc *, struct fssync_state *);
77 static int common_salv_prolog(struct cmd_syndesc *, struct fssync_state *);
78
79 static int do_salvop(struct fssync_state *, afs_int32 command, SYNC_response * res);
80
81 static char * response_code_to_string(afs_int32);
82 static char * command_code_to_string(afs_int32);
83 static char * reason_code_to_string(afs_int32);
84 static char * state_code_to_string(afs_int32);
85
86
87 static int OpStats(struct cmd_syndesc * as, void * rock);
88 static int OpSalvage(struct cmd_syndesc * as, void * rock);
89 static int OpCancel(struct cmd_syndesc * as, void * rock);
90 static int OpCancelAll(struct cmd_syndesc * as, void * rock);
91 static int OpRaisePrio(struct cmd_syndesc * as, void * rock);
92 static int OpQuery(struct cmd_syndesc * as, void * rock);
93
94
95 #ifndef AFS_NT40_ENV
96 #include "AFS_component_version_number.c"
97 #endif
98 #define MAX_ARGS 128
99
100 #define COMMON_PARMS_OFFSET    13
101 #define COMMON_PARMS(ts) \
102     cmd_Seek(ts, COMMON_PARMS_OFFSET); \
103     cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
104     cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
105
106 #define COMMON_SALV_PARMS_OFFSET    10
107 #define COMMON_SALV_PARMS(ts) \
108     cmd_Seek(ts, COMMON_SALV_PARMS_OFFSET); \
109     cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
110     cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); \
111     cmd_AddParm(ts, "-priority", CMD_SINGLE, CMD_OPTIONAL, "priority")
112
113 #define SALV_PARMS_DECL(ts) \
114     COMMON_SALV_PARMS(ts); \
115     COMMON_PARMS(ts)
116
117 #define COMMON_PARMS_DECL(ts) \
118     COMMON_PARMS(ts)
119
120 int
121 main(int argc, char **argv)
122 {
123     struct cmd_syndesc *ts;
124     int err = 0;
125
126     /* Initialize directory paths */
127     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
128 #ifdef AFS_NT40_ENV
129         ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
130 #endif
131         fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
132                 argv[0]);
133         exit(2);
134     }
135
136
137     ts = cmd_CreateSyntax("stats", OpStats, NULL, "get salvageserver statistics (SALVSYNC_NOP opcode)");
138     COMMON_PARMS_DECL(ts);
139     cmd_CreateAlias(ts, "nop");
140
141     ts = cmd_CreateSyntax("salvage", OpSalvage, NULL, "schedule a salvage (SALVSYNC_SALVAGE opcode)");
142     SALV_PARMS_DECL(ts);
143
144     ts = cmd_CreateSyntax("cancel", OpCancel, NULL, "cancel a salvage (SALVSYNC_CANCEL opcode)");
145     SALV_PARMS_DECL(ts);
146
147     ts = cmd_CreateSyntax("raiseprio", OpRaisePrio, NULL, "raise a salvage priority (SALVSYNC_RAISEPRIO opcode)");
148     SALV_PARMS_DECL(ts);
149     cmd_CreateAlias(ts, "rp");
150
151     ts = cmd_CreateSyntax("query", OpQuery, NULL, "query salvage status (SALVSYNC_QUERY opcode)");
152     SALV_PARMS_DECL(ts);
153     cmd_CreateAlias(ts, "qry");
154
155     ts = cmd_CreateSyntax("kill", OpCancelAll, NULL, "cancel all scheduled salvages (SALVSYNC_CANCELALL opcode)");
156     COMMON_PARMS_DECL(ts);
157
158     err = cmd_Dispatch(argc, argv);
159     exit(err);
160 }
161
162 static int
163 common_prolog(struct cmd_syndesc * as, struct fssync_state * state)
164 {
165     struct cmd_item *ti;
166     VolumePackageOptions opts;
167
168 #ifdef AFS_NT40_ENV
169     if (afs_winsockInit() < 0) {
170         Exit(1);
171     }
172 #endif
173
174     VOptDefaults(debugUtility, &opts);
175     if (VInitVolumePackage2(debugUtility, &opts)) {
176         /* VInitVolumePackage2 can fail on e.g. partition attachment errors,
177          * but we don't really care, since all we're doing is trying to use
178          * SALVSYNC */
179         fprintf(stderr, "errors encountered initializing volume package, but "
180                         "trying to continue anyway\n");
181     }
182     DInit(1);
183
184     if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) {  /* -reason */
185         state->reason = atoi(ti->data);
186     } else {
187         state->reason = SALVSYNC_REASON_WHATEVER;
188     }
189
190     if ((ti = as->parms[COMMON_PARMS_OFFSET+1].items)) {        /* -programtype */
191         if (!strcmp(ti->data, "fileServer")) {
192             programType = fileServer;
193         } else if (!strcmp(ti->data, "volumeUtility")) {
194             programType = volumeUtility;
195         } else if (!strcmp(ti->data, "salvager")) {
196             programType = salvager;
197         } else if (!strcmp(ti->data, "salvageServer")) {
198             programType = salvageServer;
199         } else if (!strcmp(ti->data, "volumeServer")) {
200             programType = volumeServer;
201         } else if (!strcmp(ti->data, "volumeSalvager")) {
202             programType = volumeSalvager;
203         } else {
204             programType = (ProgramType) atoi(ti->data);
205         }
206     }
207
208     VConnectSALV();
209
210     return 0;
211 }
212
213 static int
214 common_salv_prolog(struct cmd_syndesc * as, struct fssync_state * state)
215 {
216     struct cmd_item *ti;
217
218     state->sop = (struct salv_state *) calloc(1, sizeof(struct salv_state));
219     assert(state->sop != NULL);
220
221     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET].items)) {     /* -volumeid */
222         state->sop->volume = atoi(ti->data);
223     } else {
224         fprintf(stderr, "required argument -volumeid not given\n");
225     }
226
227     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+1].items)) {   /* -partition */
228         strlcpy(state->sop->partName, ti->data, sizeof(state->sop->partName));
229     } else {
230         memset(state->sop->partName, 0, sizeof(state->sop->partName));
231     }
232
233     if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+2].items)) {   /* -prio */
234         state->sop->prio = atoi(ti->data);
235     } else {
236         state->sop->prio = 0;
237     }
238
239     return 0;
240 }
241
242 static int
243 do_salvop(struct fssync_state * state, afs_int32 command, SYNC_response * res)
244 {
245     afs_int32 code;
246     SALVSYNC_response_hdr hdr_l, *hdr;
247     SYNC_response res_l;
248
249     if (!res) {
250         res = &res_l;
251         res->payload.len = sizeof(hdr_l);
252         res->payload.buf = hdr = &hdr_l;
253     } else {
254         hdr = (SALVSYNC_response_hdr *) res->payload.buf;
255     }
256
257     fprintf(stderr, "calling SALVSYNC_SalvageVolume with command code %d (%s)\n",
258             command, command_code_to_string(command));
259
260     code = SALVSYNC_SalvageVolume(state->sop->volume,
261                                   state->sop->partName,
262                                   command,
263                                   state->reason,
264                                   state->sop->prio,
265                                   res);
266
267     switch (code) {
268     case SYNC_OK:
269     case SYNC_DENIED:
270         break;
271     default:
272         fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
273     }
274
275     fprintf(stderr, "SALVSYNC_SalvageVolume returned %d (%s)\n", code, response_code_to_string(code));
276     fprintf(stderr, "protocol response code was %d (%s)\n",
277             res->hdr.response, response_code_to_string(res->hdr.response));
278     fprintf(stderr, "protocol reason code was %d (%s)\n",
279             res->hdr.reason, reason_code_to_string(res->hdr.reason));
280
281     printf("state = {\n");
282     if (res->hdr.flags & SALVSYNC_FLAG_VOL_STATS_VALID) {
283         printf("\tstate = %d (%s)\n",
284                hdr->state, state_code_to_string(hdr->state));
285         printf("\tprio = %d\n", hdr->prio);
286     }
287     printf("\tsq_len = %d\n", hdr->sq_len);
288     printf("\tpq_len = %d\n", hdr->pq_len);
289     printf("}\n");
290
291     VDisconnectSALV();
292
293     return 0;
294 }
295
296 static char *
297 response_code_to_string(afs_int32 response)
298 {
299     switch (response) {
300     case SYNC_OK:
301         return "SYNC_OK";
302     case SYNC_DENIED:
303         return "SYNC_DENIED";
304     case SYNC_COM_ERROR:
305         return "SYNC_COM_ERROR";
306     case SYNC_BAD_COMMAND:
307         return "SYNC_BAD_COMMAND";
308     case SYNC_FAILED:
309         return "SYNC_FAILED";
310     default:
311         return "**UNKNOWN**";
312     }
313 }
314
315 static char *
316 command_code_to_string(afs_int32 command)
317 {
318     switch (command) {
319     case SYNC_COM_CHANNEL_CLOSE:
320         return "SYNC_COM_CHANNEL_CLOSE";
321     case SALVSYNC_NOP:
322         return "SALVSYNC_NOP";
323     case SALVSYNC_SALVAGE:
324         return "SALVSYNC_SALVAGE";
325     case SALVSYNC_CANCEL:
326         return "SALVSYNC_CANCEL";
327     case SALVSYNC_RAISEPRIO:
328         return "SALVSYNC_RAISEPRIO";
329     case SALVSYNC_QUERY:
330         return "SALVSYNC_QUERY";
331     case SALVSYNC_CANCELALL:
332         return "SALVSYNC_CANCELLALL";
333     default:
334         return "**UNKNOWN**";
335     }
336 }
337
338 static char *
339 reason_code_to_string(afs_int32 reason)
340 {
341     switch (reason) {
342     case SALVSYNC_WHATEVER:
343         return "SALVSYNC_WHATEVER";
344     case SALVSYNC_ERROR:
345         return "SALVSYNC_ERROR";
346     case SALVSYNC_OPERATOR:
347         return "SALVSYNC_OPERATOR";
348     case SALVSYNC_SHUTDOWN:
349         return "SALVSYNC_SHUTDOWN";
350     case SALVSYNC_NEEDED:
351         return "SALVSYNC_NEEDED";
352     default:
353         return "**UNKNOWN**";
354     }
355 }
356
357 #if 0
358 static char *
359 program_type_to_string(afs_int32 type)
360 {
361     switch ((ProgramType)type) {
362     case fileServer:
363         return "fileServer";
364     case volumeUtility:
365         return "volumeUtility";
366     case salvager:
367         return "salvager";
368     case salvageServer:
369         return "salvageServer";
370     default:
371         return "**UNKNOWN**";
372     }
373 }
374 #endif
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 fssync_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 fssync_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 fssync_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 fssync_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 fssync_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 fssync_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 */