2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
14 #include <afs/procmgmt.h>
18 #ifdef IGNORE_SOME_GCC_WARNINGS
20 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
22 # pragma GCC diagnostic warning "-Wdeprecated-declarations"
26 #ifdef HAVE_SYS_RESOURCE_H
27 #include <sys/resource.h>
31 #define PATH_DELIM '\\'
33 #include <WINNT/afsevent.h>
34 #endif /* AFS_NT40_ENV */
36 #define PATH_DELIM '/'
39 #include <rx/rx_globals.h>
41 #include <rx/rxstat.h>
43 #include <afs/ktime.h>
44 #include <afs/afsutil.h>
45 #include <afs/fileutil.h>
46 #include <afs/audit.h>
47 #include <afs/cellconfig.h>
49 #if defined(AFS_SGI_ENV)
50 #include <afs/afs_args.h>
55 #include "bnode_internal.h"
56 #include "bosprototypes.h"
58 #define BOZO_LWP_STACKSIZE 16000
59 extern struct bnode_ops fsbnode_ops
, dafsbnode_ops
, ezbnode_ops
, cronbnode_ops
;
61 struct afsconf_dir
*bozo_confdir
= 0; /* bozo configuration dir */
62 static PROCESS bozo_pid
;
63 const char *bozo_fileName
;
66 static int bozo_argc
= 0;
67 static char** bozo_argv
= NULL
;
73 const char *DoPidFiles
= NULL
;
75 int DoSyslogFacility
= LOG_DAEMON
;
77 int DoTransarcLogs
= 0;
78 static afs_int32 nextRestart
;
79 static afs_int32 nextDay
;
81 struct ktime bozo_nextRestartKT
, bozo_nextDayKT
;
84 int rxkadDisableDotCheck
= 0;
86 int bozo_isrestricted
= 0;
87 int bozo_restdisable
= 0;
90 bozo_insecureme(int sig
)
92 signal(SIGFPE
, bozo_insecureme
);
93 bozo_isrestricted
= 0;
101 /* check whether caller is authorized to manage RX statistics */
103 bozo_rxstat_userok(struct rx_call
*call
)
105 return afsconf_SuperUser(bozo_confdir
, call
, NULL
);
109 * Return true if this name is a member of the local realm.
112 bozo_IsLocalRealmMatch(void *rock
, char *name
, char *inst
, char *cell
)
114 struct afsconf_dir
*dir
= (struct afsconf_dir
*)rock
;
115 afs_int32 islocal
= 0; /* default to no */
118 code
= afsconf_IsLocalRealmMatch(dir
, &islocal
, name
, inst
, cell
);
120 bozo_Log("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n",
121 code
, name
, inst
, cell
);
126 /* restart bozo process */
131 /* exit with restart code; SCM integrator process will restart bosserver with
132 the same arguments */
133 exit(BOSEXIT_RESTART
);
135 /* exec new bosserver process */
138 /* close random fd's */
139 for (i
= 3; i
< 64; i
++) {
143 unlink(AFSDIR_SERVER_BOZRXBIND_FILEPATH
);
145 execv(bozo_argv
[0], bozo_argv
); /* should not return */
147 #endif /* AFS_NT40_ENV */
151 * Make directory with parents.
153 * \param[in] adir directory path to create
154 * \param[in] areqPerm permissions to set on the last component of adir
155 * \return 0 on success
158 MakeDirParents(const char *adir
, int areqPerm
)
164 int parent_perm
= 0777; /* use umask for parent perms */
172 /* strip trailing slashes */
178 while (p
!= tdir
&& *p
== PATH_DELIM
) {
184 /* skip drive letter */
185 if (isalpha(p
[0]) && p
[1] == ':') {
189 /* skip leading slashes */
190 while (*p
== PATH_DELIM
) {
194 /* create parent directories with default perms */
195 p
= strchr(p
, PATH_DELIM
);
198 if (stat(tdir
, &stats
) != 0 || !S_ISDIR(stats
.st_mode
)) {
199 if (mkdir(tdir
, parent_perm
) != 0) {
206 /* skip back to back slashes */
207 while (*p
== PATH_DELIM
) {
210 p
= strchr(p
, PATH_DELIM
);
213 /* set required perms on the last path component */
214 if (stat(tdir
, &stats
) != 0 || !S_ISDIR(stats
.st_mode
)) {
215 if (mkdir(tdir
, areqPerm
) != 0) {
225 /* make sure a dir exists */
227 MakeDir(const char *adir
)
231 if (stat(adir
, &tstat
) < 0 || (tstat
.st_mode
& S_IFMT
) != S_IFDIR
) {
234 reqPerm
= GetRequiredDirPerm(adir
);
237 code
= MakeDirParents(adir
, reqPerm
);
243 /* create all the bozo dirs */
245 CreateDirs(const char *coredir
)
248 (AFSDIR_USR_DIRPATH
, AFSDIR_CLIENT_ETC_DIRPATH
,
249 strlen(AFSDIR_USR_DIRPATH
)))
252 (AFSDIR_USR_DIRPATH
, AFSDIR_SERVER_BIN_DIRPATH
,
253 strlen(AFSDIR_USR_DIRPATH
)))) {
254 if (MakeDir(AFSDIR_USR_DIRPATH
))
258 (AFSDIR_SERVER_AFS_DIRPATH
, AFSDIR_SERVER_BIN_DIRPATH
,
259 strlen(AFSDIR_SERVER_AFS_DIRPATH
))) {
260 if (MakeDir(AFSDIR_SERVER_AFS_DIRPATH
))
263 if (MakeDir(AFSDIR_SERVER_BIN_DIRPATH
))
265 if (MakeDir(AFSDIR_SERVER_ETC_DIRPATH
))
267 if (MakeDir(AFSDIR_SERVER_LOCAL_DIRPATH
))
269 if (MakeDir(AFSDIR_SERVER_DB_DIRPATH
))
271 if (MakeDir(AFSDIR_SERVER_LOGS_DIRPATH
))
275 (AFSDIR_CLIENT_VICE_DIRPATH
, AFSDIR_CLIENT_ETC_DIRPATH
,
276 strlen(AFSDIR_CLIENT_VICE_DIRPATH
))) {
277 if (MakeDir(AFSDIR_CLIENT_VICE_DIRPATH
))
280 if (MakeDir(AFSDIR_CLIENT_ETC_DIRPATH
))
283 if (symlink(AFSDIR_SERVER_THISCELL_FILEPATH
,
284 AFSDIR_CLIENT_THISCELL_FILEPATH
)) {
285 if (errno
!= EEXIST
) {
289 if (symlink(AFSDIR_SERVER_CELLSERVDB_FILEPATH
,
290 AFSDIR_CLIENT_CELLSERVDB_FILEPATH
)) {
291 if (errno
!= EEXIST
) {
295 #endif /* AFS_NT40_ENV */
297 if (MakeDir(coredir
))
303 /* strip the \\n from the end of the line, if it is present */
305 StripLine(char *abuffer
)
309 tp
= abuffer
+ strlen(abuffer
); /* starts off pointing at the null */
311 return 0; /* null string, no last character to check */
312 tp
--; /* aim at last character */
318 /* write one bnode's worth of entry into the file */
320 bzwrite(struct bnode
*abnode
, void *arock
)
322 struct bztemp
*at
= (struct bztemp
*)arock
;
324 char tbuffer
[BOZO_BSSIZE
];
327 if (abnode
->notifier
)
328 fprintf(at
->file
, "bnode %s %s %d %s\n", abnode
->type
->name
,
329 abnode
->name
, abnode
->fileGoal
, abnode
->notifier
);
331 fprintf(at
->file
, "bnode %s %s %d\n", abnode
->type
->name
,
332 abnode
->name
, abnode
->fileGoal
);
334 code
= bnode_GetParm(abnode
, i
, tbuffer
, BOZO_BSSIZE
);
340 fprintf(at
->file
, "parm %s\n", tbuffer
);
342 fprintf(at
->file
, "end\n");
348 ReadBozoFile(char *aname
)
351 char tbuffer
[BOZO_BSSIZE
];
353 char *instp
, *typep
, *notifier
, *notp
;
355 afs_int32 ktmask
, ktday
, kthour
, ktmin
, ktsec
;
358 char *parms
[MAXPARMS
];
359 char *thisparms
[MAXPARMS
];
362 /* rename BozoInit to BosServer for the user */
364 /* if BozoInit exists and BosConfig doesn't, try a rename */
365 if (access(AFSDIR_SERVER_BOZINIT_FILEPATH
, 0) == 0
366 && access(AFSDIR_SERVER_BOZCONF_FILEPATH
, 0) != 0) {
367 code
= rk_rename(AFSDIR_SERVER_BOZINIT_FILEPATH
,
368 AFSDIR_SERVER_BOZCONF_FILEPATH
);
370 perror("bosconfig rename");
372 if (access(AFSDIR_SERVER_BOZCONFNEW_FILEPATH
, 0) == 0) {
373 code
= rk_rename(AFSDIR_SERVER_BOZCONFNEW_FILEPATH
,
374 AFSDIR_SERVER_BOZCONF_FILEPATH
);
376 perror("bosconfig rename");
380 /* don't do server restarts by default */
381 bozo_nextRestartKT
.mask
= KTIME_NEVER
;
382 bozo_nextRestartKT
.hour
= 0;
383 bozo_nextRestartKT
.min
= 0;
384 bozo_nextRestartKT
.day
= 0;
386 /* restart processes at 5am if their binaries have changed */
387 bozo_nextDayKT
.mask
= KTIME_HOUR
| KTIME_MIN
;
388 bozo_nextDayKT
.hour
= 5;
389 bozo_nextDayKT
.min
= 0;
391 for (code
= 0; code
< MAXPARMS
; code
++)
394 aname
= (char *)bozo_fileName
;
395 tfile
= fopen(aname
, "r");
398 instp
= malloc(BOZO_BSSIZE
);
399 typep
= malloc(BOZO_BSSIZE
);
400 notp
= malloc(BOZO_BSSIZE
);
402 /* ok, read lines giving parms and such from the file */
403 tp
= fgets(tbuffer
, sizeof(tbuffer
), tfile
);
405 break; /* all done */
407 if (strncmp(tbuffer
, "restarttime", 11) == 0) {
409 sscanf(tbuffer
, "restarttime %d %d %d %d %d", &ktmask
, &ktday
,
410 &kthour
, &ktmin
, &ktsec
);
415 /* otherwise we've read in the proper ktime structure; now assign
416 * it and continue processing */
417 bozo_nextRestartKT
.mask
= ktmask
;
418 bozo_nextRestartKT
.day
= ktday
;
419 bozo_nextRestartKT
.hour
= kthour
;
420 bozo_nextRestartKT
.min
= ktmin
;
421 bozo_nextRestartKT
.sec
= ktsec
;
425 if (strncmp(tbuffer
, "checkbintime", 12) == 0) {
427 sscanf(tbuffer
, "checkbintime %d %d %d %d %d", &ktmask
,
428 &ktday
, &kthour
, &ktmin
, &ktsec
);
433 /* otherwise we've read in the proper ktime structure; now assign
434 * it and continue processing */
435 bozo_nextDayKT
.mask
= ktmask
; /* time to restart the system */
436 bozo_nextDayKT
.day
= ktday
;
437 bozo_nextDayKT
.hour
= kthour
;
438 bozo_nextDayKT
.min
= ktmin
;
439 bozo_nextDayKT
.sec
= ktsec
;
443 if (strncmp(tbuffer
, "restrictmode", 12) == 0) {
444 code
= sscanf(tbuffer
, "restrictmode %d", &rmode
);
449 if (rmode
!= 0 && rmode
!= 1) {
453 bozo_isrestricted
= rmode
;
457 if (strncmp("bnode", tbuffer
, 5) != 0) {
463 sscanf(tbuffer
, "bnode %s %s %d %s", typep
, instp
, &goal
,
468 } else if (code
== 3)
471 memset(thisparms
, 0, sizeof(thisparms
));
473 for (i
= 0; i
< MAXPARMS
; i
++) {
474 /* now read the parms, until we see an "end" line */
475 tp
= fgets(tbuffer
, sizeof(tbuffer
), tfile
);
481 if (!strncmp(tbuffer
, "end", 3))
483 if (strncmp(tbuffer
, "parm ", 5)) {
485 goto fail
; /* no "parm " either */
487 if (!parms
[i
]) /* make sure there's space */
488 parms
[i
] = malloc(BOZO_BSSIZE
);
489 strcpy(parms
[i
], tbuffer
+ 5); /* remember the parameter for later */
490 thisparms
[i
] = parms
[i
];
493 /* ok, we have the type and parms, now create the object */
495 bnode_Create(typep
, instp
, &tb
, thisparms
[0], thisparms
[1],
496 thisparms
[2], thisparms
[3], thisparms
[4], notifier
,
497 goal
? BSTAT_NORMAL
: BSTAT_SHUTDOWN
, 0);
501 /* bnode created in 'temporarily shutdown' state;
502 * check to see if we are supposed to run this guy,
503 * and if so, start the process up */
505 bnode_SetStat(tb
, BSTAT_NORMAL
); /* set goal, taking effect immediately */
507 bnode_SetStat(tb
, BSTAT_SHUTDOWN
);
518 for (i
= 0; i
< MAXPARMS
; i
++)
526 /* write a new bozo file */
528 WriteBozoFile(char *aname
)
531 char *tbuffer
= NULL
;
537 aname
= (char *)bozo_fileName
;
538 if (asprintf(&tbuffer
, "%s.NBZ", aname
) < 0)
541 tfile
= fopen(tbuffer
, "w");
548 fprintf(tfile
, "restrictmode %d\n", bozo_isrestricted
);
549 fprintf(tfile
, "restarttime %d %d %d %d %d\n", bozo_nextRestartKT
.mask
,
550 bozo_nextRestartKT
.day
, bozo_nextRestartKT
.hour
,
551 bozo_nextRestartKT
.min
, bozo_nextRestartKT
.sec
);
552 fprintf(tfile
, "checkbintime %d %d %d %d %d\n", bozo_nextDayKT
.mask
,
553 bozo_nextDayKT
.day
, bozo_nextDayKT
.hour
, bozo_nextDayKT
.min
,
555 code
= bnode_ApplyInstance(bzwrite
, &btemp
);
556 if (code
|| (code
= ferror(tfile
))) { /* something went wrong */
562 /* close the file, check for errors and snap new file into place */
563 if (fclose(tfile
) == EOF
) {
568 code
= rk_rename(tbuffer
, aname
);
581 bdrestart(struct bnode
*abnode
, void *arock
)
585 if (abnode
->fileGoal
!= BSTAT_NORMAL
|| abnode
->goal
!= BSTAT_NORMAL
)
586 return 0; /* don't restart stopped bnodes */
588 code
= bnode_RestartP(abnode
);
590 /* restart the dude */
591 bnode_SetStat(abnode
, BSTAT_SHUTDOWN
);
592 bnode_WaitStatus(abnode
, BSTAT_SHUTDOWN
);
593 bnode_SetStat(abnode
, BSTAT_NORMAL
);
595 bnode_Release(abnode
);
596 return 0; /* keep trying all bnodes */
599 #define BOZO_MINSKIP 3600 /* minimum to advance clock */
600 /* lwp to handle system restarts */
602 BozoDaemon(void *unused
)
606 /* now initialize the values */
610 now
= FT_ApproxTime();
612 if (bozo_restdisable
) {
613 bozo_Log("Restricted mode disabled by signal\n");
614 bozo_restdisable
= 0;
617 if (bozo_newKTs
) { /* need to recompute restart times */
618 bozo_newKTs
= 0; /* done for a while */
619 nextRestart
= ktime_next(&bozo_nextRestartKT
, BOZO_MINSKIP
);
620 nextDay
= ktime_next(&bozo_nextDayKT
, BOZO_MINSKIP
);
623 /* see if we should do a restart */
624 if (now
> nextRestart
) {
625 SBOZO_ReBozo(0); /* doesn't come back */
628 /* see if we should restart a server */
630 nextDay
= ktime_next(&bozo_nextDayKT
, BOZO_MINSKIP
);
632 /* call the bnode restartp function, and restart all that require it */
633 bnode_ApplyInstance(bdrestart
, 0);
645 int s
, sb_max
, ipfragttl
;
649 f
= popen("/usr/sbin/no -o sb_max", "r");
650 s
= fscanf(f
, "sb_max = %d", &sb_max
);
654 f
= popen("/usr/sbin/no -o ipfragttl", "r");
655 s
= fscanf(f
, "ipfragttl = %d", &ipfragttl
);
665 sprintf(c
, "/usr/sbin/no -o sb_max=%d -o ipfragttl=%d", sb_max
,
673 make_pid_filename(char *ainst
, char *aname
)
678 if (aname
&& *aname
) {
679 r
= asprintf(&buffer
, "%s/%s.%s.pid", DoPidFiles
, ainst
, aname
);
680 if (r
< 0 || buffer
== NULL
)
681 bozo_Log("Failed to alloc pid filename buffer for %s.%s.\n",
684 r
= asprintf(&buffer
, "%s/%s.pid", DoPidFiles
, ainst
);
685 if (r
< 0 || buffer
== NULL
)
686 bozo_Log("Failed to alloc pid filename buffer for %s.\n", ainst
);
693 * Write a file containing the pid of the named process.
695 * @param ainst instance name
696 * @param aname sub-process name of the instance, may be null
697 * @param apid process id of the newly started process
702 bozo_CreatePidFile(char *ainst
, char *aname
, pid_t apid
)
705 char *pidfile
= NULL
;
708 pidfile
= make_pid_filename(ainst
, aname
);
712 if ((fp
= fopen(pidfile
, "w")) == NULL
) {
713 bozo_Log("Failed to open pidfile %s; errno=%d\n", pidfile
, errno
);
717 if (fprintf(fp
, "%ld\n", afs_printable_int32_ld(apid
)) < 0) {
720 if (fclose(fp
) != 0) {
728 * Clean a pid file for a process which just exited.
730 * @param ainst instance name
731 * @param aname sub-process name of the instance, may be null
736 bozo_DeletePidFile(char *ainst
, char *aname
)
738 char *pidfile
= NULL
;
739 pidfile
= make_pid_filename(ainst
, aname
);
748 * Create the rxbind file of this bosserver.
750 * @param host bind address of this server
755 bozo_CreateRxBindFile(afs_uint32 host
)
760 afs_inet_ntoa_r(host
, buffer
);
761 bozo_Log("Listening on %s:%d\n", buffer
, AFSCONF_NANNYPORT
);
762 if ((fp
= fopen(AFSDIR_SERVER_BOZRXBIND_FILEPATH
, "w")) == NULL
) {
763 bozo_Log("Unable to open rxbind address file: %s, code=%d\n",
764 AFSDIR_SERVER_BOZRXBIND_FILEPATH
, errno
);
766 /* If listening on any interface, write the loopback interface
767 to the rxbind file to give local scripts a usable addresss. */
768 if (host
== htonl(INADDR_ANY
)) {
769 afs_inet_ntoa_r(htonl(0x7f000001), buffer
);
771 fprintf(fp
, "%s\n", buffer
);
777 * Get an interface address in network byte order, modulo the
778 * NetInfo/NetRestrict configuration files. Return the INADDR_ANY if no
779 * interface address is found.
782 GetRxBindAddress(void)
785 afs_int32 ccode
; /* number of addresses found */
787 if (AFSDIR_SERVER_NETRESTRICT_FILEPATH
|| AFSDIR_SERVER_NETINFO_FILEPATH
) {
789 ccode
= afsconf_ParseNetFiles(&addr
, NULL
, NULL
, 1, reason
,
790 AFSDIR_SERVER_NETINFO_FILEPATH
,
791 AFSDIR_SERVER_NETRESTRICT_FILEPATH
);
793 /* Get the first non-loopback address from the kernel. */
794 ccode
= rx_getAllAddr(&addr
, 1);
798 addr
= htonl(INADDR_ANY
);
804 * Try to create local cell config file.
806 static struct afsconf_dir
*
807 CreateLocalCellConfig(void)
810 struct afsconf_dir
*tdir
= NULL
;
811 struct afsconf_cell tcell
;
813 memset(&tcell
, 0, sizeof(tcell
));
814 strcpy(tcell
.name
, "localcell"); /* assume name is big enough for the default value */
815 tcell
.numServers
= 1;
816 code
= gethostname(tcell
.hostName
[0], MAXHOSTCHARS
);
818 bozo_Log("failed to get hostname, code %d\n", errno
);
821 if (tcell
.hostName
[0][0] == 0) {
822 bozo_Log("host name not set, can't start\n");
823 bozo_Log("try the 'hostname' command\n");
826 code
= afsconf_SetCellInfo(NULL
, AFSDIR_SERVER_ETC_DIRPATH
, &tcell
);
829 ("could not create cell database in '%s' (code %d), quitting\n",
830 AFSDIR_SERVER_ETC_DIRPATH
, code
);
833 tdir
= afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH
);
835 bozo_Log("failed to open newly-created cell database, quitting\n");
841 /* start a process and monitor it */
843 #include "AFS_component_version_number.c"
846 main(int argc
, char **argv
, char **envp
)
848 struct rx_service
*tservice
;
850 struct afsconf_dir
*tdir
;
855 afs_uint32 host
= htonl(INADDR_ANY
);
856 char *auditFileName
= NULL
;
857 struct rx_securityClass
**securityClasses
;
858 afs_int32 numClasses
;
859 int DoPeerRPCStats
= 0;
860 int DoProcessRPCStats
= 0;
866 struct sigaction nsa
;
868 /* for some reason, this permits user-mode RX to run a lot faster.
869 * we do it here in the bosserver, so we don't have to do it
870 * individually in each server.
875 * The following signal action for AIX is necessary so that in case of a
876 * crash (i.e. core is generated) we can include the user's data section
877 * in the core dump. Unfortunately, by default, only a partial core is
878 * generated which, in many cases, isn't too useful.
880 sigemptyset(&nsa
.sa_mask
);
881 nsa
.sa_handler
= SIG_DFL
;
882 nsa
.sa_flags
= SA_FULLDUMP
;
883 sigaction(SIGSEGV
, &nsa
, NULL
);
884 sigaction(SIGABRT
, &nsa
, NULL
);
887 signal(SIGFPE
, bozo_insecureme
);
890 /* Initialize winsock */
891 if (afs_winsockInit() < 0) {
892 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED
, 0, argv
[0], 0);
893 fprintf(stderr
, "%s: Couldn't initialize winsock.\n", argv
[0]);
898 /* Initialize dirpaths */
899 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK
)) {
901 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR
, 0, argv
[0], 0);
903 fprintf(stderr
, "%s: Unable to obtain AFS server directory.\n",
908 /* some path inits */
909 bozo_fileName
= AFSDIR_SERVER_BOZCONF_FILEPATH
;
910 DoCore
= AFSDIR_SERVER_LOGS_DIRPATH
;
912 /* initialize the list of dirpaths that the bosserver has
913 * an interest in monitoring */
916 #if defined(AFS_SGI_ENV)
917 /* offer some protection if AFS isn't loaded */
918 if (syscall(AFS_SYSCALL
, AFSOP_ENDLOG
) < 0 && errno
== ENOPKG
) {
919 printf("bosserver: AFS doesn't appear to be configured in O.S..\n");
925 /* save args for restart */
927 bozo_argv
= malloc((argc
+1) * sizeof(char*));
929 fprintf(stderr
, "%s: Failed to allocate argument list.\n", argv
[0]);
932 bozo_argv
[0] = (char*)AFSDIR_SERVER_BOSVR_FILEPATH
; /* expected path */
933 bozo_argv
[bozo_argc
] = NULL
; /* null terminate list */
934 #endif /* AFS_NT40_ENV */
937 for (code
= 1; code
< argc
; code
++) {
939 bozo_argv
[code
] = argv
[code
];
940 #endif /* AFS_NT40_ENV */
941 if (strcmp(argv
[code
], "-noauth") == 0) {
942 /* set noauth flag */
944 } else if (strcmp(argv
[code
], "-log") == 0) {
945 /* set extra logging flag */
949 else if (strcmp(argv
[code
], "-syslog") == 0) {
950 /* set syslog logging flag */
952 } else if (strncmp(argv
[code
], "-syslog=", 8) == 0) {
954 DoSyslogFacility
= atoi(argv
[code
] + 8);
955 } else if (strncmp(argv
[code
], "-cores=", 7) == 0) {
956 if (strcmp((argv
[code
]+7), "none") == 0)
959 DoCore
= (argv
[code
]+7);
960 } else if (strcmp(argv
[code
], "-nofork") == 0) {
964 else if (strcmp(argv
[code
], "-enable_peer_stats") == 0) {
966 } else if (strcmp(argv
[code
], "-enable_process_stats") == 0) {
967 DoProcessRPCStats
= 1;
969 else if (strcmp(argv
[code
], "-restricted") == 0) {
970 bozo_isrestricted
= 1;
972 else if (strcmp(argv
[code
], "-rxbind") == 0) {
975 else if (strcmp(argv
[code
], "-allow-dotted-principals") == 0) {
976 rxkadDisableDotCheck
= 1;
978 else if (!strcmp(argv
[code
], "-rxmaxmtu")) {
979 if ((code
+ 1) >= argc
) {
980 fprintf(stderr
, "missing argument for -rxmaxmtu\n");
983 rxMaxMTU
= atoi(argv
[++code
]);
985 else if (strcmp(argv
[code
], "-auditlog") == 0) {
986 auditFileName
= argv
[++code
];
988 } else if (strcmp(argv
[code
], "-audit-interface") == 0) {
989 char *interface
= argv
[++code
];
991 if (osi_audit_interface(interface
)) {
992 printf("Invalid audit interface '%s'\n", interface
);
995 } else if (strncmp(argv
[code
], "-pidfiles=", 10) == 0) {
996 DoPidFiles
= (argv
[code
]+10);
997 } else if (strncmp(argv
[code
], "-pidfiles", 9) == 0) {
998 DoPidFiles
= AFSDIR_LOCAL_DIR
;
999 } else if (strcmp(argv
[code
], "-transarc-logs") == 0) {
1004 /* hack to support help flag */
1006 if (strcmp(argv
[code
], "-help") == 0 || strcmp(argv
[code
], "-h") == 0)
1007 ec
= 0; /* It is not an error to ask for usage. */
1009 printf("Unrecognized option: %s\n", argv
[code
]);
1013 #ifndef AFS_NT40_ENV
1014 printf("Usage: bosserver [-noauth] [-log] "
1015 "[-auditlog <log path>] "
1016 "[-audit-interface <file|sysvmq> (default is file)] "
1017 "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
1018 "[-syslog[=FACILITY]] "
1020 "[-enable_peer_stats] [-enable_process_stats] "
1021 "[-cores=<none|path>] \n"
1022 "[-pidfiles[=path]] "
1024 "[-nofork] " "[-help]\n");
1026 printf("Usage: bosserver [-noauth] [-log] "
1027 "[-auditlog <log path>] "
1028 "[-audit-interface <file|sysvmq> (default is file)] "
1029 "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
1031 "[-enable_peer_stats] [-enable_process_stats] "
1032 "[-cores=<none|path>] \n"
1033 "[-pidfiles[=path]] "
1041 if (auditFileName
) {
1042 osi_audit_file(auditFileName
);
1045 #ifndef AFS_NT40_ENV
1046 if (geteuid() != 0) {
1047 printf("bosserver: must be run as root.\n");
1052 /* create useful dirs */
1053 i
= CreateDirs(DoCore
);
1055 printf("bosserver: could not set up directories, code %d\n", i
);
1060 /* Support logging to named pipes by not renaming. */
1062 && (lstat(AFSDIR_SERVER_BOZLOG_FILEPATH
, &sb
) == 0)
1063 && !(S_ISFIFO(sb
.st_mode
))) {
1064 if (asprintf(&oldlog
, "%s.old", AFSDIR_SERVER_BOZLOG_FILEPATH
) < 0) {
1065 printf("bosserver: out of memory\n");
1068 rk_rename(AFSDIR_SERVER_BOZLOG_FILEPATH
, oldlog
);
1071 bozo_logFile
= fopen(AFSDIR_SERVER_BOZLOG_FILEPATH
, "a");
1072 if (!bozo_logFile
) {
1073 printf("bosserver: can't initialize log file (%s).\n",
1074 AFSDIR_SERVER_BOZLOG_FILEPATH
);
1077 /* keep log closed normally, so can be removed */
1078 fclose(bozo_logFile
);
1080 #ifndef AFS_NT40_ENV
1081 openlog("bosserver", LOG_PID
, DoSyslogFacility
);
1086 * go into the background and remove our controlling tty, close open
1090 #ifndef AFS_NT40_ENV
1093 printf("bosserver: warning - daemon() returned code %d\n", errno
);
1095 #endif /* ! AFS_NT40_ENV */
1097 /* Write current state of directory permissions to log file */
1100 /* chdir to AFS log directory */
1104 i
= chdir(AFSDIR_SERVER_LOGS_DIRPATH
);
1106 printf("bosserver: could not change to %s, code %d\n",
1107 DoCore
? DoCore
: AFSDIR_SERVER_LOGS_DIRPATH
, errno
);
1111 /* try to read the key from the config file */
1112 tdir
= afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH
);
1114 tdir
= CreateLocalCellConfig();
1116 /* opened the cell databse */
1117 bozo_confdir
= tdir
;
1119 code
= bnode_Init();
1121 printf("bosserver: could not init bnode package, code %d\n", code
);
1125 bnode_Register("fs", &fsbnode_ops
, 3);
1126 bnode_Register("dafs", &dafsbnode_ops
, 4);
1127 bnode_Register("simple", &ezbnode_ops
, 1);
1128 bnode_Register("cron", &cronbnode_ops
, 2);
1130 #if defined(RLIMIT_CORE) && defined(HAVE_GETRLIMIT)
1133 getrlimit(RLIMIT_CORE
, &rlp
);
1137 rlp
.rlim_max
= rlp
.rlim_cur
= RLIM_INFINITY
;
1138 setrlimit(RLIMIT_CORE
, &rlp
);
1139 getrlimit(RLIMIT_CORE
, &rlp
);
1140 bozo_Log("Core limits now %d %d\n",(int)rlp
.rlim_cur
,(int)rlp
.rlim_max
);
1144 /* Read init file, starting up programs. Also starts watcher threads. */
1145 if ((code
= ReadBozoFile(0))) {
1147 ("bosserver: Something is wrong (%d) with the bos configuration file %s; aborting\n",
1148 code
, AFSDIR_SERVER_BOZCONF_FILEPATH
);
1153 host
= GetRxBindAddress();
1155 for (i
= 0; i
< 10; i
++) {
1157 code
= rx_InitHost(host
, htons(AFSCONF_NANNYPORT
));
1159 code
= rx_Init(htons(AFSCONF_NANNYPORT
));
1162 bozo_Log("can't initialize rx: code=%d\n", code
);
1168 bozo_Log("Bos giving up, can't initialize rx\n");
1172 /* Set some rx config */
1174 rx_enablePeerRPCStats();
1175 if (DoProcessRPCStats
)
1176 rx_enableProcessRPCStats();
1178 /* Disable jumbograms */
1181 if (rxMaxMTU
!= -1) {
1182 if (rx_SetMaxMTU(rxMaxMTU
) != 0) {
1183 bozo_Log("bosserver: rxMaxMTU %d is invalid\n", rxMaxMTU
);
1188 code
= LWP_CreateProcess(BozoDaemon
, BOZO_LWP_STACKSIZE
, /* priority */ 1,
1189 /* param */ NULL
, "bozo-the-clown", &bozo_pid
);
1191 bozo_Log("Failed to create daemon thread\n");
1195 /* initialize audit user check */
1196 osi_audit_set_user_check(bozo_confdir
, bozo_IsLocalRealmMatch
);
1198 bozo_CreateRxBindFile(host
); /* for local scripts */
1200 /* allow super users to manage RX statistics */
1201 rx_SetRxStatUserOk(bozo_rxstat_userok
);
1203 afsconf_SetNoAuthFlag(tdir
, noAuth
);
1204 afsconf_BuildServerSecurityObjects(tdir
, &securityClasses
, &numClasses
);
1207 bozo_CreatePidFile("bosserver", NULL
, getpid());
1210 tservice
= rx_NewServiceHost(host
, 0, /* service id */ 1,
1211 "bozo", securityClasses
, numClasses
,
1212 BOZO_ExecuteRequest
);
1213 rx_SetMinProcs(tservice
, 2);
1214 rx_SetMaxProcs(tservice
, 4);
1215 rx_SetStackSize(tservice
, BOZO_LWP_STACKSIZE
); /* so gethostbyname works (in cell stuff) */
1216 if (rxkadDisableDotCheck
) {
1217 rx_SetSecurityConfiguration(tservice
, RXS_CONFIG_FLAGS
,
1218 (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK
);
1222 rx_NewServiceHost(host
, 0, RX_STATS_SERVICE_ID
, "rpcstats",
1223 securityClasses
, numClasses
, RXSTATS_ExecuteRequest
);
1224 rx_SetMinProcs(tservice
, 2);
1225 rx_SetMaxProcs(tservice
, 4);
1226 rx_StartServer(1); /* donate this process */
1231 bozo_Log(const char *format
, ...)
1237 va_start(ap
, format
);
1240 #ifndef AFS_NT40_ENV
1241 vsyslog(LOG_INFO
, format
, ap
);
1245 strcpy(tdate
, ctime(&myTime
)); /* copy out of static area asap */
1248 /* log normally closed, so can be removed */
1250 bozo_logFile
= fopen(AFSDIR_SERVER_BOZLOG_FILEPATH
, "a");
1251 if (bozo_logFile
== NULL
) {
1252 printf("bosserver: WARNING: problem with %s\n",
1253 AFSDIR_SERVER_BOZLOG_FILEPATH
);
1254 printf("%s ", tdate
);
1255 vprintf(format
, ap
);
1258 fprintf(bozo_logFile
, "%s ", tdate
);
1259 vfprintf(bozo_logFile
, format
, ap
);
1261 /* close so rm BosLog works */
1262 fclose(bozo_logFile
);