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 "bnode_internal.h"
23 #include "bosprototypes.h"
25 extern char *DoPidFiles;
26 static int emergency = 0;
28 /* if this file exists, then we have to salvage the file system */
29 #define SALFILE "SALVAGE."
31 #define POLLTIME 20 /* for handling below */
32 #define SDTIME 60 /* time in seconds given to a process to evaporate */
35 Normal operation involves having the file server and the vol server both running.
37 If the vol server terminates, it can simply be restarted.
39 If the file server terminates, the disk must salvaged before the file server
40 can be restarted. In order to restart either the file server or the salvager,
41 the vol server must be shut down.
43 If the file server terminates *normally* (exits after receiving a SIGQUIT)
44 then we don't have to salvage it.
46 The needsSalvage flag is set when the file server is started. It is cleared
47 if the file server exits when fileSDW is true but fileKillSent is false,
48 indicating that it exited after receiving a quit, but before we sent it a kill.
50 The needsSalvage flag is cleared when the salvager exits.
55 afs_int32 timeSDStarted; /* time shutdown operation started */
56 char *filecmd; /* command to start primary file server */
57 char *volcmd; /* command to start secondary vol server */
58 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
59 char *salcmd; /* command to start salvager */
60 char *scancmd; /* command to start scanner (MR-AFS) */
61 struct bnode_proc *fileProc; /* process for file server */
62 struct bnode_proc *volProc; /* process for vol server */
63 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
64 struct bnode_proc *salProc; /* process for salvager */
65 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
66 afs_int32 lastFileStart; /* last start for file */
67 afs_int32 lastVolStart; /* last start for vol */
68 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
69 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
70 char fileRunning; /* file process is running */
71 char volRunning; /* volser is running */
72 char salsrvRunning; /* salvageserver is running (demand attach fs) */
73 char salRunning; /* salvager is running */
74 char scanRunning; /* scanner is running (MR_AFS) */
75 char fileSDW; /* file shutdown wait */
76 char volSDW; /* vol shutdown wait */
77 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
78 char salSDW; /* waiting for the salvager to shutdown */
79 char scanSDW; /* scanner shutdown wait (MR_AFS) */
80 char fileKillSent; /* kill signal has been sent */
82 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
84 char scanKillSent; /* kill signal has been sent (MR_AFS) */
85 char needsSalvage; /* salvage before running */
86 char needsClock; /* do we need clock ticks */
89 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
90 char *asalcmd, char *ascancmd, char *dummy);
91 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
92 char * asalsrvcmd, char *asalcmd, char *ascancmd);
94 static int fs_hascore(struct bnode *abnode);
95 static int fs_restartp(struct bnode *abnode);
96 static int fs_delete(struct bnode *abnode);
97 static int fs_timeout(struct bnode *abnode);
98 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
99 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
100 static int fs_procstarted(struct bnode *abnode, struct bnode_proc *aproc);
101 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
102 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
103 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
104 char *abuffer, afs_int32 alen);
105 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
106 char *abuffer, afs_int32 alen);
108 static int SetSalFlag(struct fsbnode *abnode, int aflag);
109 static int RestoreSalFlag(struct fsbnode *abnode);
110 static void SetNeedsClock(struct fsbnode *);
111 static int NudgeProcs(struct fsbnode *);
114 static void AppendExecutableExtension(char *cmd);
116 #define AppendExecutableExtension(x)
119 struct bnode_ops fsbnode_ops = {
133 /* demand attach fs bnode ops */
134 struct bnode_ops dafsbnode_ops = {
148 /* Quick inline function to safely convert a fsbnode to a bnode without
149 * dropping type information
152 static_inline struct bnode *
153 fsbnode2bnode(struct fsbnode *abnode) {
154 return (struct bnode *) abnode;
157 /* Function to tell whether this bnode has a core file or not. You might
158 * think that this could be in bnode.c, and decide what core files to check
159 * for based on the bnode's coreName property, but that doesn't work because
160 * there may not be an active process for a bnode that dumped core at the
161 * time the query is done.
164 fs_hascore(struct bnode *abnode)
168 /* see if file server has a core file */
169 bnode_CoreName(abnode, "file", tbuffer);
170 if (access(tbuffer, 0) == 0)
173 /* see if volserver has a core file */
174 bnode_CoreName(abnode, "vol", tbuffer);
175 if (access(tbuffer, 0) == 0)
178 /* see if salvageserver left a core file */
179 bnode_CoreName(abnode, "salsrv", tbuffer);
180 if (access(tbuffer, 0) == 0)
183 /* see if salvager left a core file */
184 bnode_CoreName(abnode, "salv", tbuffer);
185 if (access(tbuffer, 0) == 0)
188 /* see if scanner left a core file (MR-AFS) */
189 bnode_CoreName(abnode, "scan", tbuffer);
190 if (access(tbuffer, 0) == 0)
193 /* no one left a core file */
198 fs_restartp(struct bnode *bn)
200 struct fsbnode *abnode = (struct fsbnode *)bn;
201 struct bnode_token *tt;
205 code = bnode_ParseLine(abnode->filecmd, &tt);
210 code = stat(tt->key, &tstat);
212 bnode_FreeTokens(tt);
215 if (tstat.st_ctime > abnode->lastFileStart)
219 bnode_FreeTokens(tt);
223 /* now do same for volcmd */
224 code = bnode_ParseLine(abnode->volcmd, &tt);
229 code = stat(tt->key, &tstat);
231 bnode_FreeTokens(tt);
234 if (tstat.st_ctime > abnode->lastVolStart)
238 bnode_FreeTokens(tt);
242 if (abnode->salsrvcmd) { /* only in demand attach fs */
243 /* now do same for salsrvcmd (demand attach fs) */
244 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
249 code = stat(tt->key, &tstat);
251 bnode_FreeTokens(tt);
254 if (tstat.st_ctime > abnode->lastSalsrvStart)
258 bnode_FreeTokens(tt);
261 if (abnode->scancmd) { /* Only in MR-AFS */
262 /* now do same for scancmd (MR-AFS) */
263 code = bnode_ParseLine(abnode->scancmd, &tt);
268 code = stat(tt->key, &tstat);
270 bnode_FreeTokens(tt);
273 if (tstat.st_ctime > abnode->lastScanStart)
277 bnode_FreeTokens(tt);
283 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
284 we need to salvage the file system (so we can tell over panic reboots */
286 SetSalFlag(struct fsbnode *abnode, int aflag)
288 char tbuffer[AFSDIR_PATH_MAX];
291 /* don't use the salvage flag for demand attach fs */
292 if (abnode->salsrvcmd == NULL) {
293 abnode->needsSalvage = aflag;
294 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
295 SALFILE, abnode->b.name, (char *)NULL);
297 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
306 /* set the needsSalvage flag according to the existence of the salvage file */
308 RestoreSalFlag(struct fsbnode *abnode)
310 char tbuffer[AFSDIR_PATH_MAX];
312 /* never set needs salvage flag for demand attach fs */
313 if (abnode->salsrvcmd != NULL) {
314 abnode->needsSalvage = 0;
316 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
317 SALFILE, abnode->b.name, (char *)NULL);
318 if (access(tbuffer, 0) == 0) {
319 /* file exists, so need to salvage */
320 abnode->needsSalvage = 1;
322 abnode->needsSalvage = 0;
329 fs_delete(struct bnode *bn)
331 struct fsbnode *abnode = (struct fsbnode *)bn;
333 free(abnode->filecmd);
334 free(abnode->volcmd);
335 free(abnode->salcmd);
336 if (abnode->salsrvcmd)
337 free(abnode->salsrvcmd);
339 free(abnode->scancmd);
347 AppendExecutableExtension(char *cmd)
349 char cmdext[_MAX_EXT];
351 _splitpath(cmd, NULL, NULL, NULL, cmdext);
352 if (*cmdext == '\0') {
353 /* no filename extension supplied for cmd; append .exe */
357 #endif /* AFS_NT40_ENV */
361 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
362 char *ascancmd, char *dummy)
366 char cmdname[AFSDIR_PATH_MAX];
367 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
370 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
373 /* construct local paths from canonical (wire-format) paths */
374 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
375 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
379 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
380 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
384 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
385 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
390 if (ascancmd && strlen(ascancmd)) {
391 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
392 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
399 sscanf(fileCmdpath, "%s", cmdname);
400 AppendExecutableExtension(cmdname);
401 if (stat(cmdname, &tstat)) {
402 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
407 sscanf(volCmdpath, "%s", cmdname);
408 AppendExecutableExtension(cmdname);
409 if (stat(cmdname, &tstat)) {
410 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
415 sscanf(salCmdpath, "%s", cmdname);
416 AppendExecutableExtension(cmdname);
417 if (stat(cmdname, &tstat)) {
418 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
423 if (ascancmd && strlen(ascancmd)) {
424 sscanf(scanCmdpath, "%s", cmdname);
425 AppendExecutableExtension(cmdname);
426 if (stat(cmdname, &tstat)) {
427 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
434 te = calloc(1, sizeof(struct fsbnode));
439 te->filecmd = fileCmdpath;
440 te->volcmd = volCmdpath;
441 te->salsrvcmd = NULL;
442 te->salcmd = salCmdpath;
443 if (ascancmd && strlen(ascancmd))
444 te->scancmd = scanCmdpath;
447 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
451 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
452 /* ask for timeout activations every 20 seconds */
453 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
454 SetNeedsClock(te); /* compute needsClock field */
471 return fsbnode2bnode(te);
474 /* create a demand attach fs bnode */
476 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
477 char * asalsrvcmd, char *asalcmd, char *ascancmd)
481 char cmdname[AFSDIR_PATH_MAX];
482 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
485 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
488 /* construct local paths from canonical (wire-format) paths */
489 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
490 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
494 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
495 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
499 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
500 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
504 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
505 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
510 if (ascancmd && strlen(ascancmd)) {
511 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
512 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
519 sscanf(fileCmdpath, "%s", cmdname);
520 AppendExecutableExtension(cmdname);
521 if (stat(cmdname, &tstat)) {
522 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
527 sscanf(volCmdpath, "%s", cmdname);
528 AppendExecutableExtension(cmdname);
529 if (stat(cmdname, &tstat)) {
530 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
535 sscanf(salsrvCmdpath, "%s", cmdname);
536 AppendExecutableExtension(cmdname);
537 if (stat(cmdname, &tstat)) {
538 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
543 sscanf(salCmdpath, "%s", cmdname);
544 AppendExecutableExtension(cmdname);
545 if (stat(cmdname, &tstat)) {
546 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
551 if (ascancmd && strlen(ascancmd)) {
552 sscanf(scanCmdpath, "%s", cmdname);
553 AppendExecutableExtension(cmdname);
554 if (stat(cmdname, &tstat)) {
555 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
562 te = calloc(1, sizeof(struct fsbnode));
567 te->filecmd = fileCmdpath;
568 te->volcmd = volCmdpath;
569 te->salsrvcmd = salsrvCmdpath;
570 te->salcmd = salCmdpath;
571 if (ascancmd && strlen(ascancmd))
572 te->scancmd = scanCmdpath;
575 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
579 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
580 /* ask for timeout activations every 20 seconds */
581 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
582 SetNeedsClock(te); /* compute needsClock field */
601 return fsbnode2bnode(te);
604 /* called to SIGKILL a process if it doesn't terminate normally */
606 fs_timeout(struct bnode *bn)
608 struct fsbnode *abnode = (struct fsbnode *)bn;
612 now = FT_ApproxTime();
614 if (abnode->volSDW) {
615 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
616 bnode_StopProc(abnode->volProc, SIGKILL);
617 abnode->volKillSent = 1;
619 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
623 if (abnode->salSDW) {
624 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
625 bnode_StopProc(abnode->salProc, SIGKILL);
626 abnode->salKillSent = 1;
628 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
632 if (abnode->fileSDW) {
633 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
634 bnode_StopProc(abnode->fileProc, SIGKILL);
635 abnode->fileKillSent = 1;
637 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
641 if (abnode->salsrvSDW) {
642 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
643 bnode_StopProc(abnode->salsrvProc, SIGKILL);
644 abnode->salsrvKillSent = 1;
646 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
650 if (abnode->scanSDW) {
651 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
652 bnode_StopProc(abnode->scanProc, SIGKILL);
653 abnode->scanKillSent = 1;
655 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
660 if ((abnode->b.flags & BNODE_ERRORSTOP) && !abnode->salRunning
661 && !abnode->volRunning && !abnode->fileRunning && !abnode->scanRunning
662 && !abnode->salsrvRunning) {
663 bnode_SetStat(bn, BSTAT_NORMAL);
666 bnode_ResetErrorCount(bn);
669 SetNeedsClock(abnode);
674 fs_getstat(struct bnode *bn, afs_int32 * astatus)
676 struct fsbnode *abnode = (struct fsbnode *) bn;
679 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
680 || abnode->scanSDW || abnode->salsrvSDW)
681 temp = BSTAT_SHUTTINGDOWN;
682 else if (abnode->salRunning)
684 else if (abnode->volRunning && abnode->fileRunning
685 && (!abnode->scancmd || abnode->scanRunning)
686 && (!abnode->salsrvcmd || abnode->salsrvRunning))
688 else if (!abnode->salRunning && !abnode->volRunning
689 && !abnode->fileRunning && !abnode->scanRunning
690 && !abnode->salsrvRunning)
691 temp = BSTAT_SHUTDOWN;
693 temp = BSTAT_STARTINGUP;
699 fs_setstat(struct bnode *abnode, afs_int32 astatus)
701 return NudgeProcs((struct fsbnode *) abnode);
705 fs_procstarted(struct bnode *bn, struct bnode_proc *aproc)
710 code = bozo_CreatePidFile(bn->name, aproc->coreName, aproc->pid);
716 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
718 struct fsbnode *abnode = (struct fsbnode *)bn;
720 /* process has exited */
723 bozo_DeletePidFile(bn->name, aproc->coreName);
726 if (aproc == abnode->volProc) {
728 abnode->volRunning = 0;
730 abnode->volKillSent = 0;
731 } else if (aproc == abnode->fileProc) {
732 /* if we were expecting a shutdown and we didn't send a kill signal
733 * and exited (didn't have a signal termination), then we assume that
734 * the file server exited after putting the appropriate volumes safely
735 * offline, and don't salvage next time.
737 if (abnode->fileSDW && !abnode->fileKillSent
738 && aproc->lastSignal == 0)
739 SetSalFlag(abnode, 0); /* shut down normally */
740 abnode->fileProc = 0;
741 abnode->fileRunning = 0;
743 abnode->fileKillSent = 0;
744 } else if (aproc == abnode->salProc) {
745 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
746 * that we don't have to salvage again */
748 SetSalFlag(abnode, 0); /* salvage just completed */
750 abnode->salRunning = 0;
752 abnode->salKillSent = 0;
753 } else if (aproc == abnode->scanProc) {
754 abnode->scanProc = 0;
755 abnode->scanRunning = 0;
757 abnode->scanKillSent = 0;
758 } else if (aproc == abnode->salsrvProc) {
759 abnode->salsrvProc = 0;
760 abnode->salsrvRunning = 0;
761 abnode->salsrvSDW = 0;
762 abnode->salsrvKillSent = 0;
765 /* now restart anyone who needs to restart */
766 return NudgeProcs(abnode);
769 /* make sure we're periodically checking the state if we need to */
771 SetNeedsClock(struct fsbnode *ab)
773 afs_int32 timeout = POLLTIME;
775 if ((ab->fileSDW && !ab->fileKillSent) || (ab->volSDW && !ab->volKillSent)
776 || (ab->scanSDW && !ab->scanKillSent) || (ab->salSDW && !ab->salKillSent)
777 || (ab->salsrvSDW && !ab->salsrvKillSent)) {
778 /* SIGQUIT sent, will send SIGKILL if process does not exit */
780 } else if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
781 && (!ab->scancmd || ab->scanRunning)
782 && (!ab->salsrvcmd || ab->salsrvRunning)) {
783 if (ab->b.errorStopCount) {
784 /* reset error count after running for a bit */
787 ab->needsClock = 0; /* running normally */
789 } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
790 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
791 if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
792 bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
793 ab->b.errorStopDelay);
794 ab->needsClock = 1; /* halted for errors, retry later */
795 timeout = ab->b.errorStopDelay;
797 ab->needsClock = 0; /* halted normally */
800 ab->needsClock = 1; /* other */
802 if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
803 || ab->b.period != timeout))
804 bnode_SetTimeout(fsbnode2bnode(ab), timeout);
806 bnode_SetTimeout(fsbnode2bnode(ab), 0);
810 NudgeProcs(struct fsbnode *abnode)
812 struct bnode_proc *tp; /* not register */
816 now = FT_ApproxTime();
817 if (abnode->b.goal == 1) {
818 /* we're trying to run the system. If the file server is running, then we
819 * are trying to start up the system. If it is not running, then needsSalvage
820 * tells us if we need to run the salvager or not */
821 if (abnode->fileRunning) {
822 if (abnode->salRunning) {
823 bozo_Log("Salvager running along with file server!\n");
824 bozo_Log("Emergency shutdown\n");
826 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
827 bnode_StopProc(abnode->salProc, SIGKILL);
828 SetNeedsClock(abnode);
831 if (!abnode->volRunning) {
832 abnode->lastVolStart = FT_ApproxTime();
833 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
835 abnode->volProc = tp;
836 abnode->volRunning = 1;
839 if (abnode->salsrvcmd) {
840 if (!abnode->salsrvRunning) {
841 abnode->lastSalsrvStart = FT_ApproxTime();
843 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
846 abnode->salsrvProc = tp;
847 abnode->salsrvRunning = 1;
851 if (abnode->scancmd) {
852 if (!abnode->scanRunning) {
853 abnode->lastScanStart = FT_ApproxTime();
855 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
858 abnode->scanProc = tp;
859 abnode->scanRunning = 1;
863 } else { /* file is not running */
864 /* see how to start */
865 /* for demand attach fs, needsSalvage flag is ignored */
866 if (!abnode->needsSalvage || abnode->salsrvcmd) {
867 /* no crash apparent, just start up normally */
868 if (!abnode->fileRunning) {
869 abnode->lastFileStart = FT_ApproxTime();
871 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
873 abnode->fileProc = tp;
874 abnode->fileRunning = 1;
875 SetSalFlag(abnode, 1);
878 if (!abnode->volRunning) {
879 abnode->lastVolStart = FT_ApproxTime();
880 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
882 abnode->volProc = tp;
883 abnode->volRunning = 1;
886 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
887 abnode->lastSalsrvStart = FT_ApproxTime();
889 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
892 abnode->salsrvProc = tp;
893 abnode->salsrvRunning = 1;
896 if (abnode->scancmd && !abnode->scanRunning) {
897 abnode->lastScanStart = FT_ApproxTime();
899 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
902 abnode->scanProc = tp;
903 abnode->scanRunning = 1;
906 } else { /* needs to be salvaged */
907 /* make sure file server and volser are gone */
908 if (abnode->volRunning) {
909 bnode_StopProc(abnode->volProc, SIGTERM);
911 abnode->timeSDStarted = now;
914 if (abnode->fileRunning) {
915 bnode_StopProc(abnode->fileProc, SIGQUIT);
916 if (!abnode->fileSDW)
917 abnode->timeSDStarted = now;
920 if (abnode->scanRunning) {
921 bnode_StopProc(abnode->scanProc, SIGTERM);
922 if (!abnode->scanSDW)
923 abnode->timeSDStarted = now;
926 if (abnode->volRunning || abnode->fileRunning
927 || abnode->scanRunning)
929 /* otherwise, it is safe to start salvager */
930 if (!abnode->salRunning) {
931 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
933 abnode->salProc = tp;
934 abnode->salRunning = 1;
939 } else { /* goal is 0, we're shutting down */
940 /* trying to shutdown */
941 if (abnode->salRunning && !abnode->salSDW) {
942 bnode_StopProc(abnode->salProc, SIGTERM);
944 abnode->timeSDStarted = now;
946 if (abnode->fileRunning && !abnode->fileSDW) {
947 bnode_StopProc(abnode->fileProc, SIGQUIT);
949 abnode->timeSDStarted = now;
951 if (abnode->volRunning && !abnode->volSDW) {
952 bnode_StopProc(abnode->volProc, SIGTERM);
954 abnode->timeSDStarted = now;
956 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
957 bnode_StopProc(abnode->salsrvProc, SIGTERM);
958 abnode->salsrvSDW = 1;
959 abnode->timeSDStarted = now;
961 if (abnode->scanRunning && !abnode->scanSDW) {
962 bnode_StopProc(abnode->scanProc, SIGTERM);
964 abnode->timeSDStarted = now;
967 SetNeedsClock(abnode);
972 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
974 struct fsbnode *abnode = (struct fsbnode *)bn;
978 if (abnode->b.goal == 1) {
979 if (abnode->fileRunning) {
981 strcpy(abuffer, "file server shutting down");
982 else if (abnode->scancmd) {
983 if (!abnode->volRunning && !abnode->scanRunning)
985 "file server up; volser and scanner down");
986 else if (abnode->volRunning && !abnode->scanRunning)
988 "file server up; volser up; scanner down");
989 else if (!abnode->volRunning && abnode->scanRunning)
991 "file server up; volser down; scanner up");
994 strcpy(abuffer, "file server running");
995 } else if (!abnode->volRunning)
996 strcpy(abuffer, "file server up; volser down");
998 strcpy(abuffer, "file server running");
999 } else if (abnode->salRunning) {
1000 strcpy(abuffer, "salvaging file system");
1002 strcpy(abuffer, "starting file server");
1005 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
1006 strcpy(abuffer, "file server shutting down");
1007 } else if (abnode->salRunning)
1008 strcpy(abuffer, "salvager shutting down");
1010 strcpy(abuffer, "file server shut down");
1016 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1019 struct fsbnode *abnode = (struct fsbnode *)bn;
1022 strcpy(abuffer, abnode->filecmd);
1023 else if (aindex == 1)
1024 strcpy(abuffer, abnode->volcmd);
1025 else if (aindex == 2)
1026 strcpy(abuffer, abnode->salcmd);
1027 else if (aindex == 3 && abnode->scancmd)
1028 strcpy(abuffer, abnode->scancmd);
1035 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1038 struct fsbnode *abnode = (struct fsbnode *)bn;
1041 strcpy(abuffer, abnode->filecmd);
1042 else if (aindex == 1)
1043 strcpy(abuffer, abnode->volcmd);
1044 else if (aindex == 2)
1045 strcpy(abuffer, abnode->salsrvcmd);
1046 else if (aindex == 3)
1047 strcpy(abuffer, abnode->salcmd);
1048 else if (aindex == 4 && abnode->scancmd)
1049 strcpy(abuffer, abnode->scancmd);