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>
14 #include <sys/types.h>
31 #endif /* AFS_NT40_ENV */
33 #include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
34 #include <afs/afsutil.h>
36 #include "bosprototypes.h"
38 static int emergency = 0;
40 /* if this file exists, then we have to salvage the file system */
41 #define SALFILE "SALVAGE."
43 #define POLLTIME 20 /* for handling below */
44 #define SDTIME 60 /* time in seconds given to a process to evaporate */
47 Normal operation involves having the file server and the vol server both running.
49 If the vol server terminates, it can simply be restarted.
51 If the file server terminates, the disk must salvaged before the file server
52 can be restarted. In order to restart either the file server or the salvager,
53 the vol server must be shut down.
55 If the file server terminates *normally* (exits after receiving a SIGQUIT)
56 then we don't have to salvage it.
58 The needsSalvage flag is set when the file server is started. It is cleared
59 if the file server exits when fileSDW is true but fileKillSent is false,
60 indicating that it exited after receiving a quit, but before we sent it a kill.
62 The needsSalvage flag is cleared when the salvager exits.
67 afs_int32 timeSDStarted; /* time shutdown operation started */
68 char *filecmd; /* command to start primary file server */
69 char *volcmd; /* command to start secondary vol server */
70 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
71 char *salcmd; /* command to start salvager */
72 char *scancmd; /* command to start scanner (MR-AFS) */
73 struct bnode_proc *fileProc; /* process for file server */
74 struct bnode_proc *volProc; /* process for vol server */
75 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
76 struct bnode_proc *salProc; /* process for salvager */
77 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
78 afs_int32 lastFileStart; /* last start for file */
79 afs_int32 lastVolStart; /* last start for vol */
80 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
81 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
82 char fileRunning; /* file process is running */
83 char volRunning; /* volser is running */
84 char salsrvRunning; /* salvageserver is running (demand attach fs) */
85 char salRunning; /* salvager is running */
86 char scanRunning; /* scanner is running (MR_AFS) */
87 char fileSDW; /* file shutdown wait */
88 char volSDW; /* vol shutdown wait */
89 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
90 char salSDW; /* waiting for the salvager to shutdown */
91 char scanSDW; /* scanner shutdown wait (MR_AFS) */
92 char fileKillSent; /* kill signal has been sent */
94 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
96 char scanKillSent; /* kill signal has been sent (MR_AFS) */
97 char needsSalvage; /* salvage before running */
98 char needsClock; /* do we need clock ticks */
101 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
102 char *asalcmd, char *ascancmd, char *dummy);
103 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
104 char * asalsrvcmd, char *asalcmd, char *ascancmd);
106 static int fs_hascore(struct bnode *abnode);
107 static int fs_restartp(struct bnode *abnode);
108 static int fs_delete(struct bnode *abnode);
109 static int fs_timeout(struct bnode *abnode);
110 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
111 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
112 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
113 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
114 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
115 char *abuffer, afs_int32 alen);
116 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
117 char *abuffer, afs_int32 alen);
119 static int SetSalFlag(struct fsbnode *abnode, int aflag);
120 static int RestoreSalFlag(struct fsbnode *abnode);
121 static void SetNeedsClock(struct fsbnode *);
122 static int NudgeProcs(struct fsbnode *);
125 static void AppendExecutableExtension(char *cmd);
127 #define AppendExecutableExtension(x)
130 struct bnode_ops fsbnode_ops = {
143 /* demand attach fs bnode ops */
144 struct bnode_ops dafsbnode_ops = {
157 /* Quick inline function to safely convert a fsbnode to a bnode without
158 * dropping type information
161 static_inline struct bnode * fsbnode2bnode(struct fsbnode *abnode) {
162 return (struct bnode *) abnode;
165 /* Function to tell whether this bnode has a core file or not. You might
166 * think that this could be in bnode.c, and decide what core files to check
167 * for based on the bnode's coreName property, but that doesn't work because
168 * there may not be an active process for a bnode that dumped core at the
169 * time the query is done.
172 fs_hascore(struct bnode *abnode)
176 /* see if file server has a core file */
177 bnode_CoreName(abnode, "file", tbuffer);
178 if (access(tbuffer, 0) == 0)
181 /* see if volserver has a core file */
182 bnode_CoreName(abnode, "vol", tbuffer);
183 if (access(tbuffer, 0) == 0)
186 /* see if salvageserver left a core file */
187 bnode_CoreName(abnode, "salsrv", tbuffer);
188 if (access(tbuffer, 0) == 0)
191 /* see if salvager left a core file */
192 bnode_CoreName(abnode, "salv", tbuffer);
193 if (access(tbuffer, 0) == 0)
196 /* see if scanner left a core file (MR-AFS) */
197 bnode_CoreName(abnode, "scan", tbuffer);
198 if (access(tbuffer, 0) == 0)
201 /* no one left a core file */
206 fs_restartp(struct bnode *bn)
208 struct fsbnode *abnode = (struct fsbnode *)bn;
209 struct bnode_token *tt;
210 register afs_int32 code;
213 code = bnode_ParseLine(abnode->filecmd, &tt);
218 code = stat(tt->key, &tstat);
220 bnode_FreeTokens(tt);
223 if (tstat.st_ctime > abnode->lastFileStart)
227 bnode_FreeTokens(tt);
231 /* now do same for volcmd */
232 code = bnode_ParseLine(abnode->volcmd, &tt);
237 code = stat(tt->key, &tstat);
239 bnode_FreeTokens(tt);
242 if (tstat.st_ctime > abnode->lastVolStart)
246 bnode_FreeTokens(tt);
250 if (abnode->salsrvcmd) { /* only in demand attach fs */
251 /* now do same for salsrvcmd (demand attach fs) */
252 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
257 code = stat(tt->key, &tstat);
259 bnode_FreeTokens(tt);
262 if (tstat.st_ctime > abnode->lastScanStart)
266 bnode_FreeTokens(tt);
269 if (abnode->scancmd) { /* Only in MR-AFS */
270 /* now do same for scancmd (MR-AFS) */
271 code = bnode_ParseLine(abnode->scancmd, &tt);
276 code = stat(tt->key, &tstat);
278 bnode_FreeTokens(tt);
281 if (tstat.st_ctime > abnode->lastScanStart)
285 bnode_FreeTokens(tt);
291 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
292 we need to salvage the file system (so we can tell over panic reboots */
294 SetSalFlag(register struct fsbnode *abnode, register int aflag)
296 char tbuffer[AFSDIR_PATH_MAX];
299 /* don't use the salvage flag for demand attach fs */
300 if (abnode->salsrvcmd == NULL) {
301 abnode->needsSalvage = aflag;
302 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
303 SALFILE, abnode->b.name, NULL);
305 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
314 /* set the needsSalvage flag according to the existence of the salvage file */
316 RestoreSalFlag(register struct fsbnode *abnode)
318 char tbuffer[AFSDIR_PATH_MAX];
320 /* never set needs salvage flag for demand attach fs */
321 if (abnode->salsrvcmd != NULL) {
322 abnode->needsSalvage = 0;
324 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
325 SALFILE, abnode->b.name, NULL);
326 if (access(tbuffer, 0) == 0) {
327 /* file exists, so need to salvage */
328 abnode->needsSalvage = 1;
330 abnode->needsSalvage = 0;
337 copystr(register char *a)
340 b = (char *)malloc(strlen(a) + 1);
346 fs_delete(struct bnode *bn)
348 struct fsbnode *abnode = (struct fsbnode *)bn;
350 free(abnode->filecmd);
351 free(abnode->volcmd);
352 free(abnode->salcmd);
353 if (abnode->salsrvcmd)
354 free(abnode->salsrvcmd);
356 free(abnode->scancmd);
364 AppendExecutableExtension(char *cmd)
366 char cmdext[_MAX_EXT];
368 _splitpath(cmd, NULL, NULL, NULL, cmdext);
369 if (*cmdext == '\0') {
370 /* no filename extension supplied for cmd; append .exe */
374 #endif /* AFS_NT40_ENV */
378 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
379 char *ascancmd, char *dummy)
382 register struct fsbnode *te;
383 char cmdname[AFSDIR_PATH_MAX];
384 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
387 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
390 /* construct local paths from canonical (wire-format) paths */
391 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
392 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
396 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
397 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
401 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
402 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
407 if (ascancmd && strlen(ascancmd)) {
408 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
409 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
416 sscanf(fileCmdpath, "%s", cmdname);
417 AppendExecutableExtension(cmdname);
418 if (stat(cmdname, &tstat)) {
419 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
424 sscanf(volCmdpath, "%s", cmdname);
425 AppendExecutableExtension(cmdname);
426 if (stat(cmdname, &tstat)) {
427 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
432 sscanf(salCmdpath, "%s", cmdname);
433 AppendExecutableExtension(cmdname);
434 if (stat(cmdname, &tstat)) {
435 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
440 if (ascancmd && strlen(ascancmd)) {
441 sscanf(scanCmdpath, "%s", cmdname);
442 AppendExecutableExtension(cmdname);
443 if (stat(cmdname, &tstat)) {
444 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
451 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
456 memset(te, 0, sizeof(struct fsbnode));
457 te->filecmd = fileCmdpath;
458 te->volcmd = volCmdpath;
459 te->salsrvcmd = NULL;
460 te->salcmd = salCmdpath;
461 if (ascancmd && strlen(ascancmd))
462 te->scancmd = scanCmdpath;
465 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
469 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
470 /* ask for timeout activations every 10 seconds */
471 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
472 SetNeedsClock(te); /* compute needsClock field */
489 return fsbnode2bnode(te);
492 /* create a demand attach fs bnode */
494 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
495 char * asalsrvcmd, char *asalcmd, char *ascancmd)
498 register struct fsbnode *te;
499 char cmdname[AFSDIR_PATH_MAX];
500 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
503 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
506 /* construct local paths from canonical (wire-format) paths */
507 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
508 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
512 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
513 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
517 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
518 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
522 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
523 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
528 if (ascancmd && strlen(ascancmd)) {
529 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
530 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
537 sscanf(fileCmdpath, "%s", cmdname);
538 AppendExecutableExtension(cmdname);
539 if (stat(cmdname, &tstat)) {
540 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
545 sscanf(volCmdpath, "%s", cmdname);
546 AppendExecutableExtension(cmdname);
547 if (stat(cmdname, &tstat)) {
548 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
553 sscanf(salsrvCmdpath, "%s", cmdname);
554 AppendExecutableExtension(cmdname);
555 if (stat(cmdname, &tstat)) {
556 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
561 sscanf(salCmdpath, "%s", cmdname);
562 AppendExecutableExtension(cmdname);
563 if (stat(cmdname, &tstat)) {
564 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
569 if (ascancmd && strlen(ascancmd)) {
570 sscanf(scanCmdpath, "%s", cmdname);
571 AppendExecutableExtension(cmdname);
572 if (stat(cmdname, &tstat)) {
573 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
580 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
585 memset(te, 0, sizeof(struct fsbnode));
586 te->filecmd = fileCmdpath;
587 te->volcmd = volCmdpath;
588 te->salsrvcmd = salsrvCmdpath;
589 te->salcmd = salCmdpath;
590 if (ascancmd && strlen(ascancmd))
591 te->scancmd = scanCmdpath;
594 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
598 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
599 /* ask for timeout activations every 10 seconds */
600 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
601 SetNeedsClock(te); /* compute needsClock field */
620 return fsbnode2bnode(te);
623 /* called to SIGKILL a process if it doesn't terminate normally */
625 fs_timeout(struct bnode *bn)
627 struct fsbnode *abnode = (struct fsbnode *)bn;
629 register afs_int32 now;
631 now = FT_ApproxTime();
633 if (abnode->volSDW) {
634 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
635 bnode_StopProc(abnode->volProc, SIGKILL);
636 abnode->volKillSent = 1;
638 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
642 if (abnode->salSDW) {
643 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
644 bnode_StopProc(abnode->salProc, SIGKILL);
645 abnode->salKillSent = 1;
647 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
651 if (abnode->fileSDW) {
652 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
653 bnode_StopProc(abnode->fileProc, SIGKILL);
654 abnode->fileKillSent = 1;
656 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
660 if (abnode->salsrvSDW) {
661 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
662 bnode_StopProc(abnode->salsrvProc, SIGKILL);
663 abnode->salsrvKillSent = 1;
665 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
669 if (abnode->scanSDW) {
670 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
671 bnode_StopProc(abnode->scanProc, SIGKILL);
672 abnode->scanKillSent = 1;
674 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
678 SetNeedsClock(abnode);
683 fs_getstat(struct bnode *bn, afs_int32 * astatus)
685 struct fsbnode *abnode = (struct fsbnode *) bn;
687 register afs_int32 temp;
688 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
689 || abnode->scanSDW || abnode->salsrvSDW)
690 temp = BSTAT_SHUTTINGDOWN;
691 else if (abnode->salRunning)
693 else if (abnode->volRunning && abnode->fileRunning
694 && (!abnode->scancmd || abnode->scanRunning)
695 && (!abnode->salsrvcmd || abnode->salsrvRunning))
697 else if (!abnode->salRunning && !abnode->volRunning
698 && !abnode->fileRunning && !abnode->scanRunning
699 && !abnode->salsrvRunning)
700 temp = BSTAT_SHUTDOWN;
702 temp = BSTAT_STARTINGUP;
708 fs_setstat(struct bnode *abnode, afs_int32 astatus)
710 return NudgeProcs((struct fsbnode *) abnode);
714 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
716 struct fsbnode *abnode = (struct fsbnode *)bn;
718 /* process has exited */
720 if (aproc == abnode->volProc) {
722 abnode->volRunning = 0;
724 abnode->volKillSent = 0;
725 } else if (aproc == abnode->fileProc) {
726 /* if we were expecting a shutdown and we didn't send a kill signal
727 * and exited (didn't have a signal termination), then we assume that
728 * the file server exited after putting the appropriate volumes safely
729 * offline, and don't salvage next time.
731 if (abnode->fileSDW && !abnode->fileKillSent
732 && aproc->lastSignal == 0)
733 SetSalFlag(abnode, 0); /* shut down normally */
734 abnode->fileProc = 0;
735 abnode->fileRunning = 0;
737 abnode->fileKillSent = 0;
738 } else if (aproc == abnode->salProc) {
739 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
740 * that we don't have to salvage again */
742 SetSalFlag(abnode, 0); /* salvage just completed */
744 abnode->salRunning = 0;
746 abnode->salKillSent = 0;
747 } else if (aproc == abnode->scanProc) {
748 abnode->scanProc = 0;
749 abnode->scanRunning = 0;
751 abnode->scanKillSent = 0;
752 } else if (aproc == abnode->salsrvProc) {
753 abnode->salsrvProc = 0;
754 abnode->salsrvRunning = 0;
755 abnode->salsrvSDW = 0;
756 abnode->salsrvKillSent = 0;
759 /* now restart anyone who needs to restart */
760 return NudgeProcs(abnode);
763 /* make sure we're periodically checking the state if we need to */
765 SetNeedsClock(register struct fsbnode *ab)
767 if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
768 && (!ab->scancmd || ab->scanRunning)
769 && (!ab->salsrvcmd || ab->salsrvRunning))
770 ab->needsClock = 0; /* running normally */
771 else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning
772 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning)
773 ab->needsClock = 0; /* halted normally */
775 ab->needsClock = 1; /* other */
776 if (ab->needsClock && !bnode_PendingTimeout(fsbnode2bnode(ab)))
777 bnode_SetTimeout(fsbnode2bnode(ab), POLLTIME);
779 bnode_SetTimeout(fsbnode2bnode(ab), 0);
783 NudgeProcs(register struct fsbnode *abnode)
785 struct bnode_proc *tp; /* not register */
786 register afs_int32 code;
789 now = FT_ApproxTime();
790 if (abnode->b.goal == 1) {
791 /* we're trying to run the system. If the file server is running, then we
792 * are trying to start up the system. If it is not running, then needsSalvage
793 * tells us if we need to run the salvager or not */
794 if (abnode->fileRunning) {
795 if (abnode->salRunning) {
796 bozo_Log("Salvager running along with file server!\n");
797 bozo_Log("Emergency shutdown\n");
799 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
800 bnode_StopProc(abnode->salProc, SIGKILL);
801 SetNeedsClock(abnode);
804 if (!abnode->volRunning) {
805 abnode->lastVolStart = FT_ApproxTime();
806 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
808 abnode->volProc = tp;
809 abnode->volRunning = 1;
812 if (abnode->salsrvcmd) {
813 if (!abnode->salsrvRunning) {
814 abnode->lastSalsrvStart = FT_ApproxTime();
816 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
819 abnode->salsrvProc = tp;
820 abnode->salsrvRunning = 1;
824 if (abnode->scancmd) {
825 if (!abnode->scanRunning) {
826 abnode->lastScanStart = FT_ApproxTime();
828 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
831 abnode->scanProc = tp;
832 abnode->scanRunning = 1;
836 } else { /* file is not running */
837 /* see how to start */
838 /* for demand attach fs, needsSalvage flag is ignored */
839 if (!abnode->needsSalvage || abnode->salsrvcmd) {
840 /* no crash apparent, just start up normally */
841 if (!abnode->fileRunning) {
842 abnode->lastFileStart = FT_ApproxTime();
844 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
846 abnode->fileProc = tp;
847 abnode->fileRunning = 1;
848 SetSalFlag(abnode, 1);
851 if (!abnode->volRunning) {
852 abnode->lastVolStart = FT_ApproxTime();
853 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
855 abnode->volProc = tp;
856 abnode->volRunning = 1;
859 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
860 abnode->lastSalsrvStart = FT_ApproxTime();
862 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
865 abnode->salsrvProc = tp;
866 abnode->salsrvRunning = 1;
869 if (abnode->scancmd && !abnode->scanRunning) {
870 abnode->lastScanStart = FT_ApproxTime();
872 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
875 abnode->scanProc = tp;
876 abnode->scanRunning = 1;
879 } else { /* needs to be salvaged */
880 /* make sure file server and volser are gone */
881 if (abnode->volRunning) {
882 bnode_StopProc(abnode->volProc, SIGTERM);
884 abnode->timeSDStarted = now;
887 if (abnode->fileRunning) {
888 bnode_StopProc(abnode->fileProc, SIGQUIT);
889 if (!abnode->fileSDW)
890 abnode->timeSDStarted = now;
893 if (abnode->scanRunning) {
894 bnode_StopProc(abnode->scanProc, SIGTERM);
895 if (!abnode->scanSDW)
896 abnode->timeSDStarted = now;
899 if (abnode->volRunning || abnode->fileRunning
900 || abnode->scanRunning)
902 /* otherwise, it is safe to start salvager */
903 if (!abnode->salRunning) {
904 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
906 abnode->salProc = tp;
907 abnode->salRunning = 1;
912 } else { /* goal is 0, we're shutting down */
913 /* trying to shutdown */
914 if (abnode->salRunning && !abnode->salSDW) {
915 bnode_StopProc(abnode->salProc, SIGTERM);
917 abnode->timeSDStarted = now;
919 if (abnode->fileRunning && !abnode->fileSDW) {
920 bnode_StopProc(abnode->fileProc, SIGQUIT);
922 abnode->timeSDStarted = now;
924 if (abnode->volRunning && !abnode->volSDW) {
925 bnode_StopProc(abnode->volProc, SIGTERM);
927 abnode->timeSDStarted = now;
929 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
930 bnode_StopProc(abnode->salsrvProc, SIGTERM);
931 abnode->salsrvSDW = 1;
932 abnode->timeSDStarted = now;
934 if (abnode->scanRunning && !abnode->scanSDW) {
935 bnode_StopProc(abnode->scanProc, SIGTERM);
937 abnode->timeSDStarted = now;
940 SetNeedsClock(abnode);
945 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
947 struct fsbnode *abnode = (struct fsbnode *)bn;
951 if (abnode->b.goal == 1) {
952 if (abnode->fileRunning) {
954 strcpy(abuffer, "file server shutting down");
955 else if (abnode->scancmd) {
956 if (!abnode->volRunning && !abnode->scanRunning)
958 "file server up; volser and scanner down");
959 else if (abnode->volRunning && !abnode->scanRunning)
961 "file server up; volser up; scanner down");
962 else if (!abnode->volRunning && abnode->scanRunning)
964 "file server up; volser down; scanner up");
967 strcpy(abuffer, "file server running");
968 } else if (!abnode->volRunning)
969 strcpy(abuffer, "file server up; volser down");
971 strcpy(abuffer, "file server running");
972 } else if (abnode->salRunning) {
973 strcpy(abuffer, "salvaging file system");
975 strcpy(abuffer, "starting file server");
978 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
979 strcpy(abuffer, "file server shutting down");
980 } else if (abnode->salRunning)
981 strcpy(abuffer, "salvager shutting down");
983 strcpy(abuffer, "file server shut down");
989 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
992 struct fsbnode *abnode = (struct fsbnode *)bn;
995 strcpy(abuffer, abnode->filecmd);
996 else if (aindex == 1)
997 strcpy(abuffer, abnode->volcmd);
998 else if (aindex == 2)
999 strcpy(abuffer, abnode->salcmd);
1000 else if (aindex == 3 && abnode->scancmd)
1001 strcpy(abuffer, abnode->scancmd);
1008 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1011 struct fsbnode *abnode = (struct fsbnode *)bn;
1014 strcpy(abuffer, abnode->filecmd);
1015 else if (aindex == 1)
1016 strcpy(abuffer, abnode->volcmd);
1017 else if (aindex == 2)
1018 strcpy(abuffer, abnode->salsrvcmd);
1019 else if (aindex == 3)
1020 strcpy(abuffer, abnode->salcmd);
1021 else if (aindex == 4 && abnode->scancmd)
1022 strcpy(abuffer, abnode->scancmd);