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>
20 #include <opr/queue.h>
23 #include "bnode_internal.h"
24 #include "bosprototypes.h"
26 extern char *DoPidFiles;
27 static int emergency = 0;
29 /* if this file exists, then we have to salvage the file system */
30 #define SALFILE "SALVAGE."
32 #define POLLTIME 20 /* for handling below */
33 #define SDTIME 60 /* time in seconds given to a process to evaporate */
36 Normal operation involves having the file server and the vol server both running.
38 If the vol server terminates, it can simply be restarted.
40 If the file server terminates, the disk must salvaged before the file server
41 can be restarted. In order to restart either the file server or the salvager,
42 the vol server must be shut down.
44 If the file server terminates *normally* (exits after receiving a SIGQUIT)
45 then we don't have to salvage it.
47 The needsSalvage flag is set when the file server is started. It is cleared
48 if the file server exits when fileSDW is true but fileKillSent is false,
49 indicating that it exited after receiving a quit, but before we sent it a kill.
51 The needsSalvage flag is cleared when the salvager exits.
56 afs_int32 timeSDStarted; /* time shutdown operation started */
57 char *filecmd; /* command to start primary file server */
58 char *volcmd; /* command to start secondary vol server */
59 char *salsrvcmd; /* command to start salvageserver (demand attach fs) */
60 char *salcmd; /* command to start salvager */
61 char *scancmd; /* command to start scanner (MR-AFS) */
62 struct bnode_proc *fileProc; /* process for file server */
63 struct bnode_proc *volProc; /* process for vol server */
64 struct bnode_proc *salsrvProc; /* process for salvageserver (demand attach fs) */
65 struct bnode_proc *salProc; /* process for salvager */
66 struct bnode_proc *scanProc; /* process for scanner (MR-AFS) */
67 afs_int32 lastFileStart; /* last start for file */
68 afs_int32 lastVolStart; /* last start for vol */
69 afs_int32 lastSalsrvStart; /* last start for salvageserver (demand attach fs) */
70 afs_int32 lastScanStart; /* last start for scanner (MR-AFS) */
71 char fileRunning; /* file process is running */
72 char volRunning; /* volser is running */
73 char salsrvRunning; /* salvageserver is running (demand attach fs) */
74 char salRunning; /* salvager is running */
75 char scanRunning; /* scanner is running (MR_AFS) */
76 char fileSDW; /* file shutdown wait */
77 char volSDW; /* vol shutdown wait */
78 char salsrvSDW; /* salvageserver shutdown wait (demand attach fs) */
79 char salSDW; /* waiting for the salvager to shutdown */
80 char scanSDW; /* scanner shutdown wait (MR_AFS) */
81 char fileKillSent; /* kill signal has been sent */
83 char salsrvKillSent; /* kill signal has been sent (demand attach fs) */
85 char scanKillSent; /* kill signal has been sent (MR_AFS) */
86 char needsSalvage; /* salvage before running */
87 char needsClock; /* do we need clock ticks */
90 struct bnode * fs_create(char *ainstance, char *afilecmd, char *avolcmd,
91 char *asalcmd, char *ascancmd, char *dummy);
92 struct bnode * dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
93 char * asalsrvcmd, char *asalcmd, char *ascancmd);
95 static int fs_hascore(struct bnode *abnode);
96 static int fs_restartp(struct bnode *abnode);
97 static int fs_delete(struct bnode *abnode);
98 static int fs_timeout(struct bnode *abnode);
99 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
100 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
101 static int fs_procstarted(struct bnode *abnode, struct bnode_proc *aproc);
102 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
103 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
104 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
105 char *abuffer, afs_int32 alen);
106 static int dafs_getparm(struct bnode *abnode, afs_int32 aindex,
107 char *abuffer, afs_int32 alen);
109 static int SetSalFlag(struct fsbnode *abnode, int aflag);
110 static int RestoreSalFlag(struct fsbnode *abnode);
111 static void SetNeedsClock(struct fsbnode *);
112 static int NudgeProcs(struct fsbnode *);
115 static void AppendExecutableExtension(char *cmd);
117 #define AppendExecutableExtension(x)
120 struct bnode_ops fsbnode_ops = {
134 /* demand attach fs bnode ops */
135 struct bnode_ops dafsbnode_ops = {
149 /* Quick inline function to safely convert a fsbnode to a bnode without
150 * dropping type information
153 static_inline struct bnode *
154 fsbnode2bnode(struct fsbnode *abnode) {
155 return (struct bnode *) abnode;
158 /* Function to tell whether this bnode has a core file or not. You might
159 * think that this could be in bnode.c, and decide what core files to check
160 * for based on the bnode's coreName property, but that doesn't work because
161 * there may not be an active process for a bnode that dumped core at the
162 * time the query is done.
165 fs_hascore(struct bnode *abnode)
169 /* see if file server has a core file */
170 bnode_CoreName(abnode, "file", tbuffer);
171 if (access(tbuffer, 0) == 0)
174 /* see if volserver has a core file */
175 bnode_CoreName(abnode, "vol", tbuffer);
176 if (access(tbuffer, 0) == 0)
179 /* see if salvageserver left a core file */
180 bnode_CoreName(abnode, "salsrv", tbuffer);
181 if (access(tbuffer, 0) == 0)
184 /* see if salvager left a core file */
185 bnode_CoreName(abnode, "salv", tbuffer);
186 if (access(tbuffer, 0) == 0)
189 /* see if scanner left a core file (MR-AFS) */
190 bnode_CoreName(abnode, "scan", tbuffer);
191 if (access(tbuffer, 0) == 0)
194 /* no one left a core file */
199 fs_restartp(struct bnode *bn)
201 struct fsbnode *abnode = (struct fsbnode *)bn;
202 struct bnode_token *tt;
206 code = bnode_ParseLine(abnode->filecmd, &tt);
211 code = stat(tt->key, &tstat);
213 bnode_FreeTokens(tt);
216 if (tstat.st_ctime > abnode->lastFileStart)
220 bnode_FreeTokens(tt);
224 /* now do same for volcmd */
225 code = bnode_ParseLine(abnode->volcmd, &tt);
230 code = stat(tt->key, &tstat);
232 bnode_FreeTokens(tt);
235 if (tstat.st_ctime > abnode->lastVolStart)
239 bnode_FreeTokens(tt);
243 if (abnode->salsrvcmd) { /* only in demand attach fs */
244 /* now do same for salsrvcmd (demand attach fs) */
245 code = bnode_ParseLine(abnode->salsrvcmd, &tt);
250 code = stat(tt->key, &tstat);
252 bnode_FreeTokens(tt);
255 if (tstat.st_ctime > abnode->lastSalsrvStart)
259 bnode_FreeTokens(tt);
262 if (abnode->scancmd) { /* Only in MR-AFS */
263 /* now do same for scancmd (MR-AFS) */
264 code = bnode_ParseLine(abnode->scancmd, &tt);
269 code = stat(tt->key, &tstat);
271 bnode_FreeTokens(tt);
274 if (tstat.st_ctime > abnode->lastScanStart)
278 bnode_FreeTokens(tt);
284 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
285 we need to salvage the file system (so we can tell over panic reboots */
287 SetSalFlag(struct fsbnode *abnode, int aflag)
289 char tbuffer[AFSDIR_PATH_MAX];
292 /* don't use the salvage flag for demand attach fs */
293 if (abnode->salsrvcmd == NULL) {
294 abnode->needsSalvage = aflag;
295 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
296 SALFILE, abnode->b.name, (char *)NULL);
298 fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
307 /* set the needsSalvage flag according to the existence of the salvage file */
309 RestoreSalFlag(struct fsbnode *abnode)
311 char tbuffer[AFSDIR_PATH_MAX];
313 /* never set needs salvage flag for demand attach fs */
314 if (abnode->salsrvcmd != NULL) {
315 abnode->needsSalvage = 0;
317 strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
318 SALFILE, abnode->b.name, (char *)NULL);
319 if (access(tbuffer, 0) == 0) {
320 /* file exists, so need to salvage */
321 abnode->needsSalvage = 1;
323 abnode->needsSalvage = 0;
330 fs_delete(struct bnode *bn)
332 struct fsbnode *abnode = (struct fsbnode *)bn;
334 free(abnode->filecmd);
335 free(abnode->volcmd);
336 free(abnode->salcmd);
337 if (abnode->salsrvcmd)
338 free(abnode->salsrvcmd);
340 free(abnode->scancmd);
348 AppendExecutableExtension(char *cmd)
350 char cmdext[_MAX_EXT];
352 _splitpath(cmd, NULL, NULL, NULL, cmdext);
353 if (*cmdext == '\0') {
354 /* no filename extension supplied for cmd; append .exe */
358 #endif /* AFS_NT40_ENV */
362 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
363 char *ascancmd, char *dummy)
367 char cmdname[AFSDIR_PATH_MAX];
368 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
371 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
374 /* construct local paths from canonical (wire-format) paths */
375 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
376 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
380 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
381 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
385 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
386 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
391 if (ascancmd && strlen(ascancmd)) {
392 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
393 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
400 sscanf(fileCmdpath, "%s", cmdname);
401 AppendExecutableExtension(cmdname);
402 if (stat(cmdname, &tstat)) {
403 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
408 sscanf(volCmdpath, "%s", cmdname);
409 AppendExecutableExtension(cmdname);
410 if (stat(cmdname, &tstat)) {
411 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
416 sscanf(salCmdpath, "%s", cmdname);
417 AppendExecutableExtension(cmdname);
418 if (stat(cmdname, &tstat)) {
419 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
424 if (ascancmd && strlen(ascancmd)) {
425 sscanf(scanCmdpath, "%s", cmdname);
426 AppendExecutableExtension(cmdname);
427 if (stat(cmdname, &tstat)) {
428 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
435 te = calloc(1, sizeof(struct fsbnode));
440 te->filecmd = fileCmdpath;
441 te->volcmd = volCmdpath;
442 te->salsrvcmd = NULL;
443 te->salcmd = salCmdpath;
444 if (ascancmd && strlen(ascancmd))
445 te->scancmd = scanCmdpath;
448 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
452 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
453 /* ask for timeout activations every 20 seconds */
454 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
455 SetNeedsClock(te); /* compute needsClock field */
472 return fsbnode2bnode(te);
475 /* create a demand attach fs bnode */
477 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
478 char * asalsrvcmd, char *asalcmd, char *ascancmd)
482 char cmdname[AFSDIR_PATH_MAX];
483 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
486 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
489 /* construct local paths from canonical (wire-format) paths */
490 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
491 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
495 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
496 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
500 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
501 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
505 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
506 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
511 if (ascancmd && strlen(ascancmd)) {
512 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
513 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
520 sscanf(fileCmdpath, "%s", cmdname);
521 AppendExecutableExtension(cmdname);
522 if (stat(cmdname, &tstat)) {
523 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
528 sscanf(volCmdpath, "%s", cmdname);
529 AppendExecutableExtension(cmdname);
530 if (stat(cmdname, &tstat)) {
531 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
536 sscanf(salsrvCmdpath, "%s", cmdname);
537 AppendExecutableExtension(cmdname);
538 if (stat(cmdname, &tstat)) {
539 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
544 sscanf(salCmdpath, "%s", cmdname);
545 AppendExecutableExtension(cmdname);
546 if (stat(cmdname, &tstat)) {
547 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
552 if (ascancmd && strlen(ascancmd)) {
553 sscanf(scanCmdpath, "%s", cmdname);
554 AppendExecutableExtension(cmdname);
555 if (stat(cmdname, &tstat)) {
556 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
563 te = calloc(1, 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->fileSDW && !ab->fileKillSent) || (ab->volSDW && !ab->volKillSent)
777 || (ab->scanSDW && !ab->scanKillSent) || (ab->salSDW && !ab->salKillSent)
778 || (ab->salsrvSDW && !ab->salsrvKillSent)) {
779 /* SIGQUIT sent, will send SIGKILL if process does not exit */
781 } else if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
782 && (!ab->scancmd || ab->scanRunning)
783 && (!ab->salsrvcmd || ab->salsrvRunning)) {
784 if (ab->b.errorStopCount) {
785 /* reset error count after running for a bit */
788 ab->needsClock = 0; /* running normally */
790 } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
791 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
792 if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
793 bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
794 ab->b.errorStopDelay);
795 ab->needsClock = 1; /* halted for errors, retry later */
796 timeout = ab->b.errorStopDelay;
798 ab->needsClock = 0; /* halted normally */
801 ab->needsClock = 1; /* other */
803 if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
804 || ab->b.period != timeout))
805 bnode_SetTimeout(fsbnode2bnode(ab), timeout);
807 bnode_SetTimeout(fsbnode2bnode(ab), 0);
811 NudgeProcs(struct fsbnode *abnode)
813 struct bnode_proc *tp; /* not register */
817 now = FT_ApproxTime();
818 if (abnode->b.goal == 1) {
819 /* we're trying to run the system. If the file server is running, then we
820 * are trying to start up the system. If it is not running, then needsSalvage
821 * tells us if we need to run the salvager or not */
822 if (abnode->fileRunning) {
823 if (abnode->salRunning) {
824 bozo_Log("Salvager running along with file server!\n");
825 bozo_Log("Emergency shutdown\n");
827 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
828 bnode_StopProc(abnode->salProc, SIGKILL);
829 SetNeedsClock(abnode);
832 if (!abnode->volRunning) {
833 abnode->lastVolStart = FT_ApproxTime();
834 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
836 abnode->volProc = tp;
837 abnode->volRunning = 1;
840 if (abnode->salsrvcmd) {
841 if (!abnode->salsrvRunning) {
842 abnode->lastSalsrvStart = FT_ApproxTime();
844 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
847 abnode->salsrvProc = tp;
848 abnode->salsrvRunning = 1;
852 if (abnode->scancmd) {
853 if (!abnode->scanRunning) {
854 abnode->lastScanStart = FT_ApproxTime();
856 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
859 abnode->scanProc = tp;
860 abnode->scanRunning = 1;
864 } else { /* file is not running */
865 /* see how to start */
866 /* for demand attach fs, needsSalvage flag is ignored */
867 if (!abnode->needsSalvage || abnode->salsrvcmd) {
868 /* no crash apparent, just start up normally */
869 if (!abnode->fileRunning) {
870 abnode->lastFileStart = FT_ApproxTime();
872 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
874 abnode->fileProc = tp;
875 abnode->fileRunning = 1;
876 SetSalFlag(abnode, 1);
879 if (!abnode->volRunning) {
880 abnode->lastVolStart = FT_ApproxTime();
881 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
883 abnode->volProc = tp;
884 abnode->volRunning = 1;
887 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
888 abnode->lastSalsrvStart = FT_ApproxTime();
890 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
893 abnode->salsrvProc = tp;
894 abnode->salsrvRunning = 1;
897 if (abnode->scancmd && !abnode->scanRunning) {
898 abnode->lastScanStart = FT_ApproxTime();
900 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
903 abnode->scanProc = tp;
904 abnode->scanRunning = 1;
907 } else { /* needs to be salvaged */
908 /* make sure file server and volser are gone */
909 if (abnode->volRunning) {
910 bnode_StopProc(abnode->volProc, SIGTERM);
912 abnode->timeSDStarted = now;
915 if (abnode->fileRunning) {
916 bnode_StopProc(abnode->fileProc, SIGQUIT);
917 if (!abnode->fileSDW)
918 abnode->timeSDStarted = now;
921 if (abnode->scanRunning) {
922 bnode_StopProc(abnode->scanProc, SIGTERM);
923 if (!abnode->scanSDW)
924 abnode->timeSDStarted = now;
927 if (abnode->volRunning || abnode->fileRunning
928 || abnode->scanRunning)
930 /* otherwise, it is safe to start salvager */
931 if (!abnode->salRunning) {
932 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
934 abnode->salProc = tp;
935 abnode->salRunning = 1;
940 } else { /* goal is 0, we're shutting down */
941 /* trying to shutdown */
942 if (abnode->salRunning && !abnode->salSDW) {
943 bnode_StopProc(abnode->salProc, SIGTERM);
945 abnode->timeSDStarted = now;
947 if (abnode->fileRunning && !abnode->fileSDW) {
948 bnode_StopProc(abnode->fileProc, SIGQUIT);
950 abnode->timeSDStarted = now;
952 if (abnode->volRunning && !abnode->volSDW) {
953 bnode_StopProc(abnode->volProc, SIGTERM);
955 abnode->timeSDStarted = now;
957 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
958 bnode_StopProc(abnode->salsrvProc, SIGTERM);
959 abnode->salsrvSDW = 1;
960 abnode->timeSDStarted = now;
962 if (abnode->scanRunning && !abnode->scanSDW) {
963 bnode_StopProc(abnode->scanProc, SIGTERM);
965 abnode->timeSDStarted = now;
968 SetNeedsClock(abnode);
973 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
975 struct fsbnode *abnode = (struct fsbnode *)bn;
979 if (abnode->b.goal == 1) {
980 if (abnode->fileRunning) {
982 strcpy(abuffer, "file server shutting down");
983 else if (abnode->scancmd) {
984 if (!abnode->volRunning && !abnode->scanRunning)
986 "file server up; volser and scanner down");
987 else if (abnode->volRunning && !abnode->scanRunning)
989 "file server up; volser up; scanner down");
990 else if (!abnode->volRunning && abnode->scanRunning)
992 "file server up; volser down; scanner up");
995 strcpy(abuffer, "file server running");
996 } else if (!abnode->volRunning)
997 strcpy(abuffer, "file server up; volser down");
999 strcpy(abuffer, "file server running");
1000 } else if (abnode->salRunning) {
1001 strcpy(abuffer, "salvaging file system");
1003 strcpy(abuffer, "starting file server");
1006 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
1007 strcpy(abuffer, "file server shutting down");
1008 } else if (abnode->salRunning)
1009 strcpy(abuffer, "salvager shutting down");
1011 strcpy(abuffer, "file server shut down");
1017 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1020 struct fsbnode *abnode = (struct fsbnode *)bn;
1023 strcpy(abuffer, abnode->filecmd);
1024 else if (aindex == 1)
1025 strcpy(abuffer, abnode->volcmd);
1026 else if (aindex == 2)
1027 strcpy(abuffer, abnode->salcmd);
1028 else if (aindex == 3 && abnode->scancmd)
1029 strcpy(abuffer, abnode->scancmd);
1036 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1039 struct fsbnode *abnode = (struct fsbnode *)bn;
1042 strcpy(abuffer, abnode->filecmd);
1043 else if (aindex == 1)
1044 strcpy(abuffer, abnode->volcmd);
1045 else if (aindex == 2)
1046 strcpy(abuffer, abnode->salsrvcmd);
1047 else if (aindex == 3)
1048 strcpy(abuffer, abnode->salcmd);
1049 else if (aindex == 4 && abnode->scancmd)
1050 strcpy(abuffer, abnode->scancmd);