Deleted Added
full compact
1/*
2 * Copyright (c) 1997-1998 Erez Zadok
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

--- 4 unchanged lines hidden (view full) ---

33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * %W% (Berkeley) %G%
40 *
41 * $Id: hlfsd.c,v 1.2 1998/08/23 22:52:08 obrien Exp $
41 * $Id: hlfsd.c,v 1.3 1998/11/14 03:13:31 obrien Exp $
42 *
43 * HLFSD was written at Columbia University Computer Science Department, by
44 * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
45 * It is being distributed under the same terms and conditions as amd does.
46 */
47
48#ifdef HAVE_CONFIG_H
49# include <config.h>

--- 28 unchanged lines hidden (view full) ---

78/*
79 * GLOBALS:
80 */
81SVCXPRT *nfsxprt;
82char *alt_spooldir = ALT_SPOOLDIR;
83char *home_subdir = HOME_SUBDIR;
84char *logfile = DEFAULT_LOGFILE;
85char *passwdfile = NULL; /* alternate passwd file to use */
86#if 0
87char *progname;
88int foreground = 1; /* This is the top-level server */
89#endif
90char *slinkname = 0;
91char hostname[MAXHOSTNAMELEN + 1] = "localhost";
92int cache_interval = DEFAULT_CACHE_INTERVAL;
90int foreground = 1; /* This is the top-level server */
93gid_t hlfs_gid = (gid_t) INVALIDID;
94int masterpid = 0;
95int noverify = 0;
94int orig_umask;
96int orig_umask = 022;
97int serverpid = 0;
98nfstime startup;
99#if 0
100pid_t mypid; /* Current process id */
101#endif
102serv_state amd_state;
103u_short nfs_port;
104
105/* symbol must be available always */
106#ifdef MOUNT_TABLE_ON_FILE
107char *mnttab_file_name = MNTTAB_FILE_NAME;
108#else /* not MOUNT_TABLE_ON_FILE */
109char *mnttab_file_name = NULL;
110#endif /* not MOUNT_TABLE_ON_FILE */
111
112#if 0
113#ifdef DEBUG
114int debug_flags = 0;
115#endif /* DEBUG */
116#endif
117
118/* forward declarations */
119void hlfsd_going_down(int rc);
120
121
122static void
123usage(void)
124{
125 fprintf(stderr,
126 "Usage: %s [-Cfhnpv] [-a altdir] [-c cache-interval] [-g group]\n",
121 progname);
127 am_get_progname());
128 fprintf(stderr, "\t[-i interval] [-l logfile] [-o mntopts] [-P passwdfile]\n");
129 show_opts('x', xlog_opt);
130#ifdef DEBUG
131 show_opts('D', dbg_opt);
132#endif /* DEBUG */
133 fprintf(stderr, "\t[dir_name [subdir]]\n");
134 exit(2);
135}
136
137
138int
139main(int argc, char *argv[])
140{
141 char *dot;
142 char *mntopts = (char *) NULL;
143 char hostpid_fs[MAXHOSTNAMELEN + 1 + 16]; /* room for ":(pid###)" */
144 char progpid_fs[PROGNAMESZ + 1 + 11]; /* room for ":pid" */
145 char preopts[128];
146 char *progname;
147 int forcecache = 0;
148 int forcefast = 0;
149 int genflags = 0;
150 int opt, ret;
151 int opterrs = 0;
152 int retry;
153 int soNFS; /* NFS socket */
154 int s = -99;

--- 18 unchanged lines hidden (view full) ---

173 /* get program name and truncate so we don't overflow progpid_fs */
174
175 if ((progname = strrchr(argv[0], '/')) != NULL)
176 progname++;
177 else
178 progname = argv[0];
179 if ((int) strlen(progname) > PROGNAMESZ) /* truncate to reasonable size */
180 progname[PROGNAMESZ] = '\0';
181 am_set_progname(progname);
182
175 while ((opt = getopt(argc, argv, "a:c:CD:fg:hi:l:no:pP:x:v")) != EOF)
183 while ((opt = getopt(argc, argv, "a:c:CD:fg:hi:l:no:pP:x:v")) != -1)
184 switch (opt) {
185
186 case 'a':
187 if (!optarg || optarg[0] != '/') {
188 printf("%s: invalid directory for -a: %s\n",
181 progname, optarg);
189 am_get_progname(), optarg);
190 exit(3);
191 }
192 alt_spooldir = optarg;
193 break;
194
195 case 'c':
196 if (!atoi(optarg)) {
197 printf("%s: invalid interval for -c: %s\n",
190 progname, optarg);
198 am_get_progname(), optarg);
199 exit(3);
200 }
201 cache_interval = atoi(optarg);
202 break;
203
204 case 'C':
205 forcecache++;
206 break;

--- 4 unchanged lines hidden (view full) ---

211
212 case 'g':
213 hlfs_group = optarg;
214 break;
215
216 case 'i':
217 if (!atoi(optarg)) {
218 printf("%s: invalid interval for -i: %s\n",
211 progname, optarg);
219 am_get_progname(), optarg);
220 exit(3);
221 }
222 reloadinterval.it_interval.tv_sec = atoi(optarg);
223 reloadinterval.it_value.tv_sec = atoi(optarg);
224 break;
225
226 case 'l':
227 logfile = optarg;

--- 22 unchanged lines hidden (view full) ---

250 case 'x':
251 opterrs += switch_option(optarg);
252 break;
253
254 case 'D':
255#ifdef DEBUG
256 opterrs += debug_option(optarg);
257#else /* not DEBUG */
250 fprintf(stderr, "%s: not compiled with DEBUG -- sorry.\n", progname);
258 fprintf(stderr, "%s: not compiled with DEBUG -- sorry.\n", am_get_progname());
259#endif /* not DEBUG */
260 break;
261
262 case 'h':
263 case '?':
264 opterrs++;
265 }
266
267 /* set some default debugging options */
268 if (xlog_level_init == ~0)
269 switch_option("");
270 /* need my pid before any dlog/plog */
263 mypid = getpid();
271 am_set_mypid();
272#ifdef DEBUG
273 switch_option("debug");
274#endif /* DEBUG */
275
276/*
277 * Terminate if did not ask to forcecache (-C) and hlfsd would not be able
278 * to set the minimum cache intervals.
279 */
280#if !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_FIELD_NFS_ARGS_T_ACREGMIN)
281 if (!forcecache) {
274 fprintf(stderr, "%s: will not be able to turn off attribute caches.\n", progname);
282 fprintf(stderr, "%s: will not be able to turn off attribute caches.\n", am_get_progname());
283 exit(1);
284 }
285#endif /* !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_FIELD_NFS_ARGS_T_ACREGMIN) */
286
287
288 switch (argc - optind) {
289 case 2:
290 home_subdir = argv[optind + 1];

--- 14 unchanged lines hidden (view full) ---

305 exit(1);
306 }
307 setbuf(stdout, (char *) NULL);
308 umask(0);
309
310 /* find gid for hlfs_group */
311 if ((grp = getgrnam(hlfs_group)) == (struct group *) NULL) {
312 fprintf(stderr, "%s: cannot get gid for group \"%s\".\n",
305 progname, hlfs_group);
313 am_get_progname(), hlfs_group);
314 } else {
315 hlfs_gid = grp->gr_gid;
316 }
317
318 /* get hostname for logging and open log before we reset umask */
319 gethostname(hostname, sizeof(hostname));
320 hostname[sizeof(hostname) - 1] = '\0';
321 if ((dot = strchr(hostname, '.')) != NULL)
322 *dot = '\0';
315 if (logfile)
316 switch_to_logfile(logfile);
323 orig_umask = umask(0);
324 if (logfile)
325 switch_to_logfile(logfile, orig_umask);
326
327#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE)
328 if (debug_flags & D_MTAB)
329 dlog("-D mtab option ignored");
330#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */
331
332 /* avoid hanging on other NFS servers if started elsewhere */
333 if (chdir("/") < 0)

--- 8 unchanged lines hidden (view full) ---

342 */
343
344 if (dir_name[0] != '/'
345 || ((slinkname = strrchr(dir_name, '/')), *slinkname++ = '\0',
346 (dir_name[0] == '\0' || slinkname[0] == '\0'))) {
347 if (slinkname)
348 *--slinkname = '/';
349 printf("%s: invalid mount directory/link %s\n",
342 progname, dir_name);
350 am_get_progname(), dir_name);
351 exit(3);
352 }
353
354 clock_valid = 0; /* invalidate logging clock */
355
356 if (!forcefast) {
357 /* make sure mount point exists and is at least mode 555 */
358 if (stat(dir_name, &stmodes) < 0)
359 if (errno != ENOENT || mkdirs(dir_name, 0555) < 0
360 || stat(dir_name, &stmodes) < 0)
361 fatalerror(dir_name);
362
363 if ((stmodes.st_mode & 0555) != 0555) {
364 fprintf(stderr, "%s: directory %s not read/executable\n",
357 progname, dir_name);
365 am_get_progname(), dir_name);
366 plog(XLOG_WARNING, "directory %s not read/executable",
367 dir_name);
368 }
369
370 /* warn if extraneous stuff will be hidden by mount */
371 if ((mountdir = opendir(dir_name)) == NULL)
372 fatalerror(dir_name);
373
374 while ((direntry = readdir(mountdir)) != NULL) {
375 if (!NSTREQ(".", direntry->d_name, NAMLEN(direntry)) &&
376 !NSTREQ("..", direntry->d_name, NAMLEN(direntry)) &&
377 !NSTREQ(slinkname, direntry->d_name, NAMLEN(direntry)))
378 break;
379 }
380
381 if (direntry != NULL) {
382 fprintf(stderr, "%s: %s/%s will be hidden by mount\n",
375 progname, dir_name, direntry->d_name);
383 am_get_progname(), dir_name, direntry->d_name);
384 plog(XLOG_WARNING, "%s/%s will be hidden by mount\n",
385 dir_name, direntry->d_name);
386 }
387 closedir(mountdir);
388
389 /* make sure alternate spool dir exists */
390 if ((errno = mkdirs(alt_spooldir, OPEN_SPOOLMODE))) {
391 fprintf(stderr, "%s: cannot create alternate dir ",
384 progname);
392 am_get_progname());
393 perror(alt_spooldir);
394 plog(XLOG_ERROR, "cannot create alternate dir %s: %m",
395 alt_spooldir);
396 }
397 chmod(alt_spooldir, OPEN_SPOOLMODE);
398
399 /* create failsafe link to alternate spool directory */
400 slinkname[-1] = '/'; /* unsplit dir_name to include link */
401 if (lstat(dir_name, &stmodes) == 0 &&
402 (stmodes.st_mode & S_IFMT) != S_IFLNK) {
403 fprintf(stderr, "%s: failsafe %s not a symlink\n",
396 progname, dir_name);
404 am_get_progname(), dir_name);
405 plog(XLOG_WARNING, "failsafe %s not a symlink\n",
406 dir_name);
407 } else {
408 unlink(dir_name);
409
410 if (symlink(alt_spooldir, dir_name) < 0) {
411 fprintf(stderr,
412 "%s: cannot create failsafe symlink %s -> ",
405 progname, dir_name);
413 am_get_progname(), dir_name);
414 perror(alt_spooldir);
415 plog(XLOG_WARNING,
416 "cannot create failsafe symlink %s -> %s: %m",
417 dir_name, alt_spooldir);
418 }
419 }
420
421 slinkname[-1] = '\0'; /* resplit dir_name */

--- 98 unchanged lines hidden (view full) ---

520 localsocket.sin_family = AF_INET;
521 localsocket.sin_port = htons(nfsxprt->xp_port);
522#endif /* not HAVE_TRANSPORT_TYPE_TLI */
523
524 /*
525 * Update hostname field.
526 * Make some name prog:pid (i.e., hlfsd:174) for hostname
527 */
520 sprintf(progpid_fs, "%s:%d", progname, masterpid);
528 sprintf(progpid_fs, "%s:%d", am_get_progname(), masterpid);
529
530 /* Most kernels have a name length restriction. */
531 if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
532 strcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..");
533
534 genflags = compute_mount_flags(&mnt);
535
536 retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);

--- 59 unchanged lines hidden (view full) ---

596 * -Erez Zadok.
597 */
598 if (debug_flags & D_DAEMON) { /* asked for -D daemon */
599 plog(XLOG_INFO, "parent NFS mounting hlfsd service points");
600 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0)
601 fatal("nfsmount: %m");
602 } else { /* asked for -D nodaemon */
603 if (fork() == 0) { /* child runs mount */
596 mypid = getpid();
604 am_set_mypid();
605 foreground = 0;
606 plog(XLOG_INFO, "child NFS mounting hlfsd service points");
607 if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) {
608 fatal("nfsmount: %m");
609 }
610 exit(0); /* all went well */
611 } else { /* fork failed or parent running */
612 plog(XLOG_INFO, "parent waiting 1sec for mount...");

--- 60 unchanged lines hidden (view full) ---

673#endif /* DEBUG */
674 child = fork();
675
676 if (child < 0)
677 fatal("fork: %m");
678
679 if (child != 0) { /* parent process - save child pid */
680 masterpid = child;
673 mypid = getpid(); /* for logging routines */
681 am_set_mypid(); /* for logging routines */
682 return;
683 }
684
685 /*
686 * CHILD CODE:
687 * initialize server
688 */
689
690 plog(XLOG_INFO, "initializing home directory database");
691 plt_init(); /* initialize database */
692 plog(XLOG_INFO, "home directory database initialized");
693
686 masterpid = serverpid = mypid = getpid(); /* for logging routines */
694 masterpid = serverpid = am_set_mypid(); /* for logging routines */
695
696 /*
697 * SIGALRM/SIGHUP: reload password database if timer expired
698 * or user sent HUP signal.
699 */
700#ifdef HAVE_SIGACTION
701 sa.sa_handler = reload;
702 sa.sa_flags = 0;

--- 16 unchanged lines hidden (view full) ---

719 sigemptyset(&(sa.sa_mask));
720 sigaddset(&(sa.sa_mask), SIGTERM);
721 sigaction(SIGTERM, &sa, NULL);
722#else /* not HAVE_SIGACTION */
723 signal(SIGTERM, cleanup);
724#endif /* not HAVE_SIGACTION */
725
726 /*
719 * SIGCHLD: interlock sycronization and testing
727 * SIGCHLD: interlock synchronization and testing
728 */
729#ifdef HAVE_SIGACTION
730 sa.sa_handler = interlock;
731 sa.sa_flags = 0;
732 sigemptyset(&(sa.sa_mask));
733 sigaddset(&(sa.sa_mask), SIGCHLD);
734 sigaction(SIGCHLD, &sa, NULL);
735#else /* not HAVE_SIGACTION */

--- 74 unchanged lines hidden (view full) ---

810 if (getpid() != masterpid)
811 return;
812
813 /*
814 * If received a SIGHUP, close and reopen the log file (so that it
815 * can be rotated)
816 */
817 if (signum == SIGHUP && logfile)
810 switch_to_logfile(logfile);
818 switch_to_logfile(logfile, orig_umask);
819
820 /*
821 * parent performs the reload, while the child continues to serve
822 * clients accessing the home dir link.
823 */
824 if ((child = fork()) > 0) {
825 serverpid = child; /* parent runs here */
818 mypid = getpid();
826 am_set_mypid();
827
828 plt_init();
829
830 if (kill(child, SIGKILL) < 0) {
831 plog(XLOG_ERROR, "kill child: %m");
832 } else { /* wait for child to die before continue */
833 if (wait(&status) != child) {
834 /*

--- 7 unchanged lines hidden (view full) ---

842 }
843 }
844 serverpid = masterpid;
845 } else if (child < 0) {
846 plog(XLOG_ERROR, "unable to fork: %m");
847 } else {
848 /* let child handle requests while we reload */
849 serverpid = getpid();
842 mypid = getpid();
850 am_set_mypid();
851 }
852}
853
854
855RETSIGTYPE
856cleanup(int signum)
857{
858 struct stat stbuf;

--- 7 unchanged lines hidden (view full) ---

866 if (getpid() != masterpid)
867 return;
868
869#ifdef DEBUG
870 amuDebug(D_DAEMON)
871#endif /* DEBUG */
872 if (fork() != 0) {
873 masterpid = 0;
866 mypid = getpid();
874 am_set_mypid();
875 return;
876 }
869 mypid = getpid();
877 am_set_mypid();
878
879 for (;;) {
880 while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name)) == EBUSY) {
881#ifdef DEBUG
882 dlog("cleanup(): umount delaying for 10 seconds");
883#endif /* DEBUG */
884 sleep(10);
885 }
886 if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) {
887 plog(XLOG_ERROR, "unable to unmount %s", dir_name);
888 plog(XLOG_ERROR, "suspending, unmount before terminating");
881 kill(mypid, SIGSTOP);
889 kill(am_mypid, SIGSTOP);
890 continue; /* retry unmount */
891 }
892 break;
893 }
894
895#ifdef DEBUG
896 dlog("cleanup(): killing processes and terminating");
897 amuDebug(D_DAEMON)

--- 19 unchanged lines hidden (view full) ---

917 exit(4);
918 }
919}
920
921
922void
923hlfsd_going_down(int rc)
924{
917 int mypid = getpid();
925 int mypid = getpid(); /* XXX: should this be the global am_mypid */
926
927 if (mypid == masterpid)
928 cleanup(0);
929 else if (mypid == serverpid)
930 kill(masterpid, SIGTERM);
931
932 exit(rc);
933}

--- 4 unchanged lines hidden (view full) ---

938{
939 if (logfile && !STREQ(logfile, "stderr")) {
940 char lessmess[128];
941 int messlen;
942
943 messlen = strlen(mess);
944
945 if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
938 fprintf(stderr, "%s: %s\n", progname, mess);
946 fprintf(stderr, "%s: %s\n", am_get_progname(), mess);
947 else {
948 strcpy(lessmess, mess);
949 lessmess[messlen - 4] = '\0';
950
951 if (errno < sys_nerr)
944 fprintf(stderr, "%s: %s: %s\n", progname,
952 fprintf(stderr, "%s: %s: %s\n", am_get_progname(),
953 lessmess, sys_errlist[errno]);
954 else
955 fprintf(stderr, "%s: %s: Error %d\n",
948 progname, lessmess, errno);
956 am_get_progname(), lessmess, errno);
957 }
958 }
959 plog(XLOG_FATAL, mess);
960
961 hlfsd_going_down(1);
962}