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 static int emergency = 0;
26 /* if this file exists, then we have to salvage the file system */
27 #define SALFILE "SALVAGE."
29 #define POLLTIME 20 /* for handling below */
30 #define SDTIME 60 /* time in seconds given to a process to evaporate */
33 Normal operation involves having the file server and the vol server both running.
35 If the vol server terminates, it can simply be restarted.
37 If the file server terminates, the disk must salvaged before the file server
38 can be restarted. In order to restart either the file server or the salvager,
39 the vol server must be shut down.
41 If the file server terminates *normally* (exits after receiving a SIGQUIT)
42 then we don't have to salvage it.
44 The needsSalvage flag is set when the file server is started. It is cleared
45 if the file server exits when fileSDW is true but fileKillSent is false,
46 indicating that it exited after receiving a quit, but before we sent it a kill.
48 The needsSalvage flag is cleared when the salvager exits.
53 afs_int32 timeSDStarted; /* time shutdown operation started */
54 char *filecmd; /* command to start primary file server */
55 char *volcmd; /* command to start secondary vol server */
56 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
57 char *salcmd; /* command to start salvager */
58 char *scancmd; /* command to start scanner (MR-AFS) */
59 struct bnode_proc *fileProc; /* process for file server */
60 struct bnode_proc *volProc; /* process for vol server */
61 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
62 struct bnode_proc *salProc; /* process for salvager */
63 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
64 afs_int32 lastFileStart; /* last start for file */
65 afs_int32 lastVolStart; /* last start for vol */
66 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
67 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
68 char fileRunning; /* file process is running */
69 char volRunning; /* volser is running */
70 char salsrvRunning; /* salvageserver is running (demand attach fs) */
71 char salRunning; /* salvager is running */
72 char scanRunning; /* scanner is running (MR_AFS) */
73 char fileSDW; /* file shutdown wait */
74 char volSDW; /* vol shutdown wait */
75 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
76 char salSDW; /* waiting for the salvager to shutdown */
77 char scanSDW; /* scanner shutdown wait (MR_AFS) */
78 char fileKillSent; /* kill signal has been sent */
80 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
82 char scanKillSent; /* kill signal has been sent (MR_AFS) */
83 char needsSalvage; /* salvage before running */
84 char needsClock; /* do we need clock ticks */
87 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
88 char *asalcmd, char *ascancmd, char *dummy);
89 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
90 char * asalsrvcmd, char *asalcmd, char *ascancmd);
92 static int fs_hascore(struct bnode *abnode);
93 static int fs_restartp(struct bnode *abnode);
94 static int fs_delete(struct bnode *abnode);
95 static int fs_timeout(struct bnode *abnode);
96 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
97 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
98 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
99 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
100 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
101 char *abuffer, afs_int32 alen);
102 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
103 char *abuffer, afs_int32 alen);
105 static int SetSalFlag(struct fsbnode *abnode, int aflag);
106 static int RestoreSalFlag(struct fsbnode *abnode);
107 static void SetNeedsClock(struct fsbnode *);
108 static int NudgeProcs(struct fsbnode *);
111 static void AppendExecutableExtension(char *cmd);
113 #define AppendExecutableExtension(x)
116 struct bnode_ops fsbnode_ops = {
129 /* demand attach fs bnode ops */
130 struct bnode_ops dafsbnode_ops = {
143 /* Quick inline function to safely convert a fsbnode to a bnode without
144 * dropping type information
147 static_inline struct bnode *
148 fsbnode2bnode(struct fsbnode *abnode) {
149 return (struct bnode *) abnode;
152 /* Function to tell whether this bnode has a core file or not. You might
153 * think that this could be in bnode.c, and decide what core files to check
154 * for based on the bnode's coreName property, but that doesn't work because
155 * there may not be an active process for a bnode that dumped core at the
156 * time the query is done.
159 fs_hascore(struct bnode *abnode)
163 /* see if file server has a core file */
164 bnode_CoreName(abnode, "file", tbuffer);
165 if (access(tbuffer, 0) == 0)
168 /* see if volserver has a core file */
169 bnode_CoreName(abnode, "vol", tbuffer);
170 if (access(tbuffer, 0) == 0)
173 /* see if salvageserver left a core file */
174 bnode_CoreName(abnode, "salsrv", tbuffer);
175 if (access(tbuffer, 0) == 0)
178 /* see if salvager left a core file */
179 bnode_CoreName(abnode, "salv", tbuffer);
180 if (access(tbuffer, 0) == 0)
183 /* see if scanner left a core file (MR-AFS) */
184 bnode_CoreName(abnode, "scan", tbuffer);
185 if (access(tbuffer, 0) == 0)
188 /* no one left a core file */
193 fs_restartp(struct bnode *bn)
195 struct fsbnode *abnode = (struct fsbnode *)bn;
196 struct bnode_token *tt;
200 code = bnode_ParseLine(abnode->filecmd, &tt);
205 code = stat(tt->key, &tstat);
207 bnode_FreeTokens(tt);
210 if (tstat.st_ctime > abnode->lastFileStart)
214 bnode_FreeTokens(tt);
218 /* now do same for volcmd */
219 code = bnode_ParseLine(abnode->volcmd, &tt);
224 code = stat(tt->key, &tstat);
226 bnode_FreeTokens(tt);
229 if (tstat.st_ctime > abnode->lastVolStart)
233 bnode_FreeTokens(tt);
237 if (abnode->salsrvcmd) { /* only in demand attach fs */
238 /* now do same for salsrvcmd (demand attach fs) */
239 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
244 code = stat(tt->key, &tstat);
246 bnode_FreeTokens(tt);
249 if (tstat.st_ctime > abnode->lastSalsrvStart)
253 bnode_FreeTokens(tt);
256 if (abnode->scancmd) { /* Only in MR-AFS */
257 /* now do same for scancmd (MR-AFS) */
258 code = bnode_ParseLine(abnode->scancmd, &tt);
263 code = stat(tt->key, &tstat);
265 bnode_FreeTokens(tt);
268 if (tstat.st_ctime > abnode->lastScanStart)
272 bnode_FreeTokens(tt);
278 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
279 we need to salvage the file system (so we can tell over panic reboots */
281 SetSalFlag(struct fsbnode *abnode, int aflag)
283 char tbuffer[AFSDIR_PATH_MAX];
286 /* don't use the salvage flag for demand attach fs */
287 if (abnode->salsrvcmd == NULL) {
288 abnode->needsSalvage = aflag;
289 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
290 SALFILE, abnode->b.name, NULL);
292 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
301 /* set the needsSalvage flag according to the existence of the salvage file */
303 RestoreSalFlag(struct fsbnode *abnode)
305 char tbuffer[AFSDIR_PATH_MAX];
307 /* never set needs salvage flag for demand attach fs */
308 if (abnode->salsrvcmd != NULL) {
309 abnode->needsSalvage = 0;
311 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
312 SALFILE, abnode->b.name, NULL);
313 if (access(tbuffer, 0) == 0) {
314 /* file exists, so need to salvage */
315 abnode->needsSalvage = 1;
317 abnode->needsSalvage = 0;
327 b = (char *)malloc(strlen(a) + 1);
333 fs_delete(struct bnode *bn)
335 struct fsbnode *abnode = (struct fsbnode *)bn;
337 free(abnode->filecmd);
338 free(abnode->volcmd);
339 free(abnode->salcmd);
340 if (abnode->salsrvcmd)
341 free(abnode->salsrvcmd);
343 free(abnode->scancmd);
351 AppendExecutableExtension(char *cmd)
353 char cmdext[_MAX_EXT];
355 _splitpath(cmd, NULL, NULL, NULL, cmdext);
356 if (*cmdext == '\0') {
357 /* no filename extension supplied for cmd; append .exe */
361 #endif /* AFS_NT40_ENV */
365 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
366 char *ascancmd, char *dummy)
370 char cmdname[AFSDIR_PATH_MAX];
371 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
374 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
377 /* construct local paths from canonical (wire-format) paths */
378 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
379 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
383 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
384 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
388 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
389 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
394 if (ascancmd && strlen(ascancmd)) {
395 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
396 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
403 sscanf(fileCmdpath, "%s", cmdname);
404 AppendExecutableExtension(cmdname);
405 if (stat(cmdname, &tstat)) {
406 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
411 sscanf(volCmdpath, "%s", cmdname);
412 AppendExecutableExtension(cmdname);
413 if (stat(cmdname, &tstat)) {
414 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
419 sscanf(salCmdpath, "%s", cmdname);
420 AppendExecutableExtension(cmdname);
421 if (stat(cmdname, &tstat)) {
422 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
427 if (ascancmd && strlen(ascancmd)) {
428 sscanf(scanCmdpath, "%s", cmdname);
429 AppendExecutableExtension(cmdname);
430 if (stat(cmdname, &tstat)) {
431 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
438 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
443 memset(te, 0, sizeof(struct fsbnode));
444 te->filecmd = fileCmdpath;
445 te->volcmd = volCmdpath;
446 te->salsrvcmd = NULL;
447 te->salcmd = salCmdpath;
448 if (ascancmd && strlen(ascancmd))
449 te->scancmd = scanCmdpath;
452 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
456 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
457 /* ask for timeout activations every 10 seconds */
458 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
459 SetNeedsClock(te); /* compute needsClock field */
476 return fsbnode2bnode(te);
479 /* create a demand attach fs bnode */
481 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
482 char * asalsrvcmd, char *asalcmd, char *ascancmd)
486 char cmdname[AFSDIR_PATH_MAX];
487 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
490 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
493 /* construct local paths from canonical (wire-format) paths */
494 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
495 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
499 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
500 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
504 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
505 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
509 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
510 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
515 if (ascancmd && strlen(ascancmd)) {
516 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
517 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
524 sscanf(fileCmdpath, "%s", cmdname);
525 AppendExecutableExtension(cmdname);
526 if (stat(cmdname, &tstat)) {
527 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
532 sscanf(volCmdpath, "%s", cmdname);
533 AppendExecutableExtension(cmdname);
534 if (stat(cmdname, &tstat)) {
535 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
540 sscanf(salsrvCmdpath, "%s", cmdname);
541 AppendExecutableExtension(cmdname);
542 if (stat(cmdname, &tstat)) {
543 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
548 sscanf(salCmdpath, "%s", cmdname);
549 AppendExecutableExtension(cmdname);
550 if (stat(cmdname, &tstat)) {
551 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
556 if (ascancmd && strlen(ascancmd)) {
557 sscanf(scanCmdpath, "%s", cmdname);
558 AppendExecutableExtension(cmdname);
559 if (stat(cmdname, &tstat)) {
560 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
567 te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
572 memset(te, 0, sizeof(struct fsbnode));
573 te->filecmd = fileCmdpath;
574 te->volcmd = volCmdpath;
575 te->salsrvcmd = salsrvCmdpath;
576 te->salcmd = salCmdpath;
577 if (ascancmd && strlen(ascancmd))
578 te->scancmd = scanCmdpath;
581 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
585 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
586 /* ask for timeout activations every 10 seconds */
587 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
588 SetNeedsClock(te); /* compute needsClock field */
607 return fsbnode2bnode(te);
610 /* called to SIGKILL a process if it doesn't terminate normally */
612 fs_timeout(struct bnode *bn)
614 struct fsbnode *abnode = (struct fsbnode *)bn;
618 now = FT_ApproxTime();
620 if (abnode->volSDW) {
621 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
622 bnode_StopProc(abnode->volProc, SIGKILL);
623 abnode->volKillSent = 1;
625 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
629 if (abnode->salSDW) {
630 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
631 bnode_StopProc(abnode->salProc, SIGKILL);
632 abnode->salKillSent = 1;
634 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
638 if (abnode->fileSDW) {
639 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
640 bnode_StopProc(abnode->fileProc, SIGKILL);
641 abnode->fileKillSent = 1;
643 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
647 if (abnode->salsrvSDW) {
648 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
649 bnode_StopProc(abnode->salsrvProc, SIGKILL);
650 abnode->salsrvKillSent = 1;
652 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
656 if (abnode->scanSDW) {
657 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
658 bnode_StopProc(abnode->scanProc, SIGKILL);
659 abnode->scanKillSent = 1;
661 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
665 SetNeedsClock(abnode);
670 fs_getstat(struct bnode *bn, afs_int32 * astatus)
672 struct fsbnode *abnode = (struct fsbnode *) bn;
675 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
676 || abnode->scanSDW || abnode->salsrvSDW)
677 temp = BSTAT_SHUTTINGDOWN;
678 else if (abnode->salRunning)
680 else if (abnode->volRunning && abnode->fileRunning
681 && (!abnode->scancmd || abnode->scanRunning)
682 && (!abnode->salsrvcmd || abnode->salsrvRunning))
684 else if (!abnode->salRunning && !abnode->volRunning
685 && !abnode->fileRunning && !abnode->scanRunning
686 && !abnode->salsrvRunning)
687 temp = BSTAT_SHUTDOWN;
689 temp = BSTAT_STARTINGUP;
695 fs_setstat(struct bnode *abnode, afs_int32 astatus)
697 return NudgeProcs((struct fsbnode *) abnode);
701 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
703 struct fsbnode *abnode = (struct fsbnode *)bn;
705 /* process has exited */
707 if (aproc == abnode->volProc) {
709 abnode->volRunning = 0;
711 abnode->volKillSent = 0;
712 } else if (aproc == abnode->fileProc) {
713 /* if we were expecting a shutdown and we didn't send a kill signal
714 * and exited (didn't have a signal termination), then we assume that
715 * the file server exited after putting the appropriate volumes safely
716 * offline, and don't salvage next time.
718 if (abnode->fileSDW && !abnode->fileKillSent
719 && aproc->lastSignal == 0)
720 SetSalFlag(abnode, 0); /* shut down normally */
721 abnode->fileProc = 0;
722 abnode->fileRunning = 0;
724 abnode->fileKillSent = 0;
725 } else if (aproc == abnode->salProc) {
726 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
727 * that we don't have to salvage again */
729 SetSalFlag(abnode, 0); /* salvage just completed */
731 abnode->salRunning = 0;
733 abnode->salKillSent = 0;
734 } else if (aproc == abnode->scanProc) {
735 abnode->scanProc = 0;
736 abnode->scanRunning = 0;
738 abnode->scanKillSent = 0;
739 } else if (aproc == abnode->salsrvProc) {
740 abnode->salsrvProc = 0;
741 abnode->salsrvRunning = 0;
742 abnode->salsrvSDW = 0;
743 abnode->salsrvKillSent = 0;
746 /* now restart anyone who needs to restart */
747 return NudgeProcs(abnode);
750 /* make sure we're periodically checking the state if we need to */
752 SetNeedsClock(struct fsbnode *ab)
754 if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
755 && (!ab->scancmd || ab->scanRunning)
756 && (!ab->salsrvcmd || ab->salsrvRunning))
757 ab->needsClock = 0; /* running normally */
758 else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning
759 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning)
760 ab->needsClock = 0; /* halted normally */
762 ab->needsClock = 1; /* other */
763 if (ab->needsClock && !bnode_PendingTimeout(fsbnode2bnode(ab)))
764 bnode_SetTimeout(fsbnode2bnode(ab), POLLTIME);
766 bnode_SetTimeout(fsbnode2bnode(ab), 0);
770 NudgeProcs(struct fsbnode *abnode)
772 struct bnode_proc *tp; /* not register */
776 now = FT_ApproxTime();
777 if (abnode->b.goal == 1) {
778 /* we're trying to run the system. If the file server is running, then we
779 * are trying to start up the system. If it is not running, then needsSalvage
780 * tells us if we need to run the salvager or not */
781 if (abnode->fileRunning) {
782 if (abnode->salRunning) {
783 bozo_Log("Salvager running along with file server!\n");
784 bozo_Log("Emergency shutdown\n");
786 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
787 bnode_StopProc(abnode->salProc, SIGKILL);
788 SetNeedsClock(abnode);
791 if (!abnode->volRunning) {
792 abnode->lastVolStart = FT_ApproxTime();
793 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
795 abnode->volProc = tp;
796 abnode->volRunning = 1;
799 if (abnode->salsrvcmd) {
800 if (!abnode->salsrvRunning) {
801 abnode->lastSalsrvStart = FT_ApproxTime();
803 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
806 abnode->salsrvProc = tp;
807 abnode->salsrvRunning = 1;
811 if (abnode->scancmd) {
812 if (!abnode->scanRunning) {
813 abnode->lastScanStart = FT_ApproxTime();
815 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
818 abnode->scanProc = tp;
819 abnode->scanRunning = 1;
823 } else { /* file is not running */
824 /* see how to start */
825 /* for demand attach fs, needsSalvage flag is ignored */
826 if (!abnode->needsSalvage || abnode->salsrvcmd) {
827 /* no crash apparent, just start up normally */
828 if (!abnode->fileRunning) {
829 abnode->lastFileStart = FT_ApproxTime();
831 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
833 abnode->fileProc = tp;
834 abnode->fileRunning = 1;
835 SetSalFlag(abnode, 1);
838 if (!abnode->volRunning) {
839 abnode->lastVolStart = FT_ApproxTime();
840 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
842 abnode->volProc = tp;
843 abnode->volRunning = 1;
846 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
847 abnode->lastSalsrvStart = FT_ApproxTime();
849 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
852 abnode->salsrvProc = tp;
853 abnode->salsrvRunning = 1;
856 if (abnode->scancmd && !abnode->scanRunning) {
857 abnode->lastScanStart = FT_ApproxTime();
859 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
862 abnode->scanProc = tp;
863 abnode->scanRunning = 1;
866 } else { /* needs to be salvaged */
867 /* make sure file server and volser are gone */
868 if (abnode->volRunning) {
869 bnode_StopProc(abnode->volProc, SIGTERM);
871 abnode->timeSDStarted = now;
874 if (abnode->fileRunning) {
875 bnode_StopProc(abnode->fileProc, SIGQUIT);
876 if (!abnode->fileSDW)
877 abnode->timeSDStarted = now;
880 if (abnode->scanRunning) {
881 bnode_StopProc(abnode->scanProc, SIGTERM);
882 if (!abnode->scanSDW)
883 abnode->timeSDStarted = now;
886 if (abnode->volRunning || abnode->fileRunning
887 || abnode->scanRunning)
889 /* otherwise, it is safe to start salvager */
890 if (!abnode->salRunning) {
891 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
893 abnode->salProc = tp;
894 abnode->salRunning = 1;
899 } else { /* goal is 0, we're shutting down */
900 /* trying to shutdown */
901 if (abnode->salRunning && !abnode->salSDW) {
902 bnode_StopProc(abnode->salProc, SIGTERM);
904 abnode->timeSDStarted = now;
906 if (abnode->fileRunning && !abnode->fileSDW) {
907 bnode_StopProc(abnode->fileProc, SIGQUIT);
909 abnode->timeSDStarted = now;
911 if (abnode->volRunning && !abnode->volSDW) {
912 bnode_StopProc(abnode->volProc, SIGTERM);
914 abnode->timeSDStarted = now;
916 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
917 bnode_StopProc(abnode->salsrvProc, SIGTERM);
918 abnode->salsrvSDW = 1;
919 abnode->timeSDStarted = now;
921 if (abnode->scanRunning && !abnode->scanSDW) {
922 bnode_StopProc(abnode->scanProc, SIGTERM);
924 abnode->timeSDStarted = now;
927 SetNeedsClock(abnode);
932 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
934 struct fsbnode *abnode = (struct fsbnode *)bn;
938 if (abnode->b.goal == 1) {
939 if (abnode->fileRunning) {
941 strcpy(abuffer, "file server shutting down");
942 else if (abnode->scancmd) {
943 if (!abnode->volRunning && !abnode->scanRunning)
945 "file server up; volser and scanner down");
946 else if (abnode->volRunning && !abnode->scanRunning)
948 "file server up; volser up; scanner down");
949 else if (!abnode->volRunning && abnode->scanRunning)
951 "file server up; volser down; scanner up");
954 strcpy(abuffer, "file server running");
955 } else if (!abnode->volRunning)
956 strcpy(abuffer, "file server up; volser down");
958 strcpy(abuffer, "file server running");
959 } else if (abnode->salRunning) {
960 strcpy(abuffer, "salvaging file system");
962 strcpy(abuffer, "starting file server");
965 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
966 strcpy(abuffer, "file server shutting down");
967 } else if (abnode->salRunning)
968 strcpy(abuffer, "salvager shutting down");
970 strcpy(abuffer, "file server shut down");
976 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
979 struct fsbnode *abnode = (struct fsbnode *)bn;
982 strcpy(abuffer, abnode->filecmd);
983 else if (aindex == 1)
984 strcpy(abuffer, abnode->volcmd);
985 else if (aindex == 2)
986 strcpy(abuffer, abnode->salcmd);
987 else if (aindex == 3 && abnode->scancmd)
988 strcpy(abuffer, abnode->scancmd);
995 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
998 struct fsbnode *abnode = (struct fsbnode *)bn;
1001 strcpy(abuffer, abnode->filecmd);
1002 else if (aindex == 1)
1003 strcpy(abuffer, abnode->volcmd);
1004 else if (aindex == 2)
1005 strcpy(abuffer, abnode->salsrvcmd);
1006 else if (aindex == 3)
1007 strcpy(abuffer, abnode->salcmd);
1008 else if (aindex == 4 && abnode->scancmd)
1009 strcpy(abuffer, abnode->scancmd);