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