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>
13 #include <afs/procmgmt.h>
19 #include <afs/afsutil.h>
22 #include "bosprototypes.h"
24 extern char *DoPidFiles;
25 static int emergency = 0;
27 /* if this file exists, then we have to salvage the file system */
28 #define SALFILE "SALVAGE."
30 #define POLLTIME 20 /* for handling below */
31 #define SDTIME 60 /* time in seconds given to a process to evaporate */
34 Normal operation involves having the file server and the vol server both running.
36 If the vol server terminates, it can simply be restarted.
38 If the file server terminates, the disk must salvaged before the file server
39 can be restarted. In order to restart either the file server or the salvager,
40 the vol server must be shut down.
42 If the file server terminates *normally* (exits after receiving a SIGQUIT)
43 then we don't have to salvage it.
45 The needsSalvage flag is set when the file server is started. It is cleared
46 if the file server exits when fileSDW is true but fileKillSent is false,
47 indicating that it exited after receiving a quit, but before we sent it a kill.
49 The needsSalvage flag is cleared when the salvager exits.
54 afs_int32 timeSDStarted; /* time shutdown operation started */
55 char *filecmd; /* command to start primary file server */
56 char *volcmd; /* command to start secondary vol server */
57 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
58 char *salcmd; /* command to start salvager */
59 char *scancmd; /* command to start scanner (MR-AFS) */
60 struct bnode_proc *fileProc; /* process for file server */
61 struct bnode_proc *volProc; /* process for vol server */
62 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
63 struct bnode_proc *salProc; /* process for salvager */
64 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
65 afs_int32 lastFileStart; /* last start for file */
66 afs_int32 lastVolStart; /* last start for vol */
67 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
68 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
69 char fileRunning; /* file process is running */
70 char volRunning; /* volser is running */
71 char salsrvRunning; /* salvageserver is running (demand attach fs) */
72 char salRunning; /* salvager is running */
73 char scanRunning; /* scanner is running (MR_AFS) */
74 char fileSDW; /* file shutdown wait */
75 char volSDW; /* vol shutdown wait */
76 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
77 char salSDW; /* waiting for the salvager to shutdown */
78 char scanSDW; /* scanner shutdown wait (MR_AFS) */
79 char fileKillSent; /* kill signal has been sent */
81 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
83 char scanKillSent; /* kill signal has been sent (MR_AFS) */
84 char needsSalvage; /* salvage before running */
85 char needsClock; /* do we need clock ticks */
88 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
89 char *asalcmd, char *ascancmd, char *dummy);
90 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
91 char * asalsrvcmd, char *asalcmd, char *ascancmd);
93 static int fs_hascore(struct bnode *abnode);
94 static int fs_restartp(struct bnode *abnode);
95 static int fs_delete(struct bnode *abnode);
96 static int fs_timeout(struct bnode *abnode);
97 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
98 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
99 static int fs_procstarted(struct bnode *abnode, struct bnode_proc *aproc);
100 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
101 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
102 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
103 char *abuffer, afs_int32 alen);
104 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
105 char *abuffer, afs_int32 alen);
107 static int SetSalFlag(struct fsbnode *abnode, int aflag);
108 static int RestoreSalFlag(struct fsbnode *abnode);
109 static void SetNeedsClock(struct fsbnode *);
110 static int NudgeProcs(struct fsbnode *);
113 static void AppendExecutableExtension(char *cmd);
115 #define AppendExecutableExtension(x)
118 struct bnode_ops fsbnode_ops = {
132 /* demand attach fs bnode ops */
133 struct bnode_ops dafsbnode_ops = {
147 /* Quick inline function to safely convert a fsbnode to a bnode without
148 * dropping type information
151 static_inline struct bnode *
152 fsbnode2bnode(struct fsbnode *abnode) {
153 return (struct bnode *) abnode;
156 /* Function to tell whether this bnode has a core file or not. You might
157 * think that this could be in bnode.c, and decide what core files to check
158 * for based on the bnode's coreName property, but that doesn't work because
159 * there may not be an active process for a bnode that dumped core at the
160 * time the query is done.
163 fs_hascore(struct bnode *abnode)
167 /* see if file server has a core file */
168 bnode_CoreName(abnode, "file", tbuffer);
169 if (access(tbuffer, 0) == 0)
172 /* see if volserver has a core file */
173 bnode_CoreName(abnode, "vol", tbuffer);
174 if (access(tbuffer, 0) == 0)
177 /* see if salvageserver left a core file */
178 bnode_CoreName(abnode, "salsrv", tbuffer);
179 if (access(tbuffer, 0) == 0)
182 /* see if salvager left a core file */
183 bnode_CoreName(abnode, "salv", tbuffer);
184 if (access(tbuffer, 0) == 0)
187 /* see if scanner left a core file (MR-AFS) */
188 bnode_CoreName(abnode, "scan", tbuffer);
189 if (access(tbuffer, 0) == 0)
192 /* no one left a core file */
197 fs_restartp(struct bnode *bn)
199 struct fsbnode *abnode = (struct fsbnode *)bn;
200 struct bnode_token *tt;
204 code = bnode_ParseLine(abnode->filecmd, &tt);
209 code = stat(tt->key, &tstat);
211 bnode_FreeTokens(tt);
214 if (tstat.st_ctime > abnode->lastFileStart)
218 bnode_FreeTokens(tt);
222 /* now do same for volcmd */
223 code = bnode_ParseLine(abnode->volcmd, &tt);
228 code = stat(tt->key, &tstat);
230 bnode_FreeTokens(tt);
233 if (tstat.st_ctime > abnode->lastVolStart)
237 bnode_FreeTokens(tt);
241 if (abnode->salsrvcmd) { /* only in demand attach fs */
242 /* now do same for salsrvcmd (demand attach fs) */
243 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
248 code = stat(tt->key, &tstat);
250 bnode_FreeTokens(tt);
253 if (tstat.st_ctime > abnode->lastSalsrvStart)
257 bnode_FreeTokens(tt);
260 if (abnode->scancmd) { /* Only in MR-AFS */
261 /* now do same for scancmd (MR-AFS) */
262 code = bnode_ParseLine(abnode->scancmd, &tt);
267 code = stat(tt->key, &tstat);
269 bnode_FreeTokens(tt);
272 if (tstat.st_ctime > abnode->lastScanStart)
276 bnode_FreeTokens(tt);
282 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
283 we need to salvage the file system (so we can tell over panic reboots */
285 SetSalFlag(struct fsbnode *abnode, int aflag)
287 char tbuffer[AFSDIR_PATH_MAX];
290 /* don't use the salvage flag for demand attach fs */
291 if (abnode->salsrvcmd == NULL) {
292 abnode->needsSalvage = aflag;
293 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
294 SALFILE, abnode->b.name, NULL);
296 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
305 /* set the needsSalvage flag according to the existence of the salvage file */
307 RestoreSalFlag(struct fsbnode *abnode)
309 char tbuffer[AFSDIR_PATH_MAX];
311 /* never set needs salvage flag for demand attach fs */
312 if (abnode->salsrvcmd != NULL) {
313 abnode->needsSalvage = 0;
315 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
316 SALFILE, abnode->b.name, NULL);
317 if (access(tbuffer, 0) == 0) {
318 /* file exists, so need to salvage */
319 abnode->needsSalvage = 1;
321 abnode->needsSalvage = 0;
331 b = (char *)malloc(strlen(a) + 1);
337 fs_delete(struct bnode *bn)
339 struct fsbnode *abnode = (struct fsbnode *)bn;
341 free(abnode->filecmd);
342 free(abnode->volcmd);
343 free(abnode->salcmd);
344 if (abnode->salsrvcmd)
345 free(abnode->salsrvcmd);
347 free(abnode->scancmd);
355 AppendExecutableExtension(char *cmd)
357 char cmdext[_MAX_EXT];
359 _splitpath(cmd, NULL, NULL, NULL, cmdext);
360 if (*cmdext == '\0') {
361 /* no filename extension supplied for cmd; append .exe */
365 #endif /* AFS_NT40_ENV */
369 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
370 char *ascancmd, char *dummy)
374 char cmdname[AFSDIR_PATH_MAX];
375 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
378 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
381 /* construct local paths from canonical (wire-format) paths */
382 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
383 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
387 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
388 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
392 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
393 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
398 if (ascancmd && strlen(ascancmd)) {
399 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
400 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
407 sscanf(fileCmdpath, "%s", cmdname);
408 AppendExecutableExtension(cmdname);
409 if (stat(cmdname, &tstat)) {
410 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
415 sscanf(volCmdpath, "%s", cmdname);
416 AppendExecutableExtension(cmdname);
417 if (stat(cmdname, &tstat)) {
418 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
423 sscanf(salCmdpath, "%s", cmdname);
424 AppendExecutableExtension(cmdname);
425 if (stat(cmdname, &tstat)) {
426 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
431 if (ascancmd && strlen(ascancmd)) {
432 sscanf(scanCmdpath, "%s", cmdname);
433 AppendExecutableExtension(cmdname);
434 if (stat(cmdname, &tstat)) {
435 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
442 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
447 memset(te, 0, sizeof(struct fsbnode));
448 te->filecmd = fileCmdpath;
449 te->volcmd = volCmdpath;
450 te->salsrvcmd = NULL;
451 te->salcmd = salCmdpath;
452 if (ascancmd && strlen(ascancmd))
453 te->scancmd = scanCmdpath;
456 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
460 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
461 /* ask for timeout activations every 20 seconds */
462 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
463 SetNeedsClock(te); /* compute needsClock field */
480 return fsbnode2bnode(te);
483 /* create a demand attach fs bnode */
485 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
486 char * asalsrvcmd, char *asalcmd, char *ascancmd)
490 char cmdname[AFSDIR_PATH_MAX];
491 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
494 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
497 /* construct local paths from canonical (wire-format) paths */
498 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
499 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
503 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
504 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
508 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
509 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
513 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
514 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
519 if (ascancmd && strlen(ascancmd)) {
520 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
521 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
528 sscanf(fileCmdpath, "%s", cmdname);
529 AppendExecutableExtension(cmdname);
530 if (stat(cmdname, &tstat)) {
531 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
536 sscanf(volCmdpath, "%s", cmdname);
537 AppendExecutableExtension(cmdname);
538 if (stat(cmdname, &tstat)) {
539 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
544 sscanf(salsrvCmdpath, "%s", cmdname);
545 AppendExecutableExtension(cmdname);
546 if (stat(cmdname, &tstat)) {
547 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
552 sscanf(salCmdpath, "%s", cmdname);
553 AppendExecutableExtension(cmdname);
554 if (stat(cmdname, &tstat)) {
555 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
560 if (ascancmd && strlen(ascancmd)) {
561 sscanf(scanCmdpath, "%s", cmdname);
562 AppendExecutableExtension(cmdname);
563 if (stat(cmdname, &tstat)) {
564 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
571 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
576 memset(te, 0, sizeof(struct fsbnode));
577 te->filecmd = fileCmdpath;
578 te->volcmd = volCmdpath;
579 te->salsrvcmd = salsrvCmdpath;
580 te->salcmd = salCmdpath;
581 if (ascancmd && strlen(ascancmd))
582 te->scancmd = scanCmdpath;
585 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
589 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
590 /* ask for timeout activations every 20 seconds */
591 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
592 SetNeedsClock(te); /* compute needsClock field */
611 return fsbnode2bnode(te);
614 /* called to SIGKILL a process if it doesn't terminate normally */
616 fs_timeout(struct bnode *bn)
618 struct fsbnode *abnode = (struct fsbnode *)bn;
622 now = FT_ApproxTime();
624 if (abnode->volSDW) {
625 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
626 bnode_StopProc(abnode->volProc, SIGKILL);
627 abnode->volKillSent = 1;
629 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
633 if (abnode->salSDW) {
634 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
635 bnode_StopProc(abnode->salProc, SIGKILL);
636 abnode->salKillSent = 1;
638 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
642 if (abnode->fileSDW) {
643 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
644 bnode_StopProc(abnode->fileProc, SIGKILL);
645 abnode->fileKillSent = 1;
647 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
651 if (abnode->salsrvSDW) {
652 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
653 bnode_StopProc(abnode->salsrvProc, SIGKILL);
654 abnode->salsrvKillSent = 1;
656 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
660 if (abnode->scanSDW) {
661 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
662 bnode_StopProc(abnode->scanProc, SIGKILL);
663 abnode->scanKillSent = 1;
665 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
670 if ((abnode->b.flags & BNODE_ERRORSTOP) && !abnode->salRunning
671 && !abnode->volRunning && !abnode->fileRunning && !abnode->scanRunning
672 && !abnode->salsrvRunning) {
673 bnode_SetStat(bn, BSTAT_NORMAL);
676 bnode_ResetErrorCount(bn);
679 SetNeedsClock(abnode);
684 fs_getstat(struct bnode *bn, afs_int32 * astatus)
686 struct fsbnode *abnode = (struct fsbnode *) bn;
689 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
690 || abnode->scanSDW || abnode->salsrvSDW)
691 temp = BSTAT_SHUTTINGDOWN;
692 else if (abnode->salRunning)
694 else if (abnode->volRunning && abnode->fileRunning
695 && (!abnode->scancmd || abnode->scanRunning)
696 && (!abnode->salsrvcmd || abnode->salsrvRunning))
698 else if (!abnode->salRunning && !abnode->volRunning
699 && !abnode->fileRunning && !abnode->scanRunning
700 && !abnode->salsrvRunning)
701 temp = BSTAT_SHUTDOWN;
703 temp = BSTAT_STARTINGUP;
709 fs_setstat(struct bnode *abnode, afs_int32 astatus)
711 return NudgeProcs((struct fsbnode *) abnode);
715 fs_procstarted(struct bnode *bn, struct bnode_proc *aproc)
720 code = bozo_CreatePidFile(bn->name, aproc->coreName, aproc->pid);
726 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
728 struct fsbnode *abnode = (struct fsbnode *)bn;
730 /* process has exited */
733 bozo_DeletePidFile(bn->name, aproc->coreName);
736 if (aproc == abnode->volProc) {
738 abnode->volRunning = 0;
740 abnode->volKillSent = 0;
741 } else if (aproc == abnode->fileProc) {
742 /* if we were expecting a shutdown and we didn't send a kill signal
743 * and exited (didn't have a signal termination), then we assume that
744 * the file server exited after putting the appropriate volumes safely
745 * offline, and don't salvage next time.
747 if (abnode->fileSDW && !abnode->fileKillSent
748 && aproc->lastSignal == 0)
749 SetSalFlag(abnode, 0); /* shut down normally */
750 abnode->fileProc = 0;
751 abnode->fileRunning = 0;
753 abnode->fileKillSent = 0;
754 } else if (aproc == abnode->salProc) {
755 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
756 * that we don't have to salvage again */
758 SetSalFlag(abnode, 0); /* salvage just completed */
760 abnode->salRunning = 0;
762 abnode->salKillSent = 0;
763 } else if (aproc == abnode->scanProc) {
764 abnode->scanProc = 0;
765 abnode->scanRunning = 0;
767 abnode->scanKillSent = 0;
768 } else if (aproc == abnode->salsrvProc) {
769 abnode->salsrvProc = 0;
770 abnode->salsrvRunning = 0;
771 abnode->salsrvSDW = 0;
772 abnode->salsrvKillSent = 0;
775 /* now restart anyone who needs to restart */
776 return NudgeProcs(abnode);
779 /* make sure we're periodically checking the state if we need to */
781 SetNeedsClock(struct fsbnode *ab)
783 afs_int32 timeout = POLLTIME;
785 if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
786 && (!ab->scancmd || ab->scanRunning)
787 && (!ab->salsrvcmd || ab->salsrvRunning)) {
788 if (ab->b.errorStopCount) {
789 /* reset error count after running for a bit */
792 ab->needsClock = 0; /* running normally */
794 } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
795 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
796 if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
797 bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
798 ab->b.errorStopDelay);
799 ab->needsClock = 1; /* halted for errors, retry later */
800 timeout = ab->b.errorStopDelay;
802 ab->needsClock = 0; /* halted normally */
805 ab->needsClock = 1; /* other */
807 if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
808 || ab->b.period != timeout))
809 bnode_SetTimeout(fsbnode2bnode(ab), timeout);
811 bnode_SetTimeout(fsbnode2bnode(ab), 0);
815 NudgeProcs(struct fsbnode *abnode)
817 struct bnode_proc *tp; /* not register */
821 now = FT_ApproxTime();
822 if (abnode->b.goal == 1) {
823 /* we're trying to run the system. If the file server is running, then we
824 * are trying to start up the system. If it is not running, then needsSalvage
825 * tells us if we need to run the salvager or not */
826 if (abnode->fileRunning) {
827 if (abnode->salRunning) {
828 bozo_Log("Salvager running along with file server!\n");
829 bozo_Log("Emergency shutdown\n");
831 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
832 bnode_StopProc(abnode->salProc, SIGKILL);
833 SetNeedsClock(abnode);
836 if (!abnode->volRunning) {
837 abnode->lastVolStart = FT_ApproxTime();
838 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
840 abnode->volProc = tp;
841 abnode->volRunning = 1;
844 if (abnode->salsrvcmd) {
845 if (!abnode->salsrvRunning) {
846 abnode->lastSalsrvStart = FT_ApproxTime();
848 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
851 abnode->salsrvProc = tp;
852 abnode->salsrvRunning = 1;
856 if (abnode->scancmd) {
857 if (!abnode->scanRunning) {
858 abnode->lastScanStart = FT_ApproxTime();
860 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
863 abnode->scanProc = tp;
864 abnode->scanRunning = 1;
868 } else { /* file is not running */
869 /* see how to start */
870 /* for demand attach fs, needsSalvage flag is ignored */
871 if (!abnode->needsSalvage || abnode->salsrvcmd) {
872 /* no crash apparent, just start up normally */
873 if (!abnode->fileRunning) {
874 abnode->lastFileStart = FT_ApproxTime();
876 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
878 abnode->fileProc = tp;
879 abnode->fileRunning = 1;
880 SetSalFlag(abnode, 1);
883 if (!abnode->volRunning) {
884 abnode->lastVolStart = FT_ApproxTime();
885 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
887 abnode->volProc = tp;
888 abnode->volRunning = 1;
891 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
892 abnode->lastSalsrvStart = FT_ApproxTime();
894 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
897 abnode->salsrvProc = tp;
898 abnode->salsrvRunning = 1;
901 if (abnode->scancmd && !abnode->scanRunning) {
902 abnode->lastScanStart = FT_ApproxTime();
904 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
907 abnode->scanProc = tp;
908 abnode->scanRunning = 1;
911 } else { /* needs to be salvaged */
912 /* make sure file server and volser are gone */
913 if (abnode->volRunning) {
914 bnode_StopProc(abnode->volProc, SIGTERM);
916 abnode->timeSDStarted = now;
919 if (abnode->fileRunning) {
920 bnode_StopProc(abnode->fileProc, SIGQUIT);
921 if (!abnode->fileSDW)
922 abnode->timeSDStarted = now;
925 if (abnode->scanRunning) {
926 bnode_StopProc(abnode->scanProc, SIGTERM);
927 if (!abnode->scanSDW)
928 abnode->timeSDStarted = now;
931 if (abnode->volRunning || abnode->fileRunning
932 || abnode->scanRunning)
934 /* otherwise, it is safe to start salvager */
935 if (!abnode->salRunning) {
936 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
938 abnode->salProc = tp;
939 abnode->salRunning = 1;
944 } else { /* goal is 0, we're shutting down */
945 /* trying to shutdown */
946 if (abnode->salRunning && !abnode->salSDW) {
947 bnode_StopProc(abnode->salProc, SIGTERM);
949 abnode->timeSDStarted = now;
951 if (abnode->fileRunning && !abnode->fileSDW) {
952 bnode_StopProc(abnode->fileProc, SIGQUIT);
954 abnode->timeSDStarted = now;
956 if (abnode->volRunning && !abnode->volSDW) {
957 bnode_StopProc(abnode->volProc, SIGTERM);
959 abnode->timeSDStarted = now;
961 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
962 bnode_StopProc(abnode->salsrvProc, SIGTERM);
963 abnode->salsrvSDW = 1;
964 abnode->timeSDStarted = now;
966 if (abnode->scanRunning && !abnode->scanSDW) {
967 bnode_StopProc(abnode->scanProc, SIGTERM);
969 abnode->timeSDStarted = now;
972 SetNeedsClock(abnode);
977 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
979 struct fsbnode *abnode = (struct fsbnode *)bn;
983 if (abnode->b.goal == 1) {
984 if (abnode->fileRunning) {
986 strcpy(abuffer, "file server shutting down");
987 else if (abnode->scancmd) {
988 if (!abnode->volRunning && !abnode->scanRunning)
990 "file server up; volser and scanner down");
991 else if (abnode->volRunning && !abnode->scanRunning)
993 "file server up; volser up; scanner down");
994 else if (!abnode->volRunning && abnode->scanRunning)
996 "file server up; volser down; scanner up");
999 strcpy(abuffer, "file server running");
1000 } else if (!abnode->volRunning)
1001 strcpy(abuffer, "file server up; volser down");
1003 strcpy(abuffer, "file server running");
1004 } else if (abnode->salRunning) {
1005 strcpy(abuffer, "salvaging file system");
1007 strcpy(abuffer, "starting file server");
1010 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
1011 strcpy(abuffer, "file server shutting down");
1012 } else if (abnode->salRunning)
1013 strcpy(abuffer, "salvager shutting down");
1015 strcpy(abuffer, "file server shut down");
1021 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1024 struct fsbnode *abnode = (struct fsbnode *)bn;
1027 strcpy(abuffer, abnode->filecmd);
1028 else if (aindex == 1)
1029 strcpy(abuffer, abnode->volcmd);
1030 else if (aindex == 2)
1031 strcpy(abuffer, abnode->salcmd);
1032 else if (aindex == 3 && abnode->scancmd)
1033 strcpy(abuffer, abnode->scancmd);
1040 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1043 struct fsbnode *abnode = (struct fsbnode *)bn;
1046 strcpy(abuffer, abnode->filecmd);
1047 else if (aindex == 1)
1048 strcpy(abuffer, abnode->volcmd);
1049 else if (aindex == 2)
1050 strcpy(abuffer, abnode->salsrvcmd);
1051 else if (aindex == 3)
1052 strcpy(abuffer, abnode->salcmd);
1053 else if (aindex == 4 && abnode->scancmd)
1054 strcpy(abuffer, abnode->scancmd);