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;
328 fs_delete(struct bnode *bn)
330 struct fsbnode *abnode = (struct fsbnode *)bn;
332 free(abnode->filecmd);
333 free(abnode->volcmd);
334 free(abnode->salcmd);
335 if (abnode->salsrvcmd)
336 free(abnode->salsrvcmd);
338 free(abnode->scancmd);
346 AppendExecutableExtension(char *cmd)
348 char cmdext[_MAX_EXT];
350 _splitpath(cmd, NULL, NULL, NULL, cmdext);
351 if (*cmdext == '\0') {
352 /* no filename extension supplied for cmd; append .exe */
356 #endif /* AFS_NT40_ENV */
360 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
361 char *ascancmd, char *dummy)
365 char cmdname[AFSDIR_PATH_MAX];
366 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
369 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
372 /* construct local paths from canonical (wire-format) paths */
373 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
374 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
378 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
379 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
383 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
384 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
389 if (ascancmd && strlen(ascancmd)) {
390 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
391 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
398 sscanf(fileCmdpath, "%s", cmdname);
399 AppendExecutableExtension(cmdname);
400 if (stat(cmdname, &tstat)) {
401 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
406 sscanf(volCmdpath, "%s", cmdname);
407 AppendExecutableExtension(cmdname);
408 if (stat(cmdname, &tstat)) {
409 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
414 sscanf(salCmdpath, "%s", cmdname);
415 AppendExecutableExtension(cmdname);
416 if (stat(cmdname, &tstat)) {
417 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
422 if (ascancmd && strlen(ascancmd)) {
423 sscanf(scanCmdpath, "%s", cmdname);
424 AppendExecutableExtension(cmdname);
425 if (stat(cmdname, &tstat)) {
426 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
433 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
438 memset(te, 0, 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 = (struct fsbnode *)malloc(sizeof(struct fsbnode));
567 memset(te, 0, sizeof(struct fsbnode));
568 te->filecmd = fileCmdpath;
569 te->volcmd = volCmdpath;
570 te->salsrvcmd = salsrvCmdpath;
571 te->salcmd = salCmdpath;
572 if (ascancmd && strlen(ascancmd))
573 te->scancmd = scanCmdpath;
576 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
580 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
581 /* ask for timeout activations every 20 seconds */
582 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
583 SetNeedsClock(te); /* compute needsClock field */
602 return fsbnode2bnode(te);
605 /* called to SIGKILL a process if it doesn't terminate normally */
607 fs_timeout(struct bnode *bn)
609 struct fsbnode *abnode = (struct fsbnode *)bn;
613 now = FT_ApproxTime();
615 if (abnode->volSDW) {
616 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
617 bnode_StopProc(abnode->volProc, SIGKILL);
618 abnode->volKillSent = 1;
620 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
624 if (abnode->salSDW) {
625 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
626 bnode_StopProc(abnode->salProc, SIGKILL);
627 abnode->salKillSent = 1;
629 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
633 if (abnode->fileSDW) {
634 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
635 bnode_StopProc(abnode->fileProc, SIGKILL);
636 abnode->fileKillSent = 1;
638 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
642 if (abnode->salsrvSDW) {
643 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
644 bnode_StopProc(abnode->salsrvProc, SIGKILL);
645 abnode->salsrvKillSent = 1;
647 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
651 if (abnode->scanSDW) {
652 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
653 bnode_StopProc(abnode->scanProc, SIGKILL);
654 abnode->scanKillSent = 1;
656 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
661 if ((abnode->b.flags & BNODE_ERRORSTOP) && !abnode->salRunning
662 && !abnode->volRunning && !abnode->fileRunning && !abnode->scanRunning
663 && !abnode->salsrvRunning) {
664 bnode_SetStat(bn, BSTAT_NORMAL);
667 bnode_ResetErrorCount(bn);
670 SetNeedsClock(abnode);
675 fs_getstat(struct bnode *bn, afs_int32 * astatus)
677 struct fsbnode *abnode = (struct fsbnode *) bn;
680 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
681 || abnode->scanSDW || abnode->salsrvSDW)
682 temp = BSTAT_SHUTTINGDOWN;
683 else if (abnode->salRunning)
685 else if (abnode->volRunning && abnode->fileRunning
686 && (!abnode->scancmd || abnode->scanRunning)
687 && (!abnode->salsrvcmd || abnode->salsrvRunning))
689 else if (!abnode->salRunning && !abnode->volRunning
690 && !abnode->fileRunning && !abnode->scanRunning
691 && !abnode->salsrvRunning)
692 temp = BSTAT_SHUTDOWN;
694 temp = BSTAT_STARTINGUP;
700 fs_setstat(struct bnode *abnode, afs_int32 astatus)
702 return NudgeProcs((struct fsbnode *) abnode);
706 fs_procstarted(struct bnode *bn, struct bnode_proc *aproc)
711 code = bozo_CreatePidFile(bn->name, aproc->coreName, aproc->pid);
717 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
719 struct fsbnode *abnode = (struct fsbnode *)bn;
721 /* process has exited */
724 bozo_DeletePidFile(bn->name, aproc->coreName);
727 if (aproc == abnode->volProc) {
729 abnode->volRunning = 0;
731 abnode->volKillSent = 0;
732 } else if (aproc == abnode->fileProc) {
733 /* if we were expecting a shutdown and we didn't send a kill signal
734 * and exited (didn't have a signal termination), then we assume that
735 * the file server exited after putting the appropriate volumes safely
736 * offline, and don't salvage next time.
738 if (abnode->fileSDW && !abnode->fileKillSent
739 && aproc->lastSignal == 0)
740 SetSalFlag(abnode, 0); /* shut down normally */
741 abnode->fileProc = 0;
742 abnode->fileRunning = 0;
744 abnode->fileKillSent = 0;
745 } else if (aproc == abnode->salProc) {
746 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
747 * that we don't have to salvage again */
749 SetSalFlag(abnode, 0); /* salvage just completed */
751 abnode->salRunning = 0;
753 abnode->salKillSent = 0;
754 } else if (aproc == abnode->scanProc) {
755 abnode->scanProc = 0;
756 abnode->scanRunning = 0;
758 abnode->scanKillSent = 0;
759 } else if (aproc == abnode->salsrvProc) {
760 abnode->salsrvProc = 0;
761 abnode->salsrvRunning = 0;
762 abnode->salsrvSDW = 0;
763 abnode->salsrvKillSent = 0;
766 /* now restart anyone who needs to restart */
767 return NudgeProcs(abnode);
770 /* make sure we're periodically checking the state if we need to */
772 SetNeedsClock(struct fsbnode *ab)
774 afs_int32 timeout = POLLTIME;
776 if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
777 && (!ab->scancmd || ab->scanRunning)
778 && (!ab->salsrvcmd || ab->salsrvRunning)) {
779 if (ab->b.errorStopCount) {
780 /* reset error count after running for a bit */
783 ab->needsClock = 0; /* running normally */
785 } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
786 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
787 if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
788 bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
789 ab->b.errorStopDelay);
790 ab->needsClock = 1; /* halted for errors, retry later */
791 timeout = ab->b.errorStopDelay;
793 ab->needsClock = 0; /* halted normally */
796 ab->needsClock = 1; /* other */
798 if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
799 || ab->b.period != timeout))
800 bnode_SetTimeout(fsbnode2bnode(ab), timeout);
802 bnode_SetTimeout(fsbnode2bnode(ab), 0);
806 NudgeProcs(struct fsbnode *abnode)
808 struct bnode_proc *tp; /* not register */
812 now = FT_ApproxTime();
813 if (abnode->b.goal == 1) {
814 /* we're trying to run the system. If the file server is running, then we
815 * are trying to start up the system. If it is not running, then needsSalvage
816 * tells us if we need to run the salvager or not */
817 if (abnode->fileRunning) {
818 if (abnode->salRunning) {
819 bozo_Log("Salvager running along with file server!\n");
820 bozo_Log("Emergency shutdown\n");
822 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
823 bnode_StopProc(abnode->salProc, SIGKILL);
824 SetNeedsClock(abnode);
827 if (!abnode->volRunning) {
828 abnode->lastVolStart = FT_ApproxTime();
829 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
831 abnode->volProc = tp;
832 abnode->volRunning = 1;
835 if (abnode->salsrvcmd) {
836 if (!abnode->salsrvRunning) {
837 abnode->lastSalsrvStart = FT_ApproxTime();
839 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
842 abnode->salsrvProc = tp;
843 abnode->salsrvRunning = 1;
847 if (abnode->scancmd) {
848 if (!abnode->scanRunning) {
849 abnode->lastScanStart = FT_ApproxTime();
851 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
854 abnode->scanProc = tp;
855 abnode->scanRunning = 1;
859 } else { /* file is not running */
860 /* see how to start */
861 /* for demand attach fs, needsSalvage flag is ignored */
862 if (!abnode->needsSalvage || abnode->salsrvcmd) {
863 /* no crash apparent, just start up normally */
864 if (!abnode->fileRunning) {
865 abnode->lastFileStart = FT_ApproxTime();
867 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
869 abnode->fileProc = tp;
870 abnode->fileRunning = 1;
871 SetSalFlag(abnode, 1);
874 if (!abnode->volRunning) {
875 abnode->lastVolStart = FT_ApproxTime();
876 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
878 abnode->volProc = tp;
879 abnode->volRunning = 1;
882 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
883 abnode->lastSalsrvStart = FT_ApproxTime();
885 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
888 abnode->salsrvProc = tp;
889 abnode->salsrvRunning = 1;
892 if (abnode->scancmd && !abnode->scanRunning) {
893 abnode->lastScanStart = FT_ApproxTime();
895 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
898 abnode->scanProc = tp;
899 abnode->scanRunning = 1;
902 } else { /* needs to be salvaged */
903 /* make sure file server and volser are gone */
904 if (abnode->volRunning) {
905 bnode_StopProc(abnode->volProc, SIGTERM);
907 abnode->timeSDStarted = now;
910 if (abnode->fileRunning) {
911 bnode_StopProc(abnode->fileProc, SIGQUIT);
912 if (!abnode->fileSDW)
913 abnode->timeSDStarted = now;
916 if (abnode->scanRunning) {
917 bnode_StopProc(abnode->scanProc, SIGTERM);
918 if (!abnode->scanSDW)
919 abnode->timeSDStarted = now;
922 if (abnode->volRunning || abnode->fileRunning
923 || abnode->scanRunning)
925 /* otherwise, it is safe to start salvager */
926 if (!abnode->salRunning) {
927 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
929 abnode->salProc = tp;
930 abnode->salRunning = 1;
935 } else { /* goal is 0, we're shutting down */
936 /* trying to shutdown */
937 if (abnode->salRunning && !abnode->salSDW) {
938 bnode_StopProc(abnode->salProc, SIGTERM);
940 abnode->timeSDStarted = now;
942 if (abnode->fileRunning && !abnode->fileSDW) {
943 bnode_StopProc(abnode->fileProc, SIGQUIT);
945 abnode->timeSDStarted = now;
947 if (abnode->volRunning && !abnode->volSDW) {
948 bnode_StopProc(abnode->volProc, SIGTERM);
950 abnode->timeSDStarted = now;
952 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
953 bnode_StopProc(abnode->salsrvProc, SIGTERM);
954 abnode->salsrvSDW = 1;
955 abnode->timeSDStarted = now;
957 if (abnode->scanRunning && !abnode->scanSDW) {
958 bnode_StopProc(abnode->scanProc, SIGTERM);
960 abnode->timeSDStarted = now;
963 SetNeedsClock(abnode);
968 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
970 struct fsbnode *abnode = (struct fsbnode *)bn;
974 if (abnode->b.goal == 1) {
975 if (abnode->fileRunning) {
977 strcpy(abuffer, "file server shutting down");
978 else if (abnode->scancmd) {
979 if (!abnode->volRunning && !abnode->scanRunning)
981 "file server up; volser and scanner down");
982 else if (abnode->volRunning && !abnode->scanRunning)
984 "file server up; volser up; scanner down");
985 else if (!abnode->volRunning && abnode->scanRunning)
987 "file server up; volser down; scanner up");
990 strcpy(abuffer, "file server running");
991 } else if (!abnode->volRunning)
992 strcpy(abuffer, "file server up; volser down");
994 strcpy(abuffer, "file server running");
995 } else if (abnode->salRunning) {
996 strcpy(abuffer, "salvaging file system");
998 strcpy(abuffer, "starting file server");
1001 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
1002 strcpy(abuffer, "file server shutting down");
1003 } else if (abnode->salRunning)
1004 strcpy(abuffer, "salvager shutting down");
1006 strcpy(abuffer, "file server shut down");
1012 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1015 struct fsbnode *abnode = (struct fsbnode *)bn;
1018 strcpy(abuffer, abnode->filecmd);
1019 else if (aindex == 1)
1020 strcpy(abuffer, abnode->volcmd);
1021 else if (aindex == 2)
1022 strcpy(abuffer, abnode->salcmd);
1023 else if (aindex == 3 && abnode->scancmd)
1024 strcpy(abuffer, abnode->scancmd);
1031 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1034 struct fsbnode *abnode = (struct fsbnode *)bn;
1037 strcpy(abuffer, abnode->filecmd);
1038 else if (aindex == 1)
1039 strcpy(abuffer, abnode->volcmd);
1040 else if (aindex == 2)
1041 strcpy(abuffer, abnode->salsrvcmd);
1042 else if (aindex == 3)
1043 strcpy(abuffer, abnode->salcmd);
1044 else if (aindex == 4 && abnode->scancmd)
1045 strcpy(abuffer, abnode->scancmd);