2 * Copyright 2000, International Business Machines Corporation 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 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
33 #endif /* AFS_NT40_ENV */
35 #include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
36 #include <afs/afsutil.h>
38 #include "bosprototypes.h"
40 static int emergency = 0;
42 /* if this file exists, then we have to salvage the file system */
43 #define SALFILE "SALVAGE."
45 #define POLLTIME 20 /* for handling below */
46 #define SDTIME 60 /* time in seconds given to a process to evaporate */
49 Normal operation involves having the file server and the vol server both running.
51 If the vol server terminates, it can simply be restarted.
53 If the file server terminates, the disk must salvaged before the file server
54 can be restarted. In order to restart either the file server or the salvager,
55 the vol server must be shut down.
57 If the file server terminates *normally* (exits after receiving a SIGQUIT)
58 then we don't have to salvage it.
60 The needsSalvage flag is set when the file server is started. It is cleared
61 if the file server exits when fileSDW is true but fileKillSent is false,
62 indicating that it exited after receiving a quit, but before we sent it a kill.
64 The needsSalvage flag is cleared when the salvager exits.
69 afs_int32 timeSDStarted; /* time shutdown operation started */
70 char *filecmd; /* command to start primary file server */
71 char *volcmd; /* command to start secondary vol server */
72 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
73 char *salcmd; /* command to start salvager */
74 char *scancmd; /* command to start scanner (MR-AFS) */
75 struct bnode_proc *fileProc; /* process for file server */
76 struct bnode_proc *volProc; /* process for vol server */
77 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
78 struct bnode_proc *salProc; /* process for salvager */
79 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
80 afs_int32 lastFileStart; /* last start for file */
81 afs_int32 lastVolStart; /* last start for vol */
82 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
83 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
84 char fileRunning; /* file process is running */
85 char volRunning; /* volser is running */
86 char salsrvRunning; /* salvageserver is running (demand attach fs) */
87 char salRunning; /* salvager is running */
88 char scanRunning; /* scanner is running (MR_AFS) */
89 char fileSDW; /* file shutdown wait */
90 char volSDW; /* vol shutdown wait */
91 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
92 char salSDW; /* waiting for the salvager to shutdown */
93 char scanSDW; /* scanner shutdown wait (MR_AFS) */
94 char fileKillSent; /* kill signal has been sent */
96 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
98 char scanKillSent; /* kill signal has been sent (MR_AFS) */
99 char needsSalvage; /* salvage before running */
100 char needsClock; /* do we need clock ticks */
103 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
104 char *asalcmd, char *ascancmd, char *dummy);
105 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
106 char * asalsrvcmd, char *asalcmd, char *ascancmd);
108 static int fs_hascore(struct bnode *abnode);
109 static int fs_restartp(struct bnode *abnode);
110 static int fs_delete(struct bnode *abnode);
111 static int fs_timeout(struct bnode *abnode);
112 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
113 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
114 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
115 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
116 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
117 char *abuffer, afs_int32 alen);
118 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
119 char *abuffer, afs_int32 alen);
121 static int SetSalFlag(struct fsbnode *abnode, int aflag);
122 static int RestoreSalFlag(struct fsbnode *abnode);
123 static void SetNeedsClock(struct fsbnode *);
124 static int NudgeProcs(struct fsbnode *);
127 static void AppendExecutableExtension(char *cmd);
129 #define AppendExecutableExtension(x)
132 struct bnode_ops fsbnode_ops = {
145 /* demand attach fs bnode ops */
146 struct bnode_ops dafsbnode_ops = {
159 /* Quick inline function to safely convert a fsbnode to a bnode without
160 * dropping type information
163 static_inline struct bnode * fsbnode2bnode(struct fsbnode *abnode) {
164 return (struct bnode *) abnode;
167 /* Function to tell whether this bnode has a core file or not. You might
168 * think that this could be in bnode.c, and decide what core files to check
169 * for based on the bnode's coreName property, but that doesn't work because
170 * there may not be an active process for a bnode that dumped core at the
171 * time the query is done.
174 fs_hascore(struct bnode *abnode)
178 /* see if file server has a core file */
179 bnode_CoreName(abnode, "file", tbuffer);
180 if (access(tbuffer, 0) == 0)
183 /* see if volserver has a core file */
184 bnode_CoreName(abnode, "vol", tbuffer);
185 if (access(tbuffer, 0) == 0)
188 /* see if salvageserver left a core file */
189 bnode_CoreName(abnode, "salsrv", tbuffer);
190 if (access(tbuffer, 0) == 0)
193 /* see if salvager left a core file */
194 bnode_CoreName(abnode, "salv", tbuffer);
195 if (access(tbuffer, 0) == 0)
198 /* see if scanner left a core file (MR-AFS) */
199 bnode_CoreName(abnode, "scan", tbuffer);
200 if (access(tbuffer, 0) == 0)
203 /* no one left a core file */
208 fs_restartp(struct bnode *bn)
210 struct fsbnode *abnode = (struct fsbnode *)bn;
211 struct bnode_token *tt;
212 register afs_int32 code;
215 code = bnode_ParseLine(abnode->filecmd, &tt);
220 code = stat(tt->key, &tstat);
222 bnode_FreeTokens(tt);
225 if (tstat.st_ctime > abnode->lastFileStart)
229 bnode_FreeTokens(tt);
233 /* now do same for volcmd */
234 code = bnode_ParseLine(abnode->volcmd, &tt);
239 code = stat(tt->key, &tstat);
241 bnode_FreeTokens(tt);
244 if (tstat.st_ctime > abnode->lastVolStart)
248 bnode_FreeTokens(tt);
252 if (abnode->salsrvcmd) { /* only in demand attach fs */
253 /* now do same for salsrvcmd (demand attach fs) */
254 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
259 code = stat(tt->key, &tstat);
261 bnode_FreeTokens(tt);
264 if (tstat.st_ctime > abnode->lastScanStart)
268 bnode_FreeTokens(tt);
271 if (abnode->scancmd) { /* Only in MR-AFS */
272 /* now do same for scancmd (MR-AFS) */
273 code = bnode_ParseLine(abnode->scancmd, &tt);
278 code = stat(tt->key, &tstat);
280 bnode_FreeTokens(tt);
283 if (tstat.st_ctime > abnode->lastScanStart)
287 bnode_FreeTokens(tt);
293 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
294 we need to salvage the file system (so we can tell over panic reboots */
296 SetSalFlag(register struct fsbnode *abnode, register int aflag)
298 char tbuffer[AFSDIR_PATH_MAX];
301 /* don't use the salvage flag for demand attach fs */
302 if (abnode->salsrvcmd == NULL) {
303 abnode->needsSalvage = aflag;
304 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
305 SALFILE, abnode->b.name, NULL);
307 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
316 /* set the needsSalvage flag according to the existence of the salvage file */
318 RestoreSalFlag(register struct fsbnode *abnode)
320 char tbuffer[AFSDIR_PATH_MAX];
322 /* never set needs salvage flag for demand attach fs */
323 if (abnode->salsrvcmd != NULL) {
324 abnode->needsSalvage = 0;
326 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
327 SALFILE, abnode->b.name, NULL);
328 if (access(tbuffer, 0) == 0) {
329 /* file exists, so need to salvage */
330 abnode->needsSalvage = 1;
332 abnode->needsSalvage = 0;
339 copystr(register char *a)
342 b = (char *)malloc(strlen(a) + 1);
348 fs_delete(struct bnode *bn)
350 struct fsbnode *abnode = (struct fsbnode *)bn;
352 free(abnode->filecmd);
353 free(abnode->volcmd);
354 free(abnode->salcmd);
355 if (abnode->salsrvcmd)
356 free(abnode->salsrvcmd);
358 free(abnode->scancmd);
366 AppendExecutableExtension(char *cmd)
368 char cmdext[_MAX_EXT];
370 _splitpath(cmd, NULL, NULL, NULL, cmdext);
371 if (*cmdext == '\0') {
372 /* no filename extension supplied for cmd; append .exe */
376 #endif /* AFS_NT40_ENV */
380 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
381 char *ascancmd, char *dummy)
384 register struct fsbnode *te;
385 char cmdname[AFSDIR_PATH_MAX];
386 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
389 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
392 /* construct local paths from canonical (wire-format) paths */
393 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
394 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
398 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
399 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
403 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
404 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
409 if (ascancmd && strlen(ascancmd)) {
410 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
411 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
418 sscanf(fileCmdpath, "%s", cmdname);
419 AppendExecutableExtension(cmdname);
420 if (stat(cmdname, &tstat)) {
421 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
426 sscanf(volCmdpath, "%s", cmdname);
427 AppendExecutableExtension(cmdname);
428 if (stat(cmdname, &tstat)) {
429 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
434 sscanf(salCmdpath, "%s", cmdname);
435 AppendExecutableExtension(cmdname);
436 if (stat(cmdname, &tstat)) {
437 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
442 if (ascancmd && strlen(ascancmd)) {
443 sscanf(scanCmdpath, "%s", cmdname);
444 AppendExecutableExtension(cmdname);
445 if (stat(cmdname, &tstat)) {
446 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
453 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
458 memset(te, 0, sizeof(struct fsbnode));
459 te->filecmd = fileCmdpath;
460 te->volcmd = volCmdpath;
461 te->salsrvcmd = NULL;
462 te->salcmd = salCmdpath;
463 if (ascancmd && strlen(ascancmd))
464 te->scancmd = scanCmdpath;
467 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
471 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
472 /* ask for timeout activations every 10 seconds */
473 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
474 SetNeedsClock(te); /* compute needsClock field */
491 return fsbnode2bnode(te);
494 /* create a demand attach fs bnode */
496 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
497 char * asalsrvcmd, char *asalcmd, char *ascancmd)
500 register struct fsbnode *te;
501 char cmdname[AFSDIR_PATH_MAX];
502 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
505 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
508 /* construct local paths from canonical (wire-format) paths */
509 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
510 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
514 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
515 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
519 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
520 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
524 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
525 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
530 if (ascancmd && strlen(ascancmd)) {
531 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
532 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
539 sscanf(fileCmdpath, "%s", cmdname);
540 AppendExecutableExtension(cmdname);
541 if (stat(cmdname, &tstat)) {
542 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
547 sscanf(volCmdpath, "%s", cmdname);
548 AppendExecutableExtension(cmdname);
549 if (stat(cmdname, &tstat)) {
550 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
555 sscanf(salsrvCmdpath, "%s", cmdname);
556 AppendExecutableExtension(cmdname);
557 if (stat(cmdname, &tstat)) {
558 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
563 sscanf(salCmdpath, "%s", cmdname);
564 AppendExecutableExtension(cmdname);
565 if (stat(cmdname, &tstat)) {
566 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
571 if (ascancmd && strlen(ascancmd)) {
572 sscanf(scanCmdpath, "%s", cmdname);
573 AppendExecutableExtension(cmdname);
574 if (stat(cmdname, &tstat)) {
575 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
582 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
587 memset(te, 0, sizeof(struct fsbnode));
588 te->filecmd = fileCmdpath;
589 te->volcmd = volCmdpath;
590 te->salsrvcmd = salsrvCmdpath;
591 te->salcmd = salCmdpath;
592 if (ascancmd && strlen(ascancmd))
593 te->scancmd = scanCmdpath;
596 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
600 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
601 /* ask for timeout activations every 10 seconds */
602 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
603 SetNeedsClock(te); /* compute needsClock field */
622 return fsbnode2bnode(te);
625 /* called to SIGKILL a process if it doesn't terminate normally */
627 fs_timeout(struct bnode *bn)
629 struct fsbnode *abnode = (struct fsbnode *)bn;
631 register afs_int32 now;
633 now = FT_ApproxTime();
635 if (abnode->volSDW) {
636 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
637 bnode_StopProc(abnode->volProc, SIGKILL);
638 abnode->volKillSent = 1;
640 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
644 if (abnode->salSDW) {
645 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
646 bnode_StopProc(abnode->salProc, SIGKILL);
647 abnode->salKillSent = 1;
649 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
653 if (abnode->fileSDW) {
654 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
655 bnode_StopProc(abnode->fileProc, SIGKILL);
656 abnode->fileKillSent = 1;
658 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
662 if (abnode->salsrvSDW) {
663 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
664 bnode_StopProc(abnode->salsrvProc, SIGKILL);
665 abnode->salsrvKillSent = 1;
667 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
671 if (abnode->scanSDW) {
672 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
673 bnode_StopProc(abnode->scanProc, SIGKILL);
674 abnode->scanKillSent = 1;
676 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
680 SetNeedsClock(abnode);
685 fs_getstat(struct bnode *bn, afs_int32 * astatus)
687 struct fsbnode *abnode = (struct fsbnode *) bn;
689 register afs_int32 temp;
690 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
691 || abnode->scanSDW || abnode->salsrvSDW)
692 temp = BSTAT_SHUTTINGDOWN;
693 else if (abnode->salRunning)
695 else if (abnode->volRunning && abnode->fileRunning
696 && (!abnode->scancmd || abnode->scanRunning)
697 && (!abnode->salsrvcmd || abnode->salsrvRunning))
699 else if (!abnode->salRunning && !abnode->volRunning
700 && !abnode->fileRunning && !abnode->scanRunning
701 && !abnode->salsrvRunning)
702 temp = BSTAT_SHUTDOWN;
704 temp = BSTAT_STARTINGUP;
710 fs_setstat(struct bnode *abnode, afs_int32 astatus)
712 return NudgeProcs((struct fsbnode *) abnode);
716 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
718 struct fsbnode *abnode = (struct fsbnode *)bn;
720 /* process has exited */
722 if (aproc == abnode->volProc) {
724 abnode->volRunning = 0;
726 abnode->volKillSent = 0;
727 } else if (aproc == abnode->fileProc) {
728 /* if we were expecting a shutdown and we didn't send a kill signal
729 * and exited (didn't have a signal termination), then we assume that
730 * the file server exited after putting the appropriate volumes safely
731 * offline, and don't salvage next time.
733 if (abnode->fileSDW && !abnode->fileKillSent
734 && aproc->lastSignal == 0)
735 SetSalFlag(abnode, 0); /* shut down normally */
736 abnode->fileProc = 0;
737 abnode->fileRunning = 0;
739 abnode->fileKillSent = 0;
740 } else if (aproc == abnode->salProc) {
741 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
742 * that we don't have to salvage again */
744 SetSalFlag(abnode, 0); /* salvage just completed */
746 abnode->salRunning = 0;
748 abnode->salKillSent = 0;
749 } else if (aproc == abnode->scanProc) {
750 abnode->scanProc = 0;
751 abnode->scanRunning = 0;
753 abnode->scanKillSent = 0;
754 } else if (aproc == abnode->salsrvProc) {
755 abnode->salsrvProc = 0;
756 abnode->salsrvRunning = 0;
757 abnode->salsrvSDW = 0;
758 abnode->salsrvKillSent = 0;
761 /* now restart anyone who needs to restart */
762 return NudgeProcs(abnode);
765 /* make sure we're periodically checking the state if we need to */
767 SetNeedsClock(register struct fsbnode *ab)
769 if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
770 && (!ab->scancmd || ab->scanRunning)
771 && (!ab->salsrvcmd || ab->salsrvRunning))
772 ab->needsClock = 0; /* running normally */
773 else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning
774 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning)
775 ab->needsClock = 0; /* halted normally */
777 ab->needsClock = 1; /* other */
778 if (ab->needsClock && !bnode_PendingTimeout(fsbnode2bnode(ab)))
779 bnode_SetTimeout(fsbnode2bnode(ab), POLLTIME);
781 bnode_SetTimeout(fsbnode2bnode(ab), 0);
785 NudgeProcs(register struct fsbnode *abnode)
787 struct bnode_proc *tp; /* not register */
788 register afs_int32 code;
791 now = FT_ApproxTime();
792 if (abnode->b.goal == 1) {
793 /* we're trying to run the system. If the file server is running, then we
794 * are trying to start up the system. If it is not running, then needsSalvage
795 * tells us if we need to run the salvager or not */
796 if (abnode->fileRunning) {
797 if (abnode->salRunning) {
798 bozo_Log("Salvager running along with file server!\n");
799 bozo_Log("Emergency shutdown\n");
801 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
802 bnode_StopProc(abnode->salProc, SIGKILL);
803 SetNeedsClock(abnode);
806 if (!abnode->volRunning) {
807 abnode->lastVolStart = FT_ApproxTime();
808 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
810 abnode->volProc = tp;
811 abnode->volRunning = 1;
814 if (abnode->salsrvcmd) {
815 if (!abnode->salsrvRunning) {
816 abnode->lastSalsrvStart = FT_ApproxTime();
818 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
821 abnode->salsrvProc = tp;
822 abnode->salsrvRunning = 1;
826 if (abnode->scancmd) {
827 if (!abnode->scanRunning) {
828 abnode->lastScanStart = FT_ApproxTime();
830 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
833 abnode->scanProc = tp;
834 abnode->scanRunning = 1;
838 } else { /* file is not running */
839 /* see how to start */
840 /* for demand attach fs, needsSalvage flag is ignored */
841 if (!abnode->needsSalvage || abnode->salsrvcmd) {
842 /* no crash apparent, just start up normally */
843 if (!abnode->fileRunning) {
844 abnode->lastFileStart = FT_ApproxTime();
846 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
848 abnode->fileProc = tp;
849 abnode->fileRunning = 1;
850 SetSalFlag(abnode, 1);
853 if (!abnode->volRunning) {
854 abnode->lastVolStart = FT_ApproxTime();
855 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
857 abnode->volProc = tp;
858 abnode->volRunning = 1;
861 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
862 abnode->lastSalsrvStart = FT_ApproxTime();
864 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
867 abnode->salsrvProc = tp;
868 abnode->salsrvRunning = 1;
871 if (abnode->scancmd && !abnode->scanRunning) {
872 abnode->lastScanStart = FT_ApproxTime();
874 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
877 abnode->scanProc = tp;
878 abnode->scanRunning = 1;
881 } else { /* needs to be salvaged */
882 /* make sure file server and volser are gone */
883 if (abnode->volRunning) {
884 bnode_StopProc(abnode->volProc, SIGTERM);
886 abnode->timeSDStarted = now;
889 if (abnode->fileRunning) {
890 bnode_StopProc(abnode->fileProc, SIGQUIT);
891 if (!abnode->fileSDW)
892 abnode->timeSDStarted = now;
895 if (abnode->scanRunning) {
896 bnode_StopProc(abnode->scanProc, SIGTERM);
897 if (!abnode->scanSDW)
898 abnode->timeSDStarted = now;
901 if (abnode->volRunning || abnode->fileRunning
902 || abnode->scanRunning)
904 /* otherwise, it is safe to start salvager */
905 if (!abnode->salRunning) {
906 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
908 abnode->salProc = tp;
909 abnode->salRunning = 1;
914 } else { /* goal is 0, we're shutting down */
915 /* trying to shutdown */
916 if (abnode->salRunning && !abnode->salSDW) {
917 bnode_StopProc(abnode->salProc, SIGTERM);
919 abnode->timeSDStarted = now;
921 if (abnode->fileRunning && !abnode->fileSDW) {
922 bnode_StopProc(abnode->fileProc, SIGQUIT);
924 abnode->timeSDStarted = now;
926 if (abnode->volRunning && !abnode->volSDW) {
927 bnode_StopProc(abnode->volProc, SIGTERM);
929 abnode->timeSDStarted = now;
931 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
932 bnode_StopProc(abnode->salsrvProc, SIGTERM);
933 abnode->salsrvSDW = 1;
934 abnode->timeSDStarted = now;
936 if (abnode->scanRunning && !abnode->scanSDW) {
937 bnode_StopProc(abnode->scanProc, SIGTERM);
939 abnode->timeSDStarted = now;
942 SetNeedsClock(abnode);
947 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
949 struct fsbnode *abnode = (struct fsbnode *)bn;
953 if (abnode->b.goal == 1) {
954 if (abnode->fileRunning) {
956 strcpy(abuffer, "file server shutting down");
957 else if (abnode->scancmd) {
958 if (!abnode->volRunning && !abnode->scanRunning)
960 "file server up; volser and scanner down");
961 else if (abnode->volRunning && !abnode->scanRunning)
963 "file server up; volser up; scanner down");
964 else if (!abnode->volRunning && abnode->scanRunning)
966 "file server up; volser down; scanner up");
969 strcpy(abuffer, "file server running");
970 } else if (!abnode->volRunning)
971 strcpy(abuffer, "file server up; volser down");
973 strcpy(abuffer, "file server running");
974 } else if (abnode->salRunning) {
975 strcpy(abuffer, "salvaging file system");
977 strcpy(abuffer, "starting file server");
980 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
981 strcpy(abuffer, "file server shutting down");
982 } else if (abnode->salRunning)
983 strcpy(abuffer, "salvager shutting down");
985 strcpy(abuffer, "file server shut down");
991 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
994 struct fsbnode *abnode = (struct fsbnode *)bn;
997 strcpy(abuffer, abnode->filecmd);
998 else if (aindex == 1)
999 strcpy(abuffer, abnode->volcmd);
1000 else if (aindex == 2)
1001 strcpy(abuffer, abnode->salcmd);
1002 else if (aindex == 3 && abnode->scancmd)
1003 strcpy(abuffer, abnode->scancmd);
1010 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1013 struct fsbnode *abnode = (struct fsbnode *)bn;
1016 strcpy(abuffer, abnode->filecmd);
1017 else if (aindex == 1)
1018 strcpy(abuffer, abnode->volcmd);
1019 else if (aindex == 2)
1020 strcpy(abuffer, abnode->salsrvcmd);
1021 else if (aindex == 3)
1022 strcpy(abuffer, abnode->salcmd);
1023 else if (aindex == 4 && abnode->scancmd)
1024 strcpy(abuffer, abnode->scancmd);