2 * Copyright 2006, Sine Nomine Associates and others.
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
10 /* Main program file. Define globals. */
18 #include <afsconfig.h>
19 #include <afs/param.h>
30 #include <WINNT/afsevent.h>
32 #include <sys/param.h>
36 #endif /* ITIMER_REAL */
42 #include <afs/afsint.h>
43 #include <afs/afs_assert.h>
49 #include <afs/osi_inode.h>
53 #include <afs/afsutil.h>
54 #include <afs/fileutil.h>
59 #include <afs/ihandle.h>
60 #include <afs/vnode.h>
61 #include <afs/volume.h>
62 #include <afs/partition.h>
63 #include <afs/daemon_com.h>
64 #include <afs/salvsync.h>
69 int VolumeChanged; /* hack to make dir package happy */
72 #ifndef AFS_DEMAND_ATTACH_FS
74 main(int argc, char ** argv)
76 fprintf(stderr, "*** salvsync-debug is only supported for OpenAFS builds with the demand-attach fileserver extension\n");
79 #else /* AFS_DEMAND_ATTACH_FS */
89 struct salv_state * sop;
92 static int common_prolog(struct cmd_syndesc *, struct state *);
93 static int common_salv_prolog(struct cmd_syndesc *, struct state *);
95 static int do_salvop(struct state *, afs_int32 command, SYNC_response * res);
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 * state_code_to_string(afs_int32);
103 static int OpStats(struct cmd_syndesc * as, void * rock);
104 static int OpSalvage(struct cmd_syndesc * as, void * rock);
105 static int OpCancel(struct cmd_syndesc * as, void * rock);
106 static int OpCancelAll(struct cmd_syndesc * as, void * rock);
107 static int OpRaisePrio(struct cmd_syndesc * as, void * rock);
108 static int OpQuery(struct cmd_syndesc * as, void * rock);
112 #include "AFS_component_version_number.c"
116 #define COMMON_PARMS_OFFSET 13
117 #define COMMON_PARMS(ts) \
118 cmd_Seek(ts, COMMON_PARMS_OFFSET); \
119 cmd_AddParm(ts, "-reason", CMD_SINGLE, CMD_OPTIONAL, "sync protocol reason code"); \
120 cmd_AddParm(ts, "-programtype", CMD_SINGLE, CMD_OPTIONAL, "program type code")
122 #define COMMON_SALV_PARMS_OFFSET 10
123 #define COMMON_SALV_PARMS(ts) \
124 cmd_Seek(ts, COMMON_SALV_PARMS_OFFSET); \
125 cmd_AddParm(ts, "-volumeid", CMD_SINGLE, 0, "volume id"); \
126 cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name"); \
127 cmd_AddParm(ts, "-priority", CMD_SINGLE, CMD_OPTIONAL, "priority")
129 #define SALV_PARMS_DECL(ts) \
130 COMMON_SALV_PARMS(ts); \
133 #define COMMON_PARMS_DECL(ts) \
137 main(int argc, char **argv)
139 struct cmd_syndesc *ts;
142 /* Initialize directory paths */
143 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
145 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
147 fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
153 ts = cmd_CreateSyntax("stats", OpStats, NULL, "get salvageserver statistics (SALVSYNC_NOP opcode)");
154 COMMON_PARMS_DECL(ts);
155 cmd_CreateAlias(ts, "nop");
157 ts = cmd_CreateSyntax("salvage", OpSalvage, NULL, "schedule a salvage (SALVSYNC_SALVAGE opcode)");
160 ts = cmd_CreateSyntax("cancel", OpCancel, NULL, "cancel a salvage (SALVSYNC_CANCEL opcode)");
163 ts = cmd_CreateSyntax("raiseprio", OpRaisePrio, NULL, "raise a salvage priority (SALVSYNC_RAISEPRIO opcode)");
165 cmd_CreateAlias(ts, "rp");
167 ts = cmd_CreateSyntax("query", OpQuery, NULL, "query salvage status (SALVSYNC_QUERY opcode)");
169 cmd_CreateAlias(ts, "qry");
171 ts = cmd_CreateSyntax("kill", OpCancelAll, NULL, "cancel all scheduled salvages (SALVSYNC_CANCELALL opcode)");
172 COMMON_PARMS_DECL(ts);
174 err = cmd_Dispatch(argc, argv);
179 common_prolog(struct cmd_syndesc * as, struct state * state)
182 VolumePackageOptions opts;
185 if (afs_winsockInit() < 0) {
190 VOptDefaults(debugUtility, &opts);
191 if (VInitVolumePackage2(debugUtility, &opts)) {
192 /* VInitVolumePackage2 can fail on e.g. partition attachment errors,
193 * but we don't really care, since all we're doing is trying to use
195 fprintf(stderr, "errors encountered initializing volume package, but "
196 "trying to continue anyway\n");
200 if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) { /* -reason */
201 state->reason = atoi(ti->data);
203 state->reason = SALVSYNC_REASON_WHATEVER;
206 if ((ti = as->parms[COMMON_PARMS_OFFSET+1].items)) { /* -programtype */
207 if (!strcmp(ti->data, "fileServer")) {
208 programType = fileServer;
209 } else if (!strcmp(ti->data, "volumeUtility")) {
210 programType = volumeUtility;
211 } else if (!strcmp(ti->data, "salvager")) {
212 programType = salvager;
213 } else if (!strcmp(ti->data, "salvageServer")) {
214 programType = salvageServer;
215 } else if (!strcmp(ti->data, "volumeServer")) {
216 programType = volumeServer;
217 } else if (!strcmp(ti->data, "volumeSalvager")) {
218 programType = volumeSalvager;
220 programType = (ProgramType) atoi(ti->data);
230 common_salv_prolog(struct cmd_syndesc * as, struct state * state)
234 state->sop = (struct salv_state *) calloc(1, sizeof(struct salv_state));
235 assert(state->sop != NULL);
237 if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET].items)) { /* -volumeid */
238 state->sop->volume = atoi(ti->data);
240 fprintf(stderr, "required argument -volumeid not given\n");
243 if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+1].items)) { /* -partition */
244 strlcpy(state->sop->partName, ti->data, sizeof(state->sop->partName));
246 memset(state->sop->partName, 0, sizeof(state->sop->partName));
249 if ((ti = as->parms[COMMON_SALV_PARMS_OFFSET+2].items)) { /* -prio */
250 state->sop->prio = atoi(ti->data);
252 state->sop->prio = 0;
259 do_salvop(struct state * state, afs_int32 command, SYNC_response * res)
262 SALVSYNC_response_hdr hdr_l, *hdr;
267 res->payload.len = sizeof(hdr_l);
268 res->payload.buf = hdr = &hdr_l;
270 hdr = (SALVSYNC_response_hdr *) res->payload.buf;
273 fprintf(stderr, "calling SALVSYNC_SalvageVolume with command code %d (%s)\n",
274 command, command_code_to_string(command));
276 code = SALVSYNC_SalvageVolume(state->sop->volume,
277 state->sop->partName,
288 fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
291 fprintf(stderr, "SALVSYNC_SalvageVolume returned %d (%s)\n", code, response_code_to_string(code));
292 fprintf(stderr, "protocol response code was %d (%s)\n",
293 res->hdr.response, response_code_to_string(res->hdr.response));
294 fprintf(stderr, "protocol reason code was %d (%s)\n",
295 res->hdr.reason, reason_code_to_string(res->hdr.reason));
297 printf("state = {\n");
298 if (res->hdr.flags & SALVSYNC_FLAG_VOL_STATS_VALID) {
299 printf("\tstate = %d (%s)\n",
300 hdr->state, state_code_to_string(hdr->state));
301 printf("\tprio = %d\n", hdr->prio);
303 printf("\tsq_len = %d\n", hdr->sq_len);
304 printf("\tpq_len = %d\n", hdr->pq_len);
313 response_code_to_string(afs_int32 response)
319 return "SYNC_DENIED";
321 return "SYNC_COM_ERROR";
322 case SYNC_BAD_COMMAND:
323 return "SYNC_BAD_COMMAND";
325 return "SYNC_FAILED";
327 return "**UNKNOWN**";
332 command_code_to_string(afs_int32 command)
335 case SYNC_COM_CHANNEL_CLOSE:
336 return "SYNC_COM_CHANNEL_CLOSE";
338 return "SALVSYNC_NOP";
339 case SALVSYNC_SALVAGE:
340 return "SALVSYNC_SALVAGE";
341 case SALVSYNC_CANCEL:
342 return "SALVSYNC_CANCEL";
343 case SALVSYNC_RAISEPRIO:
344 return "SALVSYNC_RAISEPRIO";
346 return "SALVSYNC_QUERY";
347 case SALVSYNC_CANCELALL:
348 return "SALVSYNC_CANCELLALL";
350 return "**UNKNOWN**";
355 reason_code_to_string(afs_int32 reason)
358 case SALVSYNC_WHATEVER:
359 return "SALVSYNC_WHATEVER";
361 return "SALVSYNC_ERROR";
362 case SALVSYNC_OPERATOR:
363 return "SALVSYNC_OPERATOR";
364 case SALVSYNC_SHUTDOWN:
365 return "SALVSYNC_SHUTDOWN";
366 case SALVSYNC_NEEDED:
367 return "SALVSYNC_NEEDED";
369 return "**UNKNOWN**";
375 program_type_to_string(afs_int32 type)
377 switch ((ProgramType)type) {
381 return "volumeUtility";
385 return "salvageServer";
387 return "**UNKNOWN**";
393 state_code_to_string(afs_int32 state)
396 case SALVSYNC_STATE_UNKNOWN:
397 return "SALVSYNC_STATE_UNKNOWN";
398 case SALVSYNC_STATE_QUEUED:
399 return "SALVSYNC_STATE_QUEUED";
400 case SALVSYNC_STATE_SALVAGING:
401 return "SALVSYNC_STATE_SALVAGING";
402 case SALVSYNC_STATE_ERROR:
403 return "SALVSYNC_STATE_ERROR";
404 case SALVSYNC_STATE_DONE:
405 return "SALVSYNC_STATE_DONE";
407 return "**UNKNOWN**";
412 OpStats(struct cmd_syndesc * as, void * rock)
416 common_prolog(as, &state);
417 common_salv_prolog(as, &state);
419 do_salvop(&state, SALVSYNC_NOP, NULL);
425 OpSalvage(struct cmd_syndesc * as, void * rock)
429 common_prolog(as, &state);
430 common_salv_prolog(as, &state);
432 do_salvop(&state, SALVSYNC_SALVAGE, NULL);
438 OpCancel(struct cmd_syndesc * as, void * rock)
442 common_prolog(as, &state);
443 common_salv_prolog(as, &state);
445 do_salvop(&state, SALVSYNC_CANCEL, NULL);
451 OpCancelAll(struct cmd_syndesc * as, void * rock)
455 common_prolog(as, &state);
456 common_salv_prolog(as, &state);
458 do_salvop(&state, SALVSYNC_CANCELALL, NULL);
464 OpRaisePrio(struct cmd_syndesc * as, void * rock)
468 common_prolog(as, &state);
469 common_salv_prolog(as, &state);
471 do_salvop(&state, SALVSYNC_RAISEPRIO, NULL);
477 OpQuery(struct cmd_syndesc * as, void * rock)
481 common_prolog(as, &state);
482 common_salv_prolog(as, &state);
484 do_salvop(&state, SALVSYNC_QUERY, NULL);
489 #endif /* AFS_DEMAND_ATTACH_FS */