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 char *AppendExecutableExtension(char *cmd);
117 #define AppendExecutableExtension(x) strdup(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)
292 /* don't use the salvage flag for demand attach fs */
293 if (abnode->salsrvcmd == NULL) {
294 abnode->needsSalvage = aflag;
295 if (asprintf(&filepath, "%s/%s%s", AFSDIR_SERVER_LOCAL_DIRPATH,
296 SALFILE, abnode->b.name) < 0)
299 fd = open(filepath, O_CREAT | O_TRUNC | O_RDWR, 0666);
309 /* set the needsSalvage flag according to the existence of the salvage file */
311 RestoreSalFlag(struct fsbnode *abnode)
315 /* never set needs salvage flag for demand attach fs */
316 if (abnode->salsrvcmd != NULL) {
317 abnode->needsSalvage = 0;
319 if (asprintf(&filepath, "%s/%s%s", AFSDIR_SERVER_LOCAL_DIRPATH,
320 SALFILE, abnode->b.name) < 0)
322 if (access(filepath, 0) == 0) {
323 /* file exists, so need to salvage */
324 abnode->needsSalvage = 1;
326 abnode->needsSalvage = 0;
334 fs_delete(struct bnode *bn)
336 struct fsbnode *abnode = (struct fsbnode *)bn;
338 free(abnode->filecmd);
339 free(abnode->volcmd);
340 free(abnode->salcmd);
341 if (abnode->salsrvcmd)
342 free(abnode->salsrvcmd);
344 free(abnode->scancmd);
352 AppendExecutableExtension(char *cmd)
354 char cmdext[_MAX_EXT];
357 _splitpath(cmd, NULL, NULL, NULL, cmdext);
358 if (*cmdext == '\0') {
359 if (asprintf(&cmdexe, "%s.exe", cmd) < 0)
365 #endif /* AFS_NT40_ENV */
369 fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
370 char *ascancmd, char *dummy)
374 char *cmdname = NULL;
375 char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
378 fileCmdpath = volCmdpath = salCmdpath = scanCmdpath = NULL;
381 /* construct local paths from canonical (wire-format) paths */
382 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
383 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
387 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
388 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
392 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
393 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
398 if (ascancmd && strlen(ascancmd)) {
399 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
400 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
407 cmdname = AppendExecutableExtension(fileCmdpath);
408 if (cmdname == NULL) {
409 bozo_Log("Out of memory constructing binary filename\n");
413 if (stat(cmdname, &tstat)) {
414 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
420 cmdname = AppendExecutableExtension(volCmdpath);
421 if (cmdname == NULL) {
422 bozo_Log("Out of memory constructing binary filename\n");
426 if (stat(cmdname, &tstat)) {
427 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
433 cmdname = AppendExecutableExtension(salCmdpath);
434 if (cmdname == NULL) {
435 bozo_Log("Out of memory constructing binary filename\n");
439 if (stat(cmdname, &tstat)) {
440 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
445 if (ascancmd && strlen(ascancmd)) {
447 cmdname = AppendExecutableExtension(scanCmdpath);
448 if (cmdname == NULL) {
449 bozo_Log("Out of memory constructing binary filename\n");
453 if (stat(cmdname, &tstat)) {
454 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
461 te = calloc(1, sizeof(struct fsbnode));
466 te->filecmd = fileCmdpath;
467 te->volcmd = volCmdpath;
468 te->salsrvcmd = NULL;
469 te->salcmd = salCmdpath;
470 if (ascancmd && strlen(ascancmd))
471 te->scancmd = scanCmdpath;
474 if (bnode_InitBnode(fsbnode2bnode(te), &fsbnode_ops, ainstance) != 0) {
478 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
479 /* ask for timeout activations every 20 seconds */
480 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
481 SetNeedsClock(te); /* compute needsClock field */
499 return fsbnode2bnode(te);
502 /* create a demand attach fs bnode */
504 dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
505 char * asalsrvcmd, char *asalcmd, char *ascancmd)
509 char *cmdname = NULL;
510 char *fileCmdpath, *volCmdpath, *salsrvCmdpath, *salCmdpath, *scanCmdpath;
513 fileCmdpath = volCmdpath = salsrvCmdpath = salCmdpath = scanCmdpath = NULL;
516 /* construct local paths from canonical (wire-format) paths */
517 if (ConstructLocalBinPath(afilecmd, &fileCmdpath)) {
518 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd);
522 if (ConstructLocalBinPath(avolcmd, &volCmdpath)) {
523 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd);
527 if (ConstructLocalBinPath(asalsrvcmd, &salsrvCmdpath)) {
528 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd);
532 if (ConstructLocalBinPath(asalcmd, &salCmdpath)) {
533 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd);
538 if (ascancmd && strlen(ascancmd)) {
539 if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
540 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
547 cmdname = AppendExecutableExtension(fileCmdpath);
548 if (cmdname == NULL) {
549 bozo_Log("Out of memory constructing binary filename\n");
553 if (stat(cmdname, &tstat)) {
554 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname);
560 cmdname = AppendExecutableExtension(volCmdpath);
561 if (cmdname == NULL) {
562 bozo_Log("Out of memory constructing binary filename\n");
566 if (stat(cmdname, &tstat)) {
567 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname);
573 cmdname = AppendExecutableExtension(salsrvCmdpath);
574 if (cmdname == NULL) {
575 bozo_Log("Out of memory constructing binary filename\n");
579 if (stat(cmdname, &tstat)) {
580 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname);
586 cmdname = AppendExecutableExtension(salCmdpath);
587 if (cmdname == NULL) {
588 bozo_Log("Out of memory constructing binary filename\n");
592 if (stat(cmdname, &tstat)) {
593 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
598 if (ascancmd && strlen(ascancmd)) {
600 cmdname = AppendExecutableExtension(scanCmdpath);
601 if (cmdname == NULL) {
602 bozo_Log("Out of memory constructing binary filename\n");
606 if (stat(cmdname, &tstat)) {
607 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
614 te = calloc(1, sizeof(struct fsbnode));
619 te->filecmd = fileCmdpath;
620 te->volcmd = volCmdpath;
621 te->salsrvcmd = salsrvCmdpath;
622 te->salcmd = salCmdpath;
623 if (ascancmd && strlen(ascancmd))
624 te->scancmd = scanCmdpath;
627 if (bnode_InitBnode(fsbnode2bnode(te), &dafsbnode_ops, ainstance) != 0) {
631 bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
632 /* ask for timeout activations every 20 seconds */
633 RestoreSalFlag(te); /* restore needsSalvage flag based on file's existence */
634 SetNeedsClock(te); /* compute needsClock field */
654 return fsbnode2bnode(te);
657 /* called to SIGKILL a process if it doesn't terminate normally */
659 fs_timeout(struct bnode *bn)
661 struct fsbnode *abnode = (struct fsbnode *)bn;
665 now = FT_ApproxTime();
667 if (abnode->volSDW) {
668 if (!abnode->volKillSent && now - abnode->timeSDStarted > SDTIME) {
669 bnode_StopProc(abnode->volProc, SIGKILL);
670 abnode->volKillSent = 1;
672 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
676 if (abnode->salSDW) {
677 if (!abnode->salKillSent && now - abnode->timeSDStarted > SDTIME) {
678 bnode_StopProc(abnode->salProc, SIGKILL);
679 abnode->salKillSent = 1;
681 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
685 if (abnode->fileSDW) {
686 if (!abnode->fileKillSent && now - abnode->timeSDStarted > FSSDTIME) {
687 bnode_StopProc(abnode->fileProc, SIGKILL);
688 abnode->fileKillSent = 1;
690 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
694 if (abnode->salsrvSDW) {
695 if (!abnode->salsrvKillSent && now - abnode->timeSDStarted > SDTIME) {
696 bnode_StopProc(abnode->salsrvProc, SIGKILL);
697 abnode->salsrvKillSent = 1;
699 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
703 if (abnode->scanSDW) {
704 if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
705 bnode_StopProc(abnode->scanProc, SIGKILL);
706 abnode->scanKillSent = 1;
708 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
713 if ((abnode->b.flags & BNODE_ERRORSTOP) && !abnode->salRunning
714 && !abnode->volRunning && !abnode->fileRunning && !abnode->scanRunning
715 && !abnode->salsrvRunning) {
716 bnode_SetStat(bn, BSTAT_NORMAL);
719 bnode_ResetErrorCount(bn);
722 SetNeedsClock(abnode);
727 fs_getstat(struct bnode *bn, afs_int32 * astatus)
729 struct fsbnode *abnode = (struct fsbnode *) bn;
732 if (abnode->volSDW || abnode->fileSDW || abnode->salSDW
733 || abnode->scanSDW || abnode->salsrvSDW)
734 temp = BSTAT_SHUTTINGDOWN;
735 else if (abnode->salRunning)
737 else if (abnode->volRunning && abnode->fileRunning
738 && (!abnode->scancmd || abnode->scanRunning)
739 && (!abnode->salsrvcmd || abnode->salsrvRunning))
741 else if (!abnode->salRunning && !abnode->volRunning
742 && !abnode->fileRunning && !abnode->scanRunning
743 && !abnode->salsrvRunning)
744 temp = BSTAT_SHUTDOWN;
746 temp = BSTAT_STARTINGUP;
752 fs_setstat(struct bnode *abnode, afs_int32 astatus)
754 return NudgeProcs((struct fsbnode *) abnode);
758 fs_procstarted(struct bnode *bn, struct bnode_proc *aproc)
763 code = bozo_CreatePidFile(bn->name, aproc->coreName, aproc->pid);
769 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
771 struct fsbnode *abnode = (struct fsbnode *)bn;
773 /* process has exited */
776 bozo_DeletePidFile(bn->name, aproc->coreName);
779 if (aproc == abnode->volProc) {
781 abnode->volRunning = 0;
783 abnode->volKillSent = 0;
784 } else if (aproc == abnode->fileProc) {
785 /* if we were expecting a shutdown and we didn't send a kill signal
786 * and exited (didn't have a signal termination), then we assume that
787 * the file server exited after putting the appropriate volumes safely
788 * offline, and don't salvage next time.
790 if (abnode->fileSDW && !abnode->fileKillSent
791 && aproc->lastSignal == 0)
792 SetSalFlag(abnode, 0); /* shut down normally */
793 abnode->fileProc = 0;
794 abnode->fileRunning = 0;
796 abnode->fileKillSent = 0;
797 } else if (aproc == abnode->salProc) {
798 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
799 * that we don't have to salvage again */
801 SetSalFlag(abnode, 0); /* salvage just completed */
803 abnode->salRunning = 0;
805 abnode->salKillSent = 0;
806 } else if (aproc == abnode->scanProc) {
807 abnode->scanProc = 0;
808 abnode->scanRunning = 0;
810 abnode->scanKillSent = 0;
811 } else if (aproc == abnode->salsrvProc) {
812 abnode->salsrvProc = 0;
813 abnode->salsrvRunning = 0;
814 abnode->salsrvSDW = 0;
815 abnode->salsrvKillSent = 0;
818 /* now restart anyone who needs to restart */
819 return NudgeProcs(abnode);
822 /* make sure we're periodically checking the state if we need to */
824 SetNeedsClock(struct fsbnode *ab)
826 afs_int32 timeout = POLLTIME;
828 if ((ab->fileSDW && !ab->fileKillSent) || (ab->volSDW && !ab->volKillSent)
829 || (ab->scanSDW && !ab->scanKillSent) || (ab->salSDW && !ab->salKillSent)
830 || (ab->salsrvSDW && !ab->salsrvKillSent)) {
831 /* SIGQUIT sent, will send SIGKILL if process does not exit */
833 } else if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
834 && (!ab->scancmd || ab->scanRunning)
835 && (!ab->salsrvcmd || ab->salsrvRunning)) {
836 if (ab->b.errorStopCount) {
837 /* reset error count after running for a bit */
840 ab->needsClock = 0; /* running normally */
842 } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
843 && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
844 if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
845 bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
846 ab->b.errorStopDelay);
847 ab->needsClock = 1; /* halted for errors, retry later */
848 timeout = ab->b.errorStopDelay;
850 ab->needsClock = 0; /* halted normally */
853 ab->needsClock = 1; /* other */
855 if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
856 || ab->b.period != timeout))
857 bnode_SetTimeout(fsbnode2bnode(ab), timeout);
859 bnode_SetTimeout(fsbnode2bnode(ab), 0);
863 NudgeProcs(struct fsbnode *abnode)
865 struct bnode_proc *tp; /* not register */
869 now = FT_ApproxTime();
870 if (abnode->b.goal == 1) {
871 /* we're trying to run the system. If the file server is running, then we
872 * are trying to start up the system. If it is not running, then needsSalvage
873 * tells us if we need to run the salvager or not */
874 if (abnode->fileRunning) {
875 if (abnode->salRunning) {
876 bozo_Log("Salvager running along with file server!\n");
877 bozo_Log("Emergency shutdown\n");
879 bnode_SetGoal(fsbnode2bnode(abnode), BSTAT_SHUTDOWN);
880 bnode_StopProc(abnode->salProc, SIGKILL);
881 SetNeedsClock(abnode);
884 if (!abnode->volRunning) {
885 abnode->lastVolStart = FT_ApproxTime();
886 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
888 abnode->volProc = tp;
889 abnode->volRunning = 1;
892 if (abnode->salsrvcmd) {
893 if (!abnode->salsrvRunning) {
894 abnode->lastSalsrvStart = FT_ApproxTime();
896 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
899 abnode->salsrvProc = tp;
900 abnode->salsrvRunning = 1;
904 if (abnode->scancmd) {
905 if (!abnode->scanRunning) {
906 abnode->lastScanStart = FT_ApproxTime();
908 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
911 abnode->scanProc = tp;
912 abnode->scanRunning = 1;
916 } else { /* file is not running */
917 /* see how to start */
918 /* for demand attach fs, needsSalvage flag is ignored */
919 if (!abnode->needsSalvage || abnode->salsrvcmd) {
920 /* no crash apparent, just start up normally */
921 if (!abnode->fileRunning) {
922 abnode->lastFileStart = FT_ApproxTime();
924 bnode_NewProc(fsbnode2bnode(abnode), abnode->filecmd, "file", &tp);
926 abnode->fileProc = tp;
927 abnode->fileRunning = 1;
928 SetSalFlag(abnode, 1);
931 if (!abnode->volRunning) {
932 abnode->lastVolStart = FT_ApproxTime();
933 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->volcmd, "vol", &tp);
935 abnode->volProc = tp;
936 abnode->volRunning = 1;
939 if (abnode->salsrvcmd && !abnode->salsrvRunning) {
940 abnode->lastSalsrvStart = FT_ApproxTime();
942 bnode_NewProc(fsbnode2bnode(abnode), abnode->salsrvcmd, "salsrv",
945 abnode->salsrvProc = tp;
946 abnode->salsrvRunning = 1;
949 if (abnode->scancmd && !abnode->scanRunning) {
950 abnode->lastScanStart = FT_ApproxTime();
952 bnode_NewProc(fsbnode2bnode(abnode), abnode->scancmd, "scanner",
955 abnode->scanProc = tp;
956 abnode->scanRunning = 1;
959 } else { /* needs to be salvaged */
960 /* make sure file server and volser are gone */
961 if (abnode->volRunning) {
962 bnode_StopProc(abnode->volProc, SIGTERM);
964 abnode->timeSDStarted = now;
967 if (abnode->fileRunning) {
968 bnode_StopProc(abnode->fileProc, SIGQUIT);
969 if (!abnode->fileSDW)
970 abnode->timeSDStarted = now;
973 if (abnode->scanRunning) {
974 bnode_StopProc(abnode->scanProc, SIGTERM);
975 if (!abnode->scanSDW)
976 abnode->timeSDStarted = now;
979 if (abnode->volRunning || abnode->fileRunning
980 || abnode->scanRunning)
982 /* otherwise, it is safe to start salvager */
983 if (!abnode->salRunning) {
984 code = bnode_NewProc(fsbnode2bnode(abnode), abnode->salcmd, "salv", &tp);
986 abnode->salProc = tp;
987 abnode->salRunning = 1;
992 } else { /* goal is 0, we're shutting down */
993 /* trying to shutdown */
994 if (abnode->salRunning && !abnode->salSDW) {
995 bnode_StopProc(abnode->salProc, SIGTERM);
997 abnode->timeSDStarted = now;
999 if (abnode->fileRunning && !abnode->fileSDW) {
1000 bnode_StopProc(abnode->fileProc, SIGQUIT);
1001 abnode->fileSDW = 1;
1002 abnode->timeSDStarted = now;
1004 if (abnode->volRunning && !abnode->volSDW) {
1005 bnode_StopProc(abnode->volProc, SIGTERM);
1007 abnode->timeSDStarted = now;
1009 if (abnode->salsrvRunning && !abnode->salsrvSDW) {
1010 bnode_StopProc(abnode->salsrvProc, SIGTERM);
1011 abnode->salsrvSDW = 1;
1012 abnode->timeSDStarted = now;
1014 if (abnode->scanRunning && !abnode->scanSDW) {
1015 bnode_StopProc(abnode->scanProc, SIGTERM);
1016 abnode->scanSDW = 1;
1017 abnode->timeSDStarted = now;
1020 SetNeedsClock(abnode);
1025 fs_getstring(struct bnode *bn, char *abuffer, afs_int32 alen)
1027 struct fsbnode *abnode = (struct fsbnode *)bn;
1031 if (abnode->b.goal == 1) {
1032 if (abnode->fileRunning) {
1033 if (abnode->fileSDW)
1034 strcpy(abuffer, "file server shutting down");
1035 else if (abnode->scancmd) {
1036 if (!abnode->volRunning && !abnode->scanRunning)
1038 "file server up; volser and scanner down");
1039 else if (abnode->volRunning && !abnode->scanRunning)
1041 "file server up; volser up; scanner down");
1042 else if (!abnode->volRunning && abnode->scanRunning)
1044 "file server up; volser down; scanner up");
1047 strcpy(abuffer, "file server running");
1048 } else if (!abnode->volRunning)
1049 strcpy(abuffer, "file server up; volser down");
1051 strcpy(abuffer, "file server running");
1052 } else if (abnode->salRunning) {
1053 strcpy(abuffer, "salvaging file system");
1055 strcpy(abuffer, "starting file server");
1058 if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
1059 strcpy(abuffer, "file server shutting down");
1060 } else if (abnode->salRunning)
1061 strcpy(abuffer, "salvager shutting down");
1063 strcpy(abuffer, "file server shut down");
1069 fs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1072 struct fsbnode *abnode = (struct fsbnode *)bn;
1075 strcpy(abuffer, abnode->filecmd);
1076 else if (aindex == 1)
1077 strcpy(abuffer, abnode->volcmd);
1078 else if (aindex == 2)
1079 strcpy(abuffer, abnode->salcmd);
1080 else if (aindex == 3 && abnode->scancmd)
1081 strcpy(abuffer, abnode->scancmd);
1088 dafs_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
1091 struct fsbnode *abnode = (struct fsbnode *)bn;
1094 strcpy(abuffer, abnode->filecmd);
1095 else if (aindex == 1)
1096 strcpy(abuffer, abnode->volcmd);
1097 else if (aindex == 2)
1098 strcpy(abuffer, abnode->salsrvcmd);
1099 else if (aindex == 3)
1100 strcpy(abuffer, abnode->salcmd);
1101 else if (aindex == 4 && abnode->scancmd)
1102 strcpy(abuffer, abnode->scancmd);