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
*);
114 static char *PathToExecutable(char *cmd
);
116 struct bnode_ops fsbnode_ops
= {
130 /* demand attach fs bnode ops */
131 struct bnode_ops dafsbnode_ops
= {
145 /* Quick inline function to safely convert a fsbnode to a bnode without
146 * dropping type information
149 static_inline
struct bnode
*
150 fsbnode2bnode(struct fsbnode
*abnode
) {
151 return (struct bnode
*) abnode
;
154 /* Function to tell whether this bnode has a core file or not. You might
155 * think that this could be in bnode.c, and decide what core files to check
156 * for based on the bnode's coreName property, but that doesn't work because
157 * there may not be an active process for a bnode that dumped core at the
158 * time the query is done.
161 fs_hascore(struct bnode
*abnode
)
165 /* see if file server has a core file */
166 bnode_CoreName(abnode
, "file", tbuffer
);
167 if (access(tbuffer
, 0) == 0)
170 /* see if volserver has a core file */
171 bnode_CoreName(abnode
, "vol", tbuffer
);
172 if (access(tbuffer
, 0) == 0)
175 /* see if salvageserver left a core file */
176 bnode_CoreName(abnode
, "salsrv", tbuffer
);
177 if (access(tbuffer
, 0) == 0)
180 /* see if salvager left a core file */
181 bnode_CoreName(abnode
, "salv", tbuffer
);
182 if (access(tbuffer
, 0) == 0)
185 /* see if scanner left a core file (MR-AFS) */
186 bnode_CoreName(abnode
, "scan", tbuffer
);
187 if (access(tbuffer
, 0) == 0)
190 /* no one left a core file */
195 fs_restartp(struct bnode
*bn
)
197 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
198 struct bnode_token
*tt
;
202 code
= bnode_ParseLine(abnode
->filecmd
, &tt
);
207 code
= stat(tt
->key
, &tstat
);
209 bnode_FreeTokens(tt
);
212 if (tstat
.st_ctime
> abnode
->lastFileStart
)
216 bnode_FreeTokens(tt
);
220 /* now do same for volcmd */
221 code
= bnode_ParseLine(abnode
->volcmd
, &tt
);
226 code
= stat(tt
->key
, &tstat
);
228 bnode_FreeTokens(tt
);
231 if (tstat
.st_ctime
> abnode
->lastVolStart
)
235 bnode_FreeTokens(tt
);
239 if (abnode
->salsrvcmd
) { /* only in demand attach fs */
240 /* now do same for salsrvcmd (demand attach fs) */
241 code
= bnode_ParseLine(abnode
->salsrvcmd
, &tt
);
246 code
= stat(tt
->key
, &tstat
);
248 bnode_FreeTokens(tt
);
251 if (tstat
.st_ctime
> abnode
->lastSalsrvStart
)
255 bnode_FreeTokens(tt
);
258 if (abnode
->scancmd
) { /* Only in MR-AFS */
259 /* now do same for scancmd (MR-AFS) */
260 code
= bnode_ParseLine(abnode
->scancmd
, &tt
);
265 code
= stat(tt
->key
, &tstat
);
267 bnode_FreeTokens(tt
);
270 if (tstat
.st_ctime
> abnode
->lastScanStart
)
274 bnode_FreeTokens(tt
);
280 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
281 we need to salvage the file system (so we can tell over panic reboots */
283 SetSalFlag(struct fsbnode
*abnode
, int aflag
)
288 /* don't use the salvage flag for demand attach fs */
289 if (abnode
->salsrvcmd
== NULL
) {
290 abnode
->needsSalvage
= aflag
;
291 if (asprintf(&filepath
, "%s/%s%s", AFSDIR_SERVER_LOCAL_DIRPATH
,
292 SALFILE
, abnode
->b
.name
) < 0)
295 fd
= open(filepath
, O_CREAT
| O_TRUNC
| O_RDWR
, 0666);
305 /* set the needsSalvage flag according to the existence of the salvage file */
307 RestoreSalFlag(struct fsbnode
*abnode
)
311 /* never set needs salvage flag for demand attach fs */
312 if (abnode
->salsrvcmd
!= NULL
) {
313 abnode
->needsSalvage
= 0;
315 if (asprintf(&filepath
, "%s/%s%s", AFSDIR_SERVER_LOCAL_DIRPATH
,
316 SALFILE
, abnode
->b
.name
) < 0)
318 if (access(filepath
, 0) == 0) {
319 /* file exists, so need to salvage */
320 abnode
->needsSalvage
= 1;
322 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
);
345 /*! PathToExecutable() - for both Unix and Windows, accept a full bnode
346 * command, including any arguments, and return only the path to the
347 * binary executable, with arguments stripped.
349 * \notes The caller will stat() the returned path.
351 * \param cmd - full bnode command string with arguments
353 * \return - string path to the binary executable, to be freed by the caller
356 /* The Windows implementation must also ensure that an extension is
357 * specified in the path.
361 PathToExecutable(char *cmd
)
363 char cmdext
[_MAX_EXT
];
364 char *cmdexe
, *cmdcopy
, *cmdname
;
367 cmdcopy
= strdup(cmd
);
368 if (cmdcopy
== NULL
) {
371 /* strip off any arguments */
372 cmdname
= strsep(&cmdcopy
, " \t"); /* roken, I'm hopin' */
373 if (*cmdname
== '\0') {
377 /* Is there an extension specified? */
378 _splitpath(cmdname
, NULL
, NULL
, NULL
, cmdext
);
379 if (*cmdext
== '\0') {
380 /* No, supply one. */
381 if (asprintf(&cmdexe
, "%s.exe", cmdname
) < 0) {
390 #else /* AFS_NT40_ENV */
391 /* Unix implementation is extension-agnostic. */
393 PathToExecutable(char *cmd
)
395 char *cmdcopy
, *cmdname
;
396 cmdcopy
= strdup(cmd
);
397 if (cmdcopy
== NULL
) {
400 cmdname
= strsep(&cmdcopy
, " ");
401 if (*cmdname
== '\0') {
407 #endif /* AFS_NT40_ENV */
411 fs_create(char *ainstance
, char *afilecmd
, char *avolcmd
, char *asalcmd
,
412 char *ascancmd
, char *dummy
)
416 char *cmdname
= NULL
;
417 char *fileCmdpath
, *volCmdpath
, *salCmdpath
, *scanCmdpath
;
420 fileCmdpath
= volCmdpath
= salCmdpath
= scanCmdpath
= NULL
;
423 /* construct local paths from canonical (wire-format) paths */
424 if (ConstructLocalBinPath(afilecmd
, &fileCmdpath
)) {
425 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd
);
429 if (ConstructLocalBinPath(avolcmd
, &volCmdpath
)) {
430 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd
);
434 if (ConstructLocalBinPath(asalcmd
, &salCmdpath
)) {
435 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd
);
440 if (ascancmd
&& strlen(ascancmd
)) {
441 if (ConstructLocalBinPath(ascancmd
, &scanCmdpath
)) {
442 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd
);
449 cmdname
= PathToExecutable(fileCmdpath
);
450 if (cmdname
== NULL
) {
451 bozo_Log("Out of memory constructing binary filename\n");
455 if (stat(cmdname
, &tstat
)) {
456 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname
);
462 cmdname
= PathToExecutable(volCmdpath
);
463 if (cmdname
== NULL
) {
464 bozo_Log("Out of memory constructing binary filename\n");
468 if (stat(cmdname
, &tstat
)) {
469 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname
);
475 cmdname
= PathToExecutable(salCmdpath
);
476 if (cmdname
== NULL
) {
477 bozo_Log("Out of memory constructing binary filename\n");
481 if (stat(cmdname
, &tstat
)) {
482 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname
);
487 if (ascancmd
&& strlen(ascancmd
)) {
489 cmdname
= PathToExecutable(scanCmdpath
);
490 if (cmdname
== NULL
) {
491 bozo_Log("Out of memory constructing binary filename\n");
495 if (stat(cmdname
, &tstat
)) {
496 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname
);
503 te
= calloc(1, sizeof(struct fsbnode
));
508 te
->filecmd
= fileCmdpath
;
509 te
->volcmd
= volCmdpath
;
510 te
->salsrvcmd
= NULL
;
511 te
->salcmd
= salCmdpath
;
512 if (ascancmd
&& strlen(ascancmd
))
513 te
->scancmd
= scanCmdpath
;
516 if (bnode_InitBnode(fsbnode2bnode(te
), &fsbnode_ops
, ainstance
) != 0) {
520 bnode_SetTimeout(fsbnode2bnode(te
), POLLTIME
);
521 /* ask for timeout activations every 20 seconds */
522 RestoreSalFlag(te
); /* restore needsSalvage flag based on file's existence */
523 SetNeedsClock(te
); /* compute needsClock field */
541 return fsbnode2bnode(te
);
544 /* create a demand attach fs bnode */
546 dafs_create(char *ainstance
, char *afilecmd
, char *avolcmd
,
547 char * asalsrvcmd
, char *asalcmd
, char *ascancmd
)
551 char *cmdname
= NULL
;
552 char *fileCmdpath
, *volCmdpath
, *salsrvCmdpath
, *salCmdpath
, *scanCmdpath
;
555 fileCmdpath
= volCmdpath
= salsrvCmdpath
= salCmdpath
= scanCmdpath
= NULL
;
558 /* construct local paths from canonical (wire-format) paths */
559 if (ConstructLocalBinPath(afilecmd
, &fileCmdpath
)) {
560 bozo_Log("BNODE: command path invalid '%s'\n", afilecmd
);
564 if (ConstructLocalBinPath(avolcmd
, &volCmdpath
)) {
565 bozo_Log("BNODE: command path invalid '%s'\n", avolcmd
);
569 if (ConstructLocalBinPath(asalsrvcmd
, &salsrvCmdpath
)) {
570 bozo_Log("BNODE: command path invalid '%s'\n", asalsrvcmd
);
574 if (ConstructLocalBinPath(asalcmd
, &salCmdpath
)) {
575 bozo_Log("BNODE: command path invalid '%s'\n", asalcmd
);
580 if (ascancmd
&& strlen(ascancmd
)) {
581 if (ConstructLocalBinPath(ascancmd
, &scanCmdpath
)) {
582 bozo_Log("BNODE: command path invalid '%s'\n", ascancmd
);
589 cmdname
= PathToExecutable(fileCmdpath
);
590 if (cmdname
== NULL
) {
591 bozo_Log("Out of memory constructing binary filename\n");
595 if (stat(cmdname
, &tstat
)) {
596 bozo_Log("BNODE: file server binary '%s' not found\n", cmdname
);
602 cmdname
= PathToExecutable(volCmdpath
);
603 if (cmdname
== NULL
) {
604 bozo_Log("Out of memory constructing binary filename\n");
608 if (stat(cmdname
, &tstat
)) {
609 bozo_Log("BNODE: volume server binary '%s' not found\n", cmdname
);
615 cmdname
= PathToExecutable(salsrvCmdpath
);
616 if (cmdname
== NULL
) {
617 bozo_Log("Out of memory constructing binary filename\n");
621 if (stat(cmdname
, &tstat
)) {
622 bozo_Log("BNODE: salvageserver binary '%s' not found\n", cmdname
);
628 cmdname
= PathToExecutable(salCmdpath
);
629 if (cmdname
== NULL
) {
630 bozo_Log("Out of memory constructing binary filename\n");
634 if (stat(cmdname
, &tstat
)) {
635 bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname
);
640 if (ascancmd
&& strlen(ascancmd
)) {
642 cmdname
= PathToExecutable(scanCmdpath
);
643 if (cmdname
== NULL
) {
644 bozo_Log("Out of memory constructing binary filename\n");
648 if (stat(cmdname
, &tstat
)) {
649 bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname
);
656 te
= calloc(1, sizeof(struct fsbnode
));
661 te
->filecmd
= fileCmdpath
;
662 te
->volcmd
= volCmdpath
;
663 te
->salsrvcmd
= salsrvCmdpath
;
664 te
->salcmd
= salCmdpath
;
665 if (ascancmd
&& strlen(ascancmd
))
666 te
->scancmd
= scanCmdpath
;
669 if (bnode_InitBnode(fsbnode2bnode(te
), &dafsbnode_ops
, ainstance
) != 0) {
673 bnode_SetTimeout(fsbnode2bnode(te
), POLLTIME
);
674 /* ask for timeout activations every 20 seconds */
675 RestoreSalFlag(te
); /* restore needsSalvage flag based on file's existence */
676 SetNeedsClock(te
); /* compute needsClock field */
696 return fsbnode2bnode(te
);
699 /* called to SIGKILL a process if it doesn't terminate normally */
701 fs_timeout(struct bnode
*bn
)
703 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
707 now
= FT_ApproxTime();
709 if (abnode
->volSDW
) {
710 if (!abnode
->volKillSent
&& now
- abnode
->timeSDStarted
> SDTIME
) {
711 bnode_StopProc(abnode
->volProc
, SIGKILL
);
712 abnode
->volKillSent
= 1;
714 ("bos shutdown: volserver failed to shutdown within %d seconds\n",
718 if (abnode
->salSDW
) {
719 if (!abnode
->salKillSent
&& now
- abnode
->timeSDStarted
> SDTIME
) {
720 bnode_StopProc(abnode
->salProc
, SIGKILL
);
721 abnode
->salKillSent
= 1;
723 ("bos shutdown: salvager failed to shutdown within %d seconds\n",
727 if (abnode
->fileSDW
) {
728 if (!abnode
->fileKillSent
&& now
- abnode
->timeSDStarted
> FSSDTIME
) {
729 bnode_StopProc(abnode
->fileProc
, SIGKILL
);
730 abnode
->fileKillSent
= 1;
732 ("bos shutdown: fileserver failed to shutdown within %d seconds\n",
736 if (abnode
->salsrvSDW
) {
737 if (!abnode
->salsrvKillSent
&& now
- abnode
->timeSDStarted
> SDTIME
) {
738 bnode_StopProc(abnode
->salsrvProc
, SIGKILL
);
739 abnode
->salsrvKillSent
= 1;
741 ("bos shutdown: salvageserver failed to shutdown within %d seconds\n",
745 if (abnode
->scanSDW
) {
746 if (!abnode
->scanKillSent
&& now
- abnode
->timeSDStarted
> SDTIME
) {
747 bnode_StopProc(abnode
->scanProc
, SIGKILL
);
748 abnode
->scanKillSent
= 1;
750 ("bos shutdown: scanner failed to shutdown within %d seconds\n",
755 if ((abnode
->b
.flags
& BNODE_ERRORSTOP
) && !abnode
->salRunning
756 && !abnode
->volRunning
&& !abnode
->fileRunning
&& !abnode
->scanRunning
757 && !abnode
->salsrvRunning
) {
758 bnode_SetStat(bn
, BSTAT_NORMAL
);
761 bnode_ResetErrorCount(bn
);
764 SetNeedsClock(abnode
);
769 fs_getstat(struct bnode
*bn
, afs_int32
* astatus
)
771 struct fsbnode
*abnode
= (struct fsbnode
*) bn
;
774 if (abnode
->volSDW
|| abnode
->fileSDW
|| abnode
->salSDW
775 || abnode
->scanSDW
|| abnode
->salsrvSDW
)
776 temp
= BSTAT_SHUTTINGDOWN
;
777 else if (abnode
->salRunning
)
779 else if (abnode
->volRunning
&& abnode
->fileRunning
780 && (!abnode
->scancmd
|| abnode
->scanRunning
)
781 && (!abnode
->salsrvcmd
|| abnode
->salsrvRunning
))
783 else if (!abnode
->salRunning
&& !abnode
->volRunning
784 && !abnode
->fileRunning
&& !abnode
->scanRunning
785 && !abnode
->salsrvRunning
)
786 temp
= BSTAT_SHUTDOWN
;
788 temp
= BSTAT_STARTINGUP
;
794 fs_setstat(struct bnode
*abnode
, afs_int32 astatus
)
796 return NudgeProcs((struct fsbnode
*) abnode
);
800 fs_procstarted(struct bnode
*bn
, struct bnode_proc
*aproc
)
805 code
= bozo_CreatePidFile(bn
->name
, aproc
->coreName
, aproc
->pid
);
811 fs_procexit(struct bnode
*bn
, struct bnode_proc
*aproc
)
813 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
815 /* process has exited */
818 bozo_DeletePidFile(bn
->name
, aproc
->coreName
);
821 if (aproc
== abnode
->volProc
) {
823 abnode
->volRunning
= 0;
825 abnode
->volKillSent
= 0;
826 } else if (aproc
== abnode
->fileProc
) {
827 /* if we were expecting a shutdown and we didn't send a kill signal
828 * and exited (didn't have a signal termination), then we assume that
829 * the file server exited after putting the appropriate volumes safely
830 * offline, and don't salvage next time.
832 if (abnode
->fileSDW
&& !abnode
->fileKillSent
833 && aproc
->lastSignal
== 0)
834 SetSalFlag(abnode
, 0); /* shut down normally */
835 abnode
->fileProc
= 0;
836 abnode
->fileRunning
= 0;
838 abnode
->fileKillSent
= 0;
839 } else if (aproc
== abnode
->salProc
) {
840 /* if we didn't shutdown the salvager, then assume it exited ok, and thus
841 * that we don't have to salvage again */
843 SetSalFlag(abnode
, 0); /* salvage just completed */
845 abnode
->salRunning
= 0;
847 abnode
->salKillSent
= 0;
848 } else if (aproc
== abnode
->scanProc
) {
849 abnode
->scanProc
= 0;
850 abnode
->scanRunning
= 0;
852 abnode
->scanKillSent
= 0;
853 } else if (aproc
== abnode
->salsrvProc
) {
854 abnode
->salsrvProc
= 0;
855 abnode
->salsrvRunning
= 0;
856 abnode
->salsrvSDW
= 0;
857 abnode
->salsrvKillSent
= 0;
860 /* now restart anyone who needs to restart */
861 return NudgeProcs(abnode
);
864 /* make sure we're periodically checking the state if we need to */
866 SetNeedsClock(struct fsbnode
*ab
)
868 afs_int32 timeout
= POLLTIME
;
870 if ((ab
->fileSDW
&& !ab
->fileKillSent
) || (ab
->volSDW
&& !ab
->volKillSent
)
871 || (ab
->scanSDW
&& !ab
->scanKillSent
) || (ab
->salSDW
&& !ab
->salKillSent
)
872 || (ab
->salsrvSDW
&& !ab
->salsrvKillSent
)) {
873 /* SIGQUIT sent, will send SIGKILL if process does not exit */
875 } else if (ab
->b
.goal
== 1 && ab
->fileRunning
&& ab
->volRunning
876 && (!ab
->scancmd
|| ab
->scanRunning
)
877 && (!ab
->salsrvcmd
|| ab
->salsrvRunning
)) {
878 if (ab
->b
.errorStopCount
) {
879 /* reset error count after running for a bit */
882 ab
->needsClock
= 0; /* running normally */
884 } else if ((ab
->b
.goal
== 0) && !ab
->fileRunning
&& !ab
->volRunning
885 && !ab
->salRunning
&& !ab
->scanRunning
&& !ab
->salsrvRunning
) {
886 if (ab
->b
.flags
& BNODE_ERRORSTOP
&& ab
->b
.errorStopDelay
) {
887 bozo_Log("%s will retry start in %d seconds\n", ab
->b
.name
,
888 ab
->b
.errorStopDelay
);
889 ab
->needsClock
= 1; /* halted for errors, retry later */
890 timeout
= ab
->b
.errorStopDelay
;
892 ab
->needsClock
= 0; /* halted normally */
895 ab
->needsClock
= 1; /* other */
897 if (ab
->needsClock
&& (!bnode_PendingTimeout(fsbnode2bnode(ab
))
898 || ab
->b
.period
!= timeout
))
899 bnode_SetTimeout(fsbnode2bnode(ab
), timeout
);
901 bnode_SetTimeout(fsbnode2bnode(ab
), 0);
905 NudgeProcs(struct fsbnode
*abnode
)
907 struct bnode_proc
*tp
; /* not register */
911 now
= FT_ApproxTime();
912 if (abnode
->b
.goal
== 1) {
913 /* we're trying to run the system. If the file server is running, then we
914 * are trying to start up the system. If it is not running, then needsSalvage
915 * tells us if we need to run the salvager or not */
916 if (abnode
->fileRunning
) {
917 if (abnode
->salRunning
) {
918 bozo_Log("Salvager running along with file server!\n");
919 bozo_Log("Emergency shutdown\n");
921 bnode_SetGoal(fsbnode2bnode(abnode
), BSTAT_SHUTDOWN
);
922 bnode_StopProc(abnode
->salProc
, SIGKILL
);
923 SetNeedsClock(abnode
);
926 if (!abnode
->volRunning
) {
927 abnode
->lastVolStart
= FT_ApproxTime();
928 code
= bnode_NewProc(fsbnode2bnode(abnode
), abnode
->volcmd
, "vol", &tp
);
930 abnode
->volProc
= tp
;
931 abnode
->volRunning
= 1;
934 if (abnode
->salsrvcmd
) {
935 if (!abnode
->salsrvRunning
) {
936 abnode
->lastSalsrvStart
= FT_ApproxTime();
938 bnode_NewProc(fsbnode2bnode(abnode
), abnode
->salsrvcmd
, "salsrv",
941 abnode
->salsrvProc
= tp
;
942 abnode
->salsrvRunning
= 1;
946 if (abnode
->scancmd
) {
947 if (!abnode
->scanRunning
) {
948 abnode
->lastScanStart
= FT_ApproxTime();
950 bnode_NewProc(fsbnode2bnode(abnode
), abnode
->scancmd
, "scanner",
953 abnode
->scanProc
= tp
;
954 abnode
->scanRunning
= 1;
958 } else { /* file is not running */
959 /* see how to start */
960 /* for demand attach fs, needsSalvage flag is ignored */
961 if (!abnode
->needsSalvage
|| abnode
->salsrvcmd
) {
962 /* no crash apparent, just start up normally */
963 if (!abnode
->fileRunning
) {
964 abnode
->lastFileStart
= FT_ApproxTime();
966 bnode_NewProc(fsbnode2bnode(abnode
), abnode
->filecmd
, "file", &tp
);
968 abnode
->fileProc
= tp
;
969 abnode
->fileRunning
= 1;
970 SetSalFlag(abnode
, 1);
973 if (!abnode
->volRunning
) {
974 abnode
->lastVolStart
= FT_ApproxTime();
975 code
= bnode_NewProc(fsbnode2bnode(abnode
), abnode
->volcmd
, "vol", &tp
);
977 abnode
->volProc
= tp
;
978 abnode
->volRunning
= 1;
981 if (abnode
->salsrvcmd
&& !abnode
->salsrvRunning
) {
982 abnode
->lastSalsrvStart
= FT_ApproxTime();
984 bnode_NewProc(fsbnode2bnode(abnode
), abnode
->salsrvcmd
, "salsrv",
987 abnode
->salsrvProc
= tp
;
988 abnode
->salsrvRunning
= 1;
991 if (abnode
->scancmd
&& !abnode
->scanRunning
) {
992 abnode
->lastScanStart
= FT_ApproxTime();
994 bnode_NewProc(fsbnode2bnode(abnode
), abnode
->scancmd
, "scanner",
997 abnode
->scanProc
= tp
;
998 abnode
->scanRunning
= 1;
1001 } else { /* needs to be salvaged */
1002 /* make sure file server and volser are gone */
1003 if (abnode
->volRunning
) {
1004 bnode_StopProc(abnode
->volProc
, SIGTERM
);
1005 if (!abnode
->volSDW
)
1006 abnode
->timeSDStarted
= now
;
1009 if (abnode
->fileRunning
) {
1010 bnode_StopProc(abnode
->fileProc
, SIGQUIT
);
1011 if (!abnode
->fileSDW
)
1012 abnode
->timeSDStarted
= now
;
1013 abnode
->fileSDW
= 1;
1015 if (abnode
->scanRunning
) {
1016 bnode_StopProc(abnode
->scanProc
, SIGTERM
);
1017 if (!abnode
->scanSDW
)
1018 abnode
->timeSDStarted
= now
;
1019 abnode
->scanSDW
= 1;
1021 if (abnode
->volRunning
|| abnode
->fileRunning
1022 || abnode
->scanRunning
)
1024 /* otherwise, it is safe to start salvager */
1025 if (!abnode
->salRunning
) {
1026 code
= bnode_NewProc(fsbnode2bnode(abnode
), abnode
->salcmd
, "salv", &tp
);
1028 abnode
->salProc
= tp
;
1029 abnode
->salRunning
= 1;
1034 } else { /* goal is 0, we're shutting down */
1035 /* trying to shutdown */
1036 if (abnode
->salRunning
&& !abnode
->salSDW
) {
1037 bnode_StopProc(abnode
->salProc
, SIGTERM
);
1039 abnode
->timeSDStarted
= now
;
1041 if (abnode
->fileRunning
&& !abnode
->fileSDW
) {
1042 bnode_StopProc(abnode
->fileProc
, SIGQUIT
);
1043 abnode
->fileSDW
= 1;
1044 abnode
->timeSDStarted
= now
;
1046 if (abnode
->volRunning
&& !abnode
->volSDW
) {
1047 bnode_StopProc(abnode
->volProc
, SIGTERM
);
1049 abnode
->timeSDStarted
= now
;
1051 if (abnode
->salsrvRunning
&& !abnode
->salsrvSDW
) {
1052 bnode_StopProc(abnode
->salsrvProc
, SIGTERM
);
1053 abnode
->salsrvSDW
= 1;
1054 abnode
->timeSDStarted
= now
;
1056 if (abnode
->scanRunning
&& !abnode
->scanSDW
) {
1057 bnode_StopProc(abnode
->scanProc
, SIGTERM
);
1058 abnode
->scanSDW
= 1;
1059 abnode
->timeSDStarted
= now
;
1062 SetNeedsClock(abnode
);
1067 fs_getstring(struct bnode
*bn
, char *abuffer
, afs_int32 alen
)
1069 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
1073 if (abnode
->b
.goal
== 1) {
1074 if (abnode
->fileRunning
) {
1075 if (abnode
->fileSDW
)
1076 strcpy(abuffer
, "file server shutting down");
1077 else if (abnode
->scancmd
) {
1078 if (!abnode
->volRunning
&& !abnode
->scanRunning
)
1080 "file server up; volser and scanner down");
1081 else if (abnode
->volRunning
&& !abnode
->scanRunning
)
1083 "file server up; volser up; scanner down");
1084 else if (!abnode
->volRunning
&& abnode
->scanRunning
)
1086 "file server up; volser down; scanner up");
1089 strcpy(abuffer
, "file server running");
1090 } else if (!abnode
->volRunning
)
1091 strcpy(abuffer
, "file server up; volser down");
1093 strcpy(abuffer
, "file server running");
1094 } else if (abnode
->salRunning
) {
1095 strcpy(abuffer
, "salvaging file system");
1097 strcpy(abuffer
, "starting file server");
1100 if (abnode
->fileRunning
|| abnode
->volRunning
|| abnode
->scanRunning
) {
1101 strcpy(abuffer
, "file server shutting down");
1102 } else if (abnode
->salRunning
)
1103 strcpy(abuffer
, "salvager shutting down");
1105 strcpy(abuffer
, "file server shut down");
1111 fs_getparm(struct bnode
*bn
, afs_int32 aindex
, char *abuffer
,
1114 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
1117 strcpy(abuffer
, abnode
->filecmd
);
1118 else if (aindex
== 1)
1119 strcpy(abuffer
, abnode
->volcmd
);
1120 else if (aindex
== 2)
1121 strcpy(abuffer
, abnode
->salcmd
);
1122 else if (aindex
== 3 && abnode
->scancmd
)
1123 strcpy(abuffer
, abnode
->scancmd
);
1130 dafs_getparm(struct bnode
*bn
, afs_int32 aindex
, char *abuffer
,
1133 struct fsbnode
*abnode
= (struct fsbnode
*)bn
;
1136 strcpy(abuffer
, abnode
->filecmd
);
1137 else if (aindex
== 1)
1138 strcpy(abuffer
, abnode
->volcmd
);
1139 else if (aindex
== 2)
1140 strcpy(abuffer
, abnode
->salsrvcmd
);
1141 else if (aindex
== 3)
1142 strcpy(abuffer
, abnode
->salcmd
);
1143 else if (aindex
== 4 && abnode
->scancmd
)
1144 strcpy(abuffer
, abnode
->scancmd
);