int main(int argc, char *argv[]) { make_fs("test"); mount_fs("test"); fs_create("myfile.txt"); fs_list_files(); fs_create("junk.txt"); fs_list_files(); int fd = fs_open("myfile.txt"); char *buf = "testing this code"; fs_write(fd,buf,strlen(buf)); //fs_lseek(fd,100); buf = "it! Blahc lksjdfkj ihwtw lekjth lksajdf 123413459827 i sadfkjhq3oipu4tryheiq8u934yt5981 3yq4t97ughergo9vyq398 4y5t 98qgrebgfvkje"; fs_write(fd,buf,strlen(buf)+1); //fs_truncate(fd,2); //fs_write(fd,"",1); fs_close(fd); fd = fs_open("myfile.txt"); char word[1000]; fs_read(fd,word,10000); fs_close(fd); printf("\"%s\" was read from myfile.txt\n",word); printf("size of myfile.txt - %d\n", fs_get_filesize("myfile.txt")); unmount_fs("test"); mount_fs("test"); fs_list_files(); printf("size of myfile.txt - %d\n", fs_get_filesize("myfile.txt")); printf("size of junk.txt - %d\n", fs_get_filesize("junk.txt")); fd = fs_open("myfile.txt"); fs_read(fd,word,10000); fs_close(fd); printf("\"%s\" was read from myfile.txt\n",word); fs_delete("myfile.txt"); fs_list_files(); unmount_fs("test"); return 0; }
static int mount_ufs(char *dir, char *fs_name, char *opts) { struct ufs_args ufs_args; struct mntent mnt; int flags; /* * Figure out the name of the file system type. */ const char *type = MOUNT_FFS; bzero(&ufs_args, sizeof(ufs_args)); /* Paranoid */ /* * Fill in the mount structure */ mnt.mnt_dir = dir; mnt.mnt_fsname = fs_name; mnt.mnt_type = "ffs"; mnt.mnt_opts = opts; mnt.mnt_freq = 1; mnt.mnt_passno = 2; flags = compute_mount_flags(&mnt); ufs_args.fspec = fs_name; /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t) &ufs_args, 0, type); }
int mount_lofs(char *mntdir, char *fs_name, char *opts, int on_autofs) { mntent_t mnt; int flags; /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_LOFS; /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_LOFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) flags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ /* * Call generic mount routine */ return mount_fs(&mnt, flags, NULL, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
/*===========================================================================* * do_init_root * *===========================================================================*/ static void *do_init_root(void *arg) { struct fproc *rfp; struct job my_job; int r; char *mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */ my_job = *((struct job *) arg); fp = my_job.j_fp; lock_proc(fp, 1 /* force lock */); /* This proc is busy */ lock_pm(); /* Initialize process directories. mount_fs will set them to the correct * values */ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { FD_ZERO(&(rfp->fp_filp_inuse)); rfp->fp_rd = NULL; rfp->fp_wd = NULL; } receive_from = MFS_PROC_NR; if ((r = mount_fs(DEV_IMGRD, "/", MFS_PROC_NR, 0, mount_label)) != OK) panic("Failed to initialize root"); receive_from = ANY; unlock_pm(); thread_cleanup(fp); return(NULL); }
/*===========================================================================* * do_mount * *===========================================================================*/ PUBLIC int do_mount() { /* Perform the mount(name, mfile, mount_flags) system call. */ endpoint_t fs_e; int r, slot, rdonly, nodev; char fullpath[PATH_MAX]; char mount_label[LABEL_MAX]; dev_t dev; /* Only the super-user may do MOUNT. */ if (!super_user) return(EPERM); /* FS process' endpoint number */ if (m_in.mount_flags & MS_LABEL16) { /* Get the label from the caller, and ask DS for the endpoint. */ r = sys_datacopy(who_e, (vir_bytes) m_in.fs_label, SELF, (vir_bytes) mount_label, (phys_bytes) sizeof(mount_label)); if (r != OK) return(r); mount_label[sizeof(mount_label)-1] = 0; r = ds_retrieve_label_endpt(mount_label, &fs_e); if (r != OK) return(r); } else { /* Legacy support: get the endpoint from the request itself. */ fs_e = (endpoint_t) m_in.fs_label; mount_label[0] = 0; } /* Sanity check on process number. */ if (isokendpt(fs_e, &slot) != OK) return(EINVAL); /* Should the file system be mounted read-only? */ rdonly = (m_in.mount_flags & MS_RDONLY); /* A null string for block special device means don't use a device at all. */ nodev = (m_in.name1_length == 0); if (!nodev) { /* If 'name' is not for a block special file, return error. */ if (fetch_name(m_in.name1, m_in.name1_length, M1, fullpath) != OK) return(err_code); if ((dev = name_to_dev(FALSE /*allow_mountpt*/, fullpath)) == NO_DEV) return(err_code); } else { /* Find a free pseudo-device as substitute for an actual device. */ if ((dev = find_free_nonedev()) == NO_DEV) return(err_code); } /* Fetch the name of the mountpoint */ if (fetch_name(m_in.name2, m_in.name2_length, M1, fullpath) != OK) return(err_code); /* Do the actual job */ return mount_fs(dev, fullpath, fs_e, rdonly, mount_label); }
extern int lxc_setup_fs(void) { if (mount_fs("proc", "/proc", "proc")) return -1; if (mount_fs("shmfs", "/dev/shm", "tmpfs")) return -1; /* If we were able to mount /dev/shm, then /dev exists */ if (access("/dev/mqueue", F_OK) && mkdir("/dev/mqueue", 0666)) { SYSERROR("failed to create '/dev/mqueue'"); return -1; } if (mount_fs("mqueue", "/dev/mqueue", "mqueue")) return -1; return 0; }
extern int lxc_setup_fs(void) { if (mount_fs("proc", "/proc", "proc")) return -1; if (mount_fs("shmfs", "/dev/shm", "tmpfs")) return -1; /* If we were able to mount /dev/shm, then /dev exists */ /* Sure, but it's read-only per config :) */ if (access("/dev/mqueue", F_OK) && mkdir("/dev/mqueue", 0666)) { DEBUG("failed to create '/dev/mqueue'"); return 0; } if (mount_fs("mqueue", "/dev/mqueue", "mqueue")) return -1; return 0; }
extern void lxc_setup_fs(void) { if (mount_fs("proc", "/proc", "proc")) INFO("failed to remount proc"); /* if we can't mount /dev/shm, continue anyway */ if (mount_fs("shmfs", "/dev/shm", "tmpfs")) INFO("failed to mount /dev/shm"); /* If we were able to mount /dev/shm, then /dev exists */ /* Sure, but it's read-only per config :) */ if (access("/dev/mqueue", F_OK) && mkdir("/dev/mqueue", 0666)) { DEBUG("failed to create '/dev/mqueue'"); return; } /* continue even without posix message queue support */ if (mount_fs("mqueue", "/dev/mqueue", "mqueue")) INFO("failed to mount /dev/mqueue"); }
static int mount_efs(char *mntdir, char *fs_name, char *opts, int on_autofs) { efs_args_t efs_args; mntent_t mnt; int flags; /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_EFS; memset((voidp) &efs_args, 0, sizeof(efs_args)); /* Paranoid */ /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_EFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) flags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ #ifdef HAVE_EFS_ARGS_T_FLAGS efs_args.flags = 0; /* XXX: fix this to correct flags */ #endif /* HAVE_EFS_ARGS_T_FLAGS */ #ifdef HAVE_EFS_ARGS_T_FSPEC efs_args.fspec = fs_name; #endif /* HAVE_EFS_ARGS_T_FSPEC */ #if defined(HAVE_EFS_ARGS_T_VERSION) && defined(EFS_MNT_VERSION) efs_args.version = EFS_MNT_VERSION; #endif /* HAVE_EFS_ARGS_T_VERSION && EFS_MNT_VERSION */ /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t) &efs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
static int lustre_mount(am_node *am, mntfs *mf) { mntent_t mnt; int genflags, error; int on_autofs = mf->mf_flags & MFF_ON_AUTOFS; /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_LUSTRE; /* * Fill in the mount structure */ memset(&mnt, 0, sizeof(mnt)); mnt.mnt_dir = mf->mf_mount; mnt.mnt_fsname = mf->mf_info; mnt.mnt_type = MNTTAB_TYPE_LUSTRE; mnt.mnt_opts = mf->mf_mopts; genflags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) genflags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ /* * Call generic mount routine */ error = mount_fs(&mnt, genflags, NULL, 0, type, 0, NULL, mnttab_file_name, on_autofs); if (error) { errno = error; plog(XLOG_ERROR, "mount_lustre: %m"); return error; } return 0; }
/*===========================================================================* * do_init_root * *===========================================================================*/ static void do_init_root(void) { char *mount_type, *mount_label; int r; /* Disallow requests from e.g. init(8) while doing the initial mounting. */ worker_allow(FALSE); /* Mount the pipe file server. */ mount_pfs(); /* Mount the root file system. */ mount_type = "mfs"; /* FIXME: use boot image process name instead */ mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */ r = mount_fs(DEV_IMGRD, "bootramdisk", "/", MFS_PROC_NR, 0, mount_type, mount_label); if (r != OK) panic("Failed to initialize root"); /* All done with mounting, allow requests now. */ worker_allow(TRUE); }
static int mount_tmpfs(char *mntdir, char *fs_name, char *opts, int on_autofs) { tmpfs_args_t tmpfs_args; mntent_t mnt; int flags; const char *p; /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_TMPFS; p = NULL; memset((voidp) &tmpfs_args, 0, sizeof(tmpfs_args)); /* Paranoid */ /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_TMPFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) flags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ #if defined(HAVE_TMPFS_ARGS_T_TA_VERSION) && defined(TMPFS_ARGS_VERSION) tmpfs_args.ta_version = TMPFS_ARGS_VERSION; #endif /* HAVE_TMPFS_ARGS_T_TA_VERSION && TMPFS_ARGS_VERSION */ #ifdef HAVE_TMPFS_ARGS_T_TA_NODES_MAX if ((p = amu_hasmntopt(&mnt, "nodes")) == NULL) p = "1000000"; tmpfs_args.ta_nodes_max = atoi(p); #endif /* HAVE_TMPFS_ARGS_T_TA_SIZE_MAX */ #ifdef HAVE_TMPFS_ARGS_T_TA_SIZE_MAX if ((p = amu_hasmntopt(&mnt, "size")) == NULL) p = "10000000"; tmpfs_args.ta_size_max = atoi(p); #endif /* HAVE_TMPFS_ARGS_T_TA_SIZE_MAX */ #ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_UID if ((p = amu_hasmntopt(&mnt, "uid")) == NULL) p = "0"; tmpfs_args.ta_root_uid = atoi(p); #endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_UID */ #ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_GID if ((p = amu_hasmntopt(&mnt, "gid")) == NULL) p = "0"; tmpfs_args.ta_root_gid = atoi(p); #endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_GID */ #ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_MODE if ((p = amu_hasmntopt(&mnt, "mode")) == NULL) p = "01777"; tmpfs_args.ta_root_mode = strtol(p, NULL, 8); #endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_MODE */ /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t) &tmpfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
/* * mntpt is the mount point ($fs) [XXX: was 'dir'] * backdir is the mounted pathname ($rfs) [XXX: was 'fs_name'] * cachedir is the cache directory ($cachedir) */ static int mount_cachefs(char *mntdir, char *backdir, char *cachedir, char *opts, int on_autofs) { cachefs_args_t ca; mntent_t mnt; int flags; char *cp; MTYPE_TYPE type = MOUNT_TYPE_CACHEFS; /* F/S mount type */ memset((voidp) &ca, 0, sizeof(ca)); /* Paranoid */ /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = backdir; mnt.mnt_type = MNTTAB_TYPE_CACHEFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) flags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ /* Fill in cachefs mount arguments */ /* * XXX: Caveats * (1) cache directory is NOT checked for sanity beforehand, nor is it * purged. Maybe it should be purged first? * (2) cache directory is NOT locked. Should we? */ /* mount flags */ ca.cfs_options.opt_flags = CFS_WRITE_AROUND | CFS_ACCESS_BACKFS; /* cache population size */ ca.cfs_options.opt_popsize = DEF_POP_SIZE; /* default: 64K */ /* filegrp size */ ca.cfs_options.opt_fgsize = DEF_FILEGRP_SIZE; /* default: 256 */ /* CFS ID for file system (must be unique) */ ca.cfs_fsid = cachedir; /* CFS fscdir name */ memset(ca.cfs_cacheid, 0, sizeof(ca.cfs_cacheid)); /* * Append cacheid and mountpoint. * sizeof(cfs_cacheid) should be C_MAX_MOUNT_FSCDIRNAME as per * <sys/fs/cachefs_fs.h> (checked on Solaris 8). */ xsnprintf(ca.cfs_cacheid, sizeof(ca.cfs_cacheid), "%s:%s", ca.cfs_fsid, mntdir); /* convert '/' to '_' (Solaris does that...) */ cp = ca.cfs_cacheid; while ((cp = strpbrk(cp, "/")) != NULL) *cp = '_'; /* path for this cache dir */ ca.cfs_cachedir = cachedir; /* back filesystem dir */ ca.cfs_backfs = backdir; /* same as nfs values (XXX: need to handle these options) */ ca.cfs_acregmin = 0; ca.cfs_acregmax = 0; ca.cfs_acdirmin = 0; ca.cfs_acdirmax = 0; /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t) &ca, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
int mountfs(const char *vfstype, const char *spec, const char *name, int flags, const char *options, const char *mntopts) { struct statfs sf; int i, ret; char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX]; static struct cpa mnt_argv; /* resolve the mountpoint with realpath(3) */ if (checkpath(name, mntpath) != 0) { warn("%s", mntpath); return (1); } name = mntpath; if (mntopts == NULL) mntopts = ""; optbuf = catopt(strdup(mntopts), options); if (strcmp(name, "/") == 0) flags |= MNT_UPDATE; if (flags & MNT_FORCE) optbuf = catopt(optbuf, "force"); if (flags & MNT_RDONLY) optbuf = catopt(optbuf, "ro"); /* * XXX * The mount_mfs (newfs) command uses -o to select the * optimization mode. We don't pass the default "-o rw" * for that reason. */ if (flags & MNT_UPDATE) optbuf = catopt(optbuf, "update"); /* Compatibility glue. */ if (strcmp(vfstype, "msdos") == 0) { warnx( "Using \"-t msdosfs\", since \"-t msdos\" is deprecated."); vfstype = "msdosfs"; } /* Construct the name of the appropriate mount command */ (void)snprintf(execname, sizeof(execname), "mount_%s", vfstype); mnt_argv.c = -1; append_arg(&mnt_argv, execname); mangle(optbuf, &mnt_argv); if (mountprog != NULL) strcpy(execname, mountprog); append_arg(&mnt_argv, strdup(spec)); append_arg(&mnt_argv, strdup(name)); append_arg(&mnt_argv, NULL); if (debug) { if (use_mountprog(vfstype)) printf("exec: %s", execname); else printf("mount -t %s", vfstype); for (i = 1; i < mnt_argv.c; i++) (void)printf(" %s", mnt_argv.a[i]); (void)printf("\n"); free(optbuf); free(mountprog); mountprog = NULL; return (0); } if (use_mountprog(vfstype)) { ret = exec_mountprog(name, execname, mnt_argv.a); } else { ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a); } free(optbuf); free(mountprog); mountprog = NULL; if (verbose) { if (statfs(name, &sf) < 0) { warn("statfs %s", name); return (1); } if (fstab_style) putfsent(&sf); else prmount(&sf); } return (ret); }
static int mount_udf(char *mntdir, char *fs_name, char *opts, int on_autofs) { udf_args_t udf_args; mntent_t mnt; int flags; char *str; #if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) uid_t uid_nobody; gid_t gid_nobody; #endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */ /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_UDF; #if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) uid_nobody = a_uid("nobody", "user"); if (uid_nobody == 0) { plog(XLOG_ERROR, "mount_udf: invalid uid for nobody"); return EPERM; } #endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */ #if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) gid_nobody = a_gid("nobody", "group"); if (gid_nobody == 0) { plog(XLOG_ERROR, "mount_udf: invalid gid for nobody"); return EPERM; } #endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) */ str = NULL; memset((voidp) &udf_args, 0, sizeof(udf_args)); /* Paranoid */ /* * Fill in the mount structure */ memset((voidp)&mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_UDF; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_UDF_ARGS_T_UDFMFLAGS # if defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) if (amu_hasmntopt(&mnt, MNTTAB_OPT_CLOSESESSION)) udf_args.udfmflags |= MNT2_UDF_OPT_CLOSESESSION; # endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) */ #endif /* HAVE_UDF_ARGS_T_UDFMFLAGS */ #ifdef HAVE_UDF_ARGS_T_NOBODY_UID udf_args.nobody_uid = uid_nobody; #endif /* HAVE_UDF_ARGS_T_NOBODY_UID */ #ifdef HAVE_UDF_ARGS_T_NOBODY_GID udf_args.nobody_gid = gid_nobody; #endif /* HAVE_UDF_ARGS_T_NOBODY_GID */ #ifdef HAVE_UDF_ARGS_T_ANON_UID udf_args.anon_uid = uid_nobody; /* default to nobody */ if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { udf_args.anon_uid = a_uid(str, MNTTAB_OPT_USER); XFREE(str); } #endif /* HAVE_UDF_ARGS_T_ANON_UID */ #ifdef HAVE_UDF_ARGS_T_ANON_GID udf_args.anon_gid = gid_nobody; /* default to nobody */ if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { udf_args.anon_gid = a_gid(str, MNTTAB_OPT_GROUP); XFREE(str); } #endif /* HAVE_UDF_ARGS_T_ANON_GID */ #ifdef HAVE_UDF_ARGS_T_GMTOFF udf_args.gmtoff = 0; if ((str = hasmntstr(&mnt, MNTTAB_OPT_GMTOFF)) != NULL) { udf_args.gmtoff = a_num(str, MNTTAB_OPT_GMTOFF); XFREE(str); } #endif /* HAVE_UDF_ARGS_T_GMTOFF */ #ifdef HAVE_UDF_ARGS_T_SESSIONNR udf_args.sessionnr = 0; if ((str = hasmntstr(&mnt, MNTTAB_OPT_SESSIONNR)) != NULL) { udf_args.sessionnr = a_num(str, MNTTAB_OPT_SESSIONNR); XFREE(str); } #endif /* HAVE_UDF_ARGS_T_SESSIONNR */ #ifdef HAVE_UDF_ARGS_T_VERSION # ifdef UDFMNT_VERSION udf_args.version = UDFMNT_VERSION; # endif /* UDFMNT_VERSION */ #endif /* HAVE_UDF_ARGS_T_VERSION */ #ifdef HAVE_UFS_ARGS_T_FSPEC udf_args.fspec = fs_name; #endif /* HAVE_UFS_ARGS_T_FSPEC */ /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t)&udf_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
static int mount_cdfs(char *mntdir, char *fs_name, char *opts, int on_autofs) { cdfs_args_t cdfs_args; mntent_t mnt; int genflags, cdfs_flags, retval; /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_CDFS; memset((voidp) &cdfs_args, 0, sizeof(cdfs_args)); /* Paranoid */ cdfs_flags = 0; /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_CDFS; mnt.mnt_opts = opts; #if defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM) if (amu_hasmntopt(&mnt, MNTTAB_OPT_DEFPERM)) # ifdef MNT2_CDFS_OPT_DEFPERM cdfs_flags |= MNT2_CDFS_OPT_DEFPERM; # else /* not MNT2_CDFS_OPT_DEFPERM */ cdfs_flags &= ~MNT2_CDFS_OPT_NODEFPERM; # endif /* not MNT2_CDFS_OPT_DEFPERM */ #endif /* defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM) */ #if defined(MNT2_CDFS_OPT_NODEFPERM) && defined(MNTTAB_OPT_NODEFPERM) if (amu_hasmntopt(&mnt, MNTTAB_OPT_NODEFPERM)) cdfs_flags |= MNT2_CDFS_OPT_NODEFPERM; #endif /* MNTTAB_OPT_NODEFPERM */ #if defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION) if (amu_hasmntopt(&mnt, MNTTAB_OPT_NOVERSION)) cdfs_flags |= MNT2_CDFS_OPT_NOVERSION; #endif /* defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION) */ #if defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP) if (amu_hasmntopt(&mnt, MNTTAB_OPT_RRIP)) cdfs_flags |= MNT2_CDFS_OPT_RRIP; #endif /* defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP) */ #if defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP) if (amu_hasmntopt(&mnt, MNTTAB_OPT_NORRIP)) cdfs_flags |= MNT2_CDFS_OPT_NORRIP; #endif /* defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP) */ #if defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS) if (amu_hasmntopt(&mnt, MNTTAB_OPT_GENS)) cdfs_flags |= MNT2_CDFS_OPT_GENS; #endif /* defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS) */ #if defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT) if (amu_hasmntopt(&mnt, MNTTAB_OPT_EXTATT)) cdfs_flags |= MNT2_CDFS_OPT_EXTATT; #endif /* defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT) */ genflags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) genflags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ #ifdef HAVE_CDFS_ARGS_T_FLAGS cdfs_args.flags = cdfs_flags; #endif /* HAVE_CDFS_ARGS_T_FLAGS */ #ifdef HAVE_CDFS_ARGS_T_ISO_FLAGS cdfs_args.iso_flags = genflags | cdfs_flags; #endif /* HAVE_CDFS_ARGS_T_ISO_FLAGS */ #ifdef HAVE_CDFS_ARGS_T_ISO_PGTHRESH cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH); #endif /* HAVE_CDFS_ARGS_T_ISO_PGTHRESH */ #ifdef HAVE_CDFS_ARGS_T_NORRIP /* XXX: need to provide norrip mount opt */ cdfs_args.norrip = 0; /* use Rock-Ridge Protocol extensions */ #endif /* HAVE_CDFS_ARGS_T_NORRIP */ #ifdef HAVE_CDFS_ARGS_T_SSECTOR /* XXX: need to provide ssector mount option */ cdfs_args.ssector = 0; /* use 1st session on disk */ #endif /* HAVE_CDFS_ARGS_T_SSECTOR */ #ifdef HAVE_CDFS_ARGS_T_FSPEC cdfs_args.fspec = fs_name; #endif /* HAVE_CDFS_ARGS_T_FSPEC */ /* * Call generic mount routine */ retval = mount_fs(&mnt, genflags, (caddr_t) &cdfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); return retval; }
bool default_mount_fs(fs_context** fs) { return mount_fs(default_io_ctx, fs); }
int autofs_link_mount(am_node *mp) { int err = -1; #ifdef MNT2_GEN_OPT_BIND if (bind_works) { mntent_t mnt; struct stat buf; /* * we need to stat() the destination, because the bind mount does not * follow symlinks and/or allow for non-existent destinations. * we fall back to symlinks if there are problems. * * we need to temporarily change pgrp, otherwise our stat() won't * trigger whatever cascading mounts are needed. * * WARNING: we will deadlock if this function is called from the master * amd process and it happens to trigger another auto mount. Therefore, * this function should be called only from a child amd process, or * at the very least it should not be called from the parent unless we * know for sure that it won't cause a recursive mount. We refuse to * cause the recursive mount anyway if called from the parent amd. */ if (!foreground) { pid_t pgrp = getpgrp(); setpgrp(); err = stat(mp->am_link, &buf); if (setpgid(0, pgrp)) { plog(XLOG_ERROR, "autofs: cannot restore pgrp: %s", strerror(errno)); plog(XLOG_ERROR, "autofs: aborting the mount"); return errno; } if (err) goto use_symlink; } if ((err = lstat(mp->am_link, &buf))) goto use_symlink; if (S_ISLNK(buf.st_mode)) goto use_symlink; plog(XLOG_INFO, "autofs: bind-mounting %s -> %s", mp->am_path, mp->am_link); memset(&mnt, 0, sizeof(mnt)); mnt.mnt_dir = mp->am_path; mnt.mnt_fsname = mp->am_link; mnt.mnt_type = "bind"; mnt.mnt_opts = ""; mkdirs(mp->am_path, 0555); err = mount_fs(&mnt, MNT2_GEN_OPT_BIND, NULL, 0, "bind", 0, NULL, mnttab_file_name); if (err) rmdir(mp->am_path); } use_symlink: #endif /* MNT2_GEN_OPT_BIND */ if (err) { plog(XLOG_INFO, "autofs: symlinking %s -> %s", mp->am_path, mp->am_link); err = symlink(mp->am_link, mp->am_path); } if (err) return errno; return 0; }
static int mount_pcfs(char *mntdir, char *fs_name, char *opts, int on_autofs) { pcfs_args_t pcfs_args; mntent_t mnt; int flags; #if defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) int mask; #endif /* defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) */ #if defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) char *str; #endif /* defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) */ /* * Figure out the name of the file system type. */ MTYPE_TYPE type = MOUNT_TYPE_PCFS; memset((voidp) &pcfs_args, 0, sizeof(pcfs_args)); /* Paranoid */ /* * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_PCFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) flags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "mount_pcfs: flags=0x%x", (u_int) flags); #ifdef HAVE_PCFS_ARGS_T_FSPEC pcfs_args.fspec = fs_name; #endif /* HAVE_PCFS_ARGS_T_FSPEC */ #ifdef HAVE_PCFS_ARGS_T_MASK pcfs_args.mask = 0777; /* this may be the msdos file modes */ if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0) pcfs_args.mask = mask; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask); #endif /* HAVE_PCFS_ARGS_T_MASK */ #ifdef HAVE_PCFS_ARGS_T_DIRMASK pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */ if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0) pcfs_args.dirmask = mask; if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask); #endif /* HAVE_PCFS_ARGS_T_DIRMASK */ #ifdef HAVE_PCFS_ARGS_T_UID pcfs_args.uid = 0; /* default to root */ if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { struct passwd *pw; if ((pw = getpwnam(str)) != NULL) pcfs_args.uid = pw->pw_uid; else /* maybe used passed a UID number, not user name */ pcfs_args.uid = atoi(str); /* atoi returns '0' if it failed */ XFREE(str); } if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "mount_pcfs: uid=%d", (int) pcfs_args.uid); #endif /* HAVE_PCFS_ARGS_T_UID */ #ifdef HAVE_PCFS_ARGS_T_GID pcfs_args.gid = 0; /* default to wheel/root group */ if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { struct group *gr; if ((gr = getgrnam(str)) != NULL) pcfs_args.gid = gr->gr_gid; else /* maybe used passed a GID number, not group name */ pcfs_args.gid = atoi(str); /* atoi returns '0' if it failed */ XFREE(str); } if (amuDebug(D_TRACE)) plog(XLOG_DEBUG, "mount_pcfs: gid=%d", (int) pcfs_args.gid); #endif /* HAVE_PCFS_ARGS_T_GID */ #ifdef HAVE_PCFS_ARGS_T_SECONDSWEST pcfs_args.secondswest = 0; /* XXX: fill in correct values */ #endif /* HAVE_PCFS_ARGS_T_SECONDSWEST */ #ifdef HAVE_PCFS_ARGS_T_DSTTIME pcfs_args.dsttime = 0; /* XXX: fill in correct values */ #endif /* HAVE_PCFS_ARGS_T_DSTTIME */ /* * Call generic mount routine */ return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); }
int main(int argc, char *argv[]) { char *dot; char *mntopts = (char *) NULL; char hostpid_fs[MAXHOSTNAMELEN + 1 + 16]; /* room for ":(pid###)" */ char progpid_fs[PROGNAMESZ + 1 + 11]; /* room for ":pid" */ char preopts[128]; char *progname; int forcecache = 0; int forcefast = 0; int genflags = 0; int opt, ret; int opterrs = 0; int retry; int soNFS; /* NFS socket */ int s = -99; mntent_t mnt; nfs_args_t nfs_args; am_nfs_handle_t anh; struct dirent *direntry; struct group *grp; struct stat stmodes; DIR *mountdir; MTYPE_TYPE type = MOUNT_TYPE_NFS; #ifdef HAVE_SIGACTION struct sigaction sa; #endif /* not HAVE_SIGACTION */ #ifndef HAVE_TRANSPORT_TYPE_TLI struct sockaddr_in localsocket; #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /* get program name and truncate so we don't overflow progpid_fs */ if ((progname = strrchr(argv[0], '/')) != NULL) progname++; else progname = argv[0]; if ((int) strlen(progname) > PROGNAMESZ) /* truncate to reasonable size */ progname[PROGNAMESZ] = '\0'; am_set_progname(progname); while ((opt = getopt(argc, argv, "a:c:CD:fg:hi:l:no:pP:x:v")) != -1) switch (opt) { case 'a': if (!optarg || optarg[0] != '/') { printf("%s: invalid directory for -a: %s\n", am_get_progname(), optarg); exit(3); } alt_spooldir = optarg; break; case 'c': if (!atoi(optarg)) { printf("%s: invalid interval for -c: %s\n", am_get_progname(), optarg); exit(3); } cache_interval = atoi(optarg); break; case 'C': forcecache++; break; case 'f': forcefast++; break; case 'g': hlfs_group = optarg; break; case 'i': if (!atoi(optarg)) { printf("%s: invalid interval for -i: %s\n", am_get_progname(), optarg); exit(3); } reloadinterval.it_interval.tv_sec = atoi(optarg); reloadinterval.it_value.tv_sec = atoi(optarg); break; case 'l': logfile = optarg; break; case 'n': noverify++; break; case 'o': mntopts = optarg; break; case 'p': printpid++; break; case 'P': passwdfile = optarg; break; case 'v': fprintf(stderr, "%s\n", HLFSD_VERSION); exit(0); case 'x': opterrs += switch_option(optarg); break; case 'D': #ifdef DEBUG opterrs += debug_option(optarg); #else /* not DEBUG */ fprintf(stderr, "%s: not compiled with DEBUG -- sorry.\n", am_get_progname()); #endif /* not DEBUG */ break; case 'h': case '?': opterrs++; } /* need my pid before any dlog/plog */ am_set_mypid(); #ifdef DEBUG switch_option("debug"); #endif /* DEBUG */ /* * Terminate if did not ask to forcecache (-C) and hlfsd would not be able * to set the minimum cache intervals. */ #if !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_NFS_ARGS_T_ACREGMIN) if (!forcecache) { fprintf(stderr, "%s: will not be able to turn off attribute caches.\n", am_get_progname()); exit(1); } #endif /* !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_NFS_ARGS_T_ACREGMIN) */ switch (argc - optind) { case 2: home_subdir = argv[optind + 1]; case 1: dir_name = argv[optind]; case 0: break; default: opterrs++; } if (opterrs) usage(); /* ensure that only root can run hlfsd */ if (geteuid()) { fprintf(stderr, "hlfsd can only be run as root\n"); exit(1); } setbuf(stdout, (char *) NULL); umask(0); /* find gid for hlfs_group */ if ((grp = getgrnam(hlfs_group)) == (struct group *) NULL) { fprintf(stderr, "%s: cannot get gid for group \"%s\".\n", am_get_progname(), hlfs_group); } else { hlfs_gid = grp->gr_gid; } /* get hostname for logging and open log before we reset umask */ gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; if ((dot = strchr(hostname, '.')) != NULL) *dot = '\0'; orig_umask = umask(0); if (logfile) switch_to_logfile(logfile, orig_umask, 0); #ifndef MOUNT_TABLE_ON_FILE if (amuDebug(D_MTAB)) dlog("-D mtab option ignored"); #endif /* not MOUNT_TABLE_ON_FILE */ /* avoid hanging on other NFS servers if started elsewhere */ if (chdir("/") < 0) fatal("cannot chdir to /: %m"); if (geteuid() != 0) fatal("must be root to mount filesystems"); /* * dir_name must match "^(/.*)/([^/]+)$", and is split at last '/' with * slinkname = `basename $dir_name` - requires dir_name be writable */ if (dir_name[0] != '/' || ((slinkname = strrchr(dir_name, '/')), *slinkname++ = '\0', (dir_name[0] == '\0' || slinkname[0] == '\0'))) { if (slinkname) *--slinkname = '/'; printf("%s: invalid mount directory/link %s\n", am_get_progname(), dir_name); exit(3); } if (!forcefast) { /* make sure mount point exists and is at least mode 555 */ if (stat(dir_name, &stmodes) < 0) if (errno != ENOENT || mkdirs(dir_name, 0555) < 0 || stat(dir_name, &stmodes) < 0) fatalerror(dir_name); if ((stmodes.st_mode & 0555) != 0555) { fprintf(stderr, "%s: directory %s not read/executable\n", am_get_progname(), dir_name); plog(XLOG_WARNING, "directory %s not read/executable", dir_name); } /* warn if extraneous stuff will be hidden by mount */ if ((mountdir = opendir(dir_name)) == NULL) fatalerror(dir_name); while ((direntry = readdir(mountdir)) != NULL) { if (!NSTREQ(".", direntry->d_name, NAMLEN(direntry)) && !NSTREQ("..", direntry->d_name, NAMLEN(direntry)) && !NSTREQ(slinkname, direntry->d_name, NAMLEN(direntry))) break; } if (direntry != NULL) { fprintf(stderr, "%s: %s/%s will be hidden by mount\n", am_get_progname(), dir_name, direntry->d_name); plog(XLOG_WARNING, "%s/%s will be hidden by mount\n", dir_name, direntry->d_name); } closedir(mountdir); /* make sure alternate spool dir exists */ if ((errno = mkdirs(alt_spooldir, OPEN_SPOOLMODE))) { fprintf(stderr, "%s: cannot create alternate dir ", am_get_progname()); perror(alt_spooldir); plog(XLOG_ERROR, "cannot create alternate dir %s: %m", alt_spooldir); } chmod(alt_spooldir, OPEN_SPOOLMODE); /* create failsafe link to alternate spool directory */ *(slinkname-1) = '/'; /* unsplit dir_name to include link */ if (lstat(dir_name, &stmodes) == 0 && (stmodes.st_mode & S_IFMT) != S_IFLNK) { fprintf(stderr, "%s: failsafe %s not a symlink\n", am_get_progname(), dir_name); plog(XLOG_WARNING, "failsafe %s not a symlink\n", dir_name); } else { unlink(dir_name); if (symlink(alt_spooldir, dir_name) < 0) { fprintf(stderr, "%s: cannot create failsafe symlink %s -> ", am_get_progname(), dir_name); perror(alt_spooldir); plog(XLOG_WARNING, "cannot create failsafe symlink %s -> %s: %m", dir_name, alt_spooldir); } } *(slinkname-1) = '\0'; /* resplit dir_name */ } /* end of "if (!forcefast) {" */ /* * Register hlfsd as an nfs service with the portmapper. */ #ifdef HAVE_TRANSPORT_TYPE_TLI ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2); #else /* not HAVE_TRANSPORT_TYPE_TLI */ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ if (ret != 0) fatal("cannot create NFS service"); #ifdef HAVE_SIGACTION sa.sa_handler = proceed; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR2); sigaction(SIGUSR2, &sa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGUSR2, proceed); #endif /* not HAVE_SIGACTION */ plog(XLOG_INFO, "Initializing hlfsd..."); hlfsd_init(); /* start up child (forking) to run svc_run */ #ifdef HAVE_SIGACTION sa.sa_handler = reaper; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGCHLD, reaper); #endif /* not HAVE_SIGACTION */ /* * In the parent, if -D nodaemon, we don't need to * set this signal handler. */ if (amuDebug(D_DAEMON)) { s = -99; while (stoplight != SIGUSR2) { plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight); #ifdef HAVE_SIGSUSPEND { sigset_t mask; sigemptyset(&mask); s = sigsuspend(&mask); /* wait for child to set up */ } #else /* not HAVE_SIGSUSPEND */ s = sigpause(0); /* wait for child to set up */ #endif /* not HAVE_SIGSUSPEND */ sleep(1); } } /* * setup options to mount table (/etc/{mtab,mnttab}) entry */ xsnprintf(hostpid_fs, sizeof(hostpid_fs), "%s:(pid%d)", hostname, masterpid); memset((char *) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = dir_name; /* i.e., "/mail" */ mnt.mnt_fsname = hostpid_fs; if (mntopts) { mnt.mnt_opts = mntopts; } else { xstrlcpy(preopts, default_mntopts, sizeof(preopts)); /* * Turn off all kinds of attribute and symlink caches as * much as possible. Also make sure that mount does not * show up to df. */ #ifdef MNTTAB_OPT_INTR xstrlcat(preopts, ",", sizeof(preopts)); xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts)); #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_IGNORE xstrlcat(preopts, ",", sizeof(preopts)); xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts)); #endif /* MNTTAB_OPT_IGNORE */ #ifdef MNT2_GEN_OPT_CACHE xstrlcat(preopts, ",nocache", sizeof(preopts)); #endif /* MNT2_GEN_OPT_CACHE */ #ifdef MNT2_NFS_OPT_SYMTTL xstrlcat(preopts, ",symttl=0", sizeof(preopts)); #endif /* MNT2_NFS_OPT_SYMTTL */ mnt.mnt_opts = preopts; } /* * Make sure that amd's top-level NFS mounts are hidden by default * from df. * If they don't appear to support the either the "ignore" mnttab * option entry, or the "auto" one, set the mount type to "nfs". */ #ifdef HIDE_MOUNT_TYPE mnt.mnt_type = HIDE_MOUNT_TYPE; #else /* not HIDE_MOUNT_TYPE */ mnt.mnt_type = "nfs"; #endif /* not HIDE_MOUNT_TYPE */ /* some systems don't have a mount type, but a mount flag */ #ifndef HAVE_TRANSPORT_TYPE_TLI amu_get_myaddress(&localsocket.sin_addr, NULL); localsocket.sin_family = AF_INET; localsocket.sin_port = htons(nfsxprt->xp_port); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /* * Update hostname field. * Make some name prog:pid (i.e., hlfsd:174) for hostname */ xsnprintf(progpid_fs, sizeof(progpid_fs), "%s:%d", am_get_progname(), masterpid); /* Most kernels have a name length restriction. */ if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN) xstrlcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..", sizeof(progpid_fs) - MAXHOSTNAMELEN + 3); genflags = compute_mount_flags(&mnt); retry = hasmntval(&mnt, MNTTAB_OPT_RETRY); if (retry <= 0) retry = 1; /* XXX */ memmove(&anh.v2, root_fhp, sizeof(*root_fhp)); #ifdef HAVE_TRANSPORT_TYPE_TLI compute_nfs_args(&nfs_args, &mnt, genflags, nfsncp, NULL, /* remote host IP addr is set below */ NFS_VERSION, /* version 2 */ "udp", /* XXX: shouldn't this be "udp"? */ &anh, progpid_fs, /* host name for kernel */ hostpid_fs); /* filesystem name for kernel */ /* * IMPORTANT: set the correct IP address AFTERWARDS. It cannot * be done using the normal mechanism of compute_nfs_args(), because * that one will allocate a new address and use NFS_SA_DREF() to copy * parts to it, while assuming that the ip_addr passed is always * a "struct sockaddr_in". That assumption is incorrect on TLI systems, * because they define a special macro HOST_SELF which is DIFFERENT * than localhost (127.0.0.1)! */ nfs_args.addr = &nfsxprt->xp_ltaddr; #else /* not HAVE_TRANSPORT_TYPE_TLI */ compute_nfs_args(&nfs_args, &mnt, genflags, NULL, &localsocket, NFS_VERSION, /* version 2 */ "udp", /* XXX: shouldn't this be "udp"? */ &anh, progpid_fs, /* host name for kernel */ hostpid_fs); /* filesystem name for kernel */ #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /************************************************************************* * NOTE: while compute_nfs_args() works ok for regular NFS mounts * * the toplvl one is not, and so some options must be corrected by hand * * more carefully, *after* compute_nfs_args() runs. * *************************************************************************/ compute_automounter_nfs_args(&nfs_args, &mnt); /* * For some reason, this mount may have to be done in the background, if I am * using -D daemon. I suspect that the actual act of mounting requires * calling to hlfsd itself to invoke one or more of its nfs calls, to stat * /mail. That means that even if you say -D daemon, at least the mount * of hlfsd itself on top of /mail will be done in the background. * The other alternative I have is to run svc_run, but set a special * signal handler to perform the mount in N seconds via some alarm. * -Erez Zadok. */ if (!amuDebug(D_DAEMON)) { /* Normal case */ plog(XLOG_INFO, "normal NFS mounting hlfsd service points"); if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) fatal("nfsmount: %m"); } else { /* asked for -D daemon */ if (fork() == 0) { /* child runs mount */ am_set_mypid(); foreground = 0; plog(XLOG_INFO, "child NFS mounting hlfsd service points"); if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) { fatal("nfsmount: %m"); } exit(0); /* all went well */ } else { /* fork failed or parent running */ plog(XLOG_INFO, "parent waiting 1sec for mount..."); } } #ifdef HAVE_TRANSPORT_TYPE_TLI /* * XXX: this free_knetconfig() was not done for hlfsd before, * and apparently there was a reason for it, but why? -Erez */ free_knetconfig(nfs_args.knconf); /* * local automounter mounts do not allocate a special address, so * no need to XFREE(nfs_args.addr) under TLI. */ #endif /* HAVE_TRANSPORT_TYPE_TLI */ if (printpid) printf("%d\n", masterpid); plog(XLOG_INFO, "hlfsd ready to serve"); /* * If asked not to fork a daemon (-D nodaemon), then hlfsd_init() * will not run svc_run. We must start svc_run here. */ if (!amuDebug(D_DAEMON)) { plog(XLOG_DEBUG, "starting no-daemon debugging svc_run"); svc_run(); } cleanup(0); /* should never happen here */ return (0); /* everything went fine? */ }
void kernel_init(multiboot_info_t *mboot_info) { extern char __start_bss[], __stop_bss[]; memset(__start_bss, 0, __stop_bss - __start_bss); /* mboot_info is a physical address. while some arches currently have the * lower memory mapped, everyone should have it mapped at kernbase by now. * also, it might be in 'free' memory, so once we start dynamically using * memory, we may clobber it. */ multiboot_kaddr = (struct multiboot_info*)((physaddr_t)mboot_info + KERNBASE); extract_multiboot_cmdline(multiboot_kaddr); cons_init(); print_cpuinfo(); printk("Boot Command Line: '%s'\n", boot_cmdline); exception_table_init(); cache_init(); // Determine systems's cache properties pmem_init(multiboot_kaddr); kmem_cache_init(); // Sets up slab allocator kmalloc_init(); hashtable_init(); radix_init(); cache_color_alloc_init(); // Inits data structs colored_page_alloc_init(); // Allocates colors for agnostic processes acpiinit(); topology_init(); kthread_init(); /* might need to tweak when this happens */ vmr_init(); file_init(); page_check(); idt_init(); kernel_msg_init(); timer_init(); vfs_init(); devfs_init(); train_timing(); kb_buf_init(&cons_buf); arch_init(); block_init(); enable_irq(); run_linker_funcs(); /* reset/init devtab after linker funcs 3 and 4. these run NIC and medium * pre-inits, which need to happen before devether. */ devtabreset(); devtabinit(); #ifdef CONFIG_EXT2FS mount_fs(&ext2_fs_type, "/dev/ramdisk", "/mnt", 0); #endif /* CONFIG_EXT2FS */ #ifdef CONFIG_ETH_AUDIO eth_audio_init(); #endif /* CONFIG_ETH_AUDIO */ get_coreboot_info(&sysinfo); booting = 0; #ifdef CONFIG_RUN_INIT_SCRIPT if (run_init_script()) { printk("Configured to run init script, but no script specified!\n"); manager(); } #else manager(); #endif }
/* * Mount an automounter directory. * The automounter is connected into the system * as a user-level NFS server. mount_amfs_toplvl constructs * the necessary NFS parameters to be given to the * kernel so that it will talk back to us. * * NOTE: automounter mounts in themselves are using NFS Version 2. */ static int mount_amfs_toplvl(char *dir, char *opts) { char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1]; int retry, error, genflags; mntent_t mnt; nfs_args_t nfs_args; am_nfs_fh *fhp; am_nfs_handle_t anh; MTYPE_TYPE type = MOUNT_TYPE_NFS; #ifndef HAVE_TRANSPORT_TYPE_TLI u_short port; struct sockaddr_in sin; #endif /* not HAVE_TRANSPORT_TYPE_TLI */ memset((voidp) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = dir; mnt.mnt_fsname = pid_fsname; mnt.mnt_opts = opts; /* * Make sure that amd's top-level NFS mounts are hidden by default * from df. * If they don't appear to support the either the "ignore" mnttab * option entry, or the "auto" one, set the mount type to "nfs". */ mnt.mnt_type = HIDE_MOUNT_TYPE; retry = hasmntval(&mnt, MNTTAB_OPT_RETRY); if (retry <= 0) retry = 2; /* XXX */ /* * SET MOUNT ARGS */ /* * get fhandle of remote path for automount point */ fhp = root_fh(dir); if (!fhp) { plog(XLOG_FATAL, "Can't find root file handle for %s", dir); return EINVAL; } #ifndef HAVE_TRANSPORT_TYPE_TLI /* * Create sockaddr to point to the local machine. 127.0.0.1 * is not used since that will not work in HP-UX clusters and * this is no more expensive. */ memset((voidp) &sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = myipaddr; port = hasmntval(&mnt, MNTTAB_OPT_PORT); if (port) { sin.sin_port = htons(port); } else { plog(XLOG_ERROR, "no port number specified for %s", dir); return EINVAL; } #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /* * Make a ``hostname'' string for the kernel */ sprintf(fs_hostname, "pid%ld@%s:%s", (long) (foreground ? am_mypid : getppid()), am_get_hostname(), dir); /* * Most kernels have a name length restriction (64 bytes)... */ if (strlen(fs_hostname) >= MAXHOSTNAMELEN) strcpy(fs_hostname + MAXHOSTNAMELEN - 3, ".."); #ifdef HOSTNAMESZ /* * ... and some of these restrictions are 32 bytes (HOSTNAMESZ) * If you need to get the definition for HOSTNAMESZ found, you may * add the proper header file to the conf/nfs_prot/nfs_prot_*.h file. */ if (strlen(fs_hostname) >= HOSTNAMESZ) strcpy(fs_hostname + HOSTNAMESZ - 3, ".."); #endif /* HOSTNAMESZ */ /* * Finally we can compute the mount genflags set above, * and add any automounter specific flags. */ genflags = compute_mount_flags(&mnt); genflags |= compute_automounter_mount_flags(&mnt); /* setup the many fields and flags within nfs_args */ memmove(&anh.v2.fhs_fh, fhp, sizeof(*fhp)); #ifdef HAVE_TRANSPORT_TYPE_TLI compute_nfs_args(&nfs_args, &mnt, genflags, nfsncp, NULL, /* remote host IP addr is set below */ NFS_VERSION, /* version 2 */ "udp", &anh, fs_hostname, pid_fsname); /* * IMPORTANT: set the correct IP address AFTERWARDS. It cannot * be done using the normal mechanism of compute_nfs_args(), because * that one will allocate a new address and use NFS_SA_DREF() to copy * parts to it, while assuming that the ip_addr passed is always * a "struct sockaddr_in". That assumption is incorrect on TLI systems, * because they define a special macro HOST_SELF which is DIFFERENT * than localhost (127.0.0.1)! */ nfs_args.addr = &nfsxprt->xp_ltaddr; #else /* not HAVE_TRANSPORT_TYPE_TLI */ compute_nfs_args(&nfs_args, &mnt, genflags, &sin, NFS_VERSION, /* version 2 */ "udp", &anh, fs_hostname, pid_fsname); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /************************************************************************* * NOTE: while compute_nfs_args() works ok for regular NFS mounts * * the toplvl one is not, and so some options must be corrected by hand * * more carefully, *after* compute_nfs_args() runs. * *************************************************************************/ compute_automounter_nfs_args(&nfs_args, &mnt); /* This is it! Here we try to mount amd on its mount points */ #ifdef DEBUG amuDebug(D_TRACE) { print_nfs_args(&nfs_args, 0); plog(XLOG_DEBUG, "Generic mount flags 0x%x", genflags); } #endif /* DEBUG */ error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name); #ifdef HAVE_TRANSPORT_TYPE_TLI free_knetconfig(nfs_args.knconf); /* * local automounter mounts do not allocate a special address, so * no need to XFREE(nfs_args.addr) under TLI. */ #endif /* HAVE_TRANSPORT_TYPE_TLI */ return error; }
/* * Mount an automounter directory. * The automounter is connected into the system * as a user-level NFS server. amfs_mount constructs * the necessary NFS parameters to be given to the * kernel so that it will talk back to us. * * NOTE: automounter mounts in themselves are using NFS Version 2 (UDP). * * NEW: on certain systems, mounting can be done using the * kernel-level automount (autofs) support. In that case, * we don't need NFS at all here. */ int amfs_mount(am_node *mp, mntfs *mf, char *opts) { char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1]; int retry, error = 0, genflags; int on_autofs = mf->mf_flags & MFF_ON_AUTOFS; char *dir = mf->mf_mount; mntent_t mnt; MTYPE_TYPE type; int forced_unmount = 0; /* are we using forced unmounts? */ u_long nfs_version = get_nfs_dispatcher_version(nfs_dispatcher); memset(&mnt, 0, sizeof(mnt)); mnt.mnt_dir = dir; mnt.mnt_fsname = pid_fsname; mnt.mnt_opts = opts; #ifdef HAVE_FS_AUTOFS if (mf->mf_flags & MFF_IS_AUTOFS) { type = MOUNT_TYPE_AUTOFS; /* * Make sure that amd's top-level autofs mounts are hidden by default * from df. * XXX: It works ok on Linux, might not work on other systems. */ mnt.mnt_type = "autofs"; } else #endif /* HAVE_FS_AUTOFS */ { type = MOUNT_TYPE_NFS; /* * Make sure that amd's top-level NFS mounts are hidden by default * from df. * If they don't appear to support the either the "ignore" mnttab * option entry, or the "auto" one, set the mount type to "nfs". */ mnt.mnt_type = HIDE_MOUNT_TYPE; } retry = hasmntval(&mnt, MNTTAB_OPT_RETRY); if (retry <= 0) retry = 2; /* XXX: default to 2 retries */ /* * SET MOUNT ARGS */ /* * Make a ``hostname'' string for the kernel */ xsnprintf(fs_hostname, sizeof(fs_hostname), "pid%ld@%s:%s", get_server_pid(), am_get_hostname(), dir); /* * Most kernels have a name length restriction (64 bytes)... */ if (strlen(fs_hostname) >= MAXHOSTNAMELEN) xstrlcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..", sizeof(fs_hostname) - MAXHOSTNAMELEN + 3); #ifdef HOSTNAMESZ /* * ... and some of these restrictions are 32 bytes (HOSTNAMESZ) * If you need to get the definition for HOSTNAMESZ found, you may * add the proper header file to the conf/nfs_prot/nfs_prot_*.h file. */ if (strlen(fs_hostname) >= HOSTNAMESZ) xstrlcpy(fs_hostname + HOSTNAMESZ - 3, "..", sizeof(fs_hostname) - HOSTNAMESZ + 3); #endif /* HOSTNAMESZ */ /* * Finally we can compute the mount genflags set above, * and add any automounter specific flags. */ genflags = compute_mount_flags(&mnt); #ifdef HAVE_FS_AUTOFS if (on_autofs) genflags |= autofs_compute_mount_flags(&mnt); #endif /* HAVE_FS_AUTOFS */ genflags |= compute_automounter_mount_flags(&mnt); again: if (!(mf->mf_flags & MFF_IS_AUTOFS)) { nfs_args_t nfs_args; am_nfs_handle_t *fhp, anh; #ifndef HAVE_TRANSPORT_TYPE_TLI u_short port; struct sockaddr_in sin; #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /* * get fhandle of remote path for automount point */ fhp = get_root_nfs_fh(dir, &anh); if (!fhp) { plog(XLOG_FATAL, "Can't find root file handle for %s", dir); return EINVAL; } #ifndef HAVE_TRANSPORT_TYPE_TLI /* * Create sockaddr to point to the local machine. */ memset(&sin, 0, sizeof(sin)); /* as per POSIX, sin_len need not be set (used internally by kernel) */ sin.sin_family = AF_INET; sin.sin_addr = myipaddr; port = hasmntval(&mnt, MNTTAB_OPT_PORT); if (port) { sin.sin_port = htons(port); } else { plog(XLOG_ERROR, "no port number specified for %s", dir); return EINVAL; } #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /* setup the many fields and flags within nfs_args */ #ifdef HAVE_TRANSPORT_TYPE_TLI compute_nfs_args(&nfs_args, &mnt, genflags, nfsncp, NULL, /* remote host IP addr is set below */ nfs_version, "udp", fhp, fs_hostname, pid_fsname); /* * IMPORTANT: set the correct IP address AFTERWARDS. It cannot * be done using the normal mechanism of compute_nfs_args(), because * that one will allocate a new address and use NFS_SA_DREF() to copy * parts to it, while assuming that the ip_addr passed is always * a "struct sockaddr_in". That assumption is incorrect on TLI systems, * because they define a special macro HOST_SELF which is DIFFERENT * than localhost (127.0.0.1)! */ nfs_args.addr = &nfsxprt->xp_ltaddr; #else /* not HAVE_TRANSPORT_TYPE_TLI */ compute_nfs_args(&nfs_args, &mnt, genflags, NULL, &sin, nfs_version, "udp", fhp, fs_hostname, pid_fsname); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ /************************************************************************* * NOTE: while compute_nfs_args() works ok for regular NFS mounts * * the toplvl one is not quite regular, and so some options must be * * corrected by hand more carefully, *after* compute_nfs_args() runs. * *************************************************************************/ compute_automounter_nfs_args(&nfs_args, &mnt); if (amuDebug(D_TRACE)) { print_nfs_args(&nfs_args, 0); plog(XLOG_DEBUG, "Generic mount flags 0x%x", genflags); } /* This is it! Here we try to mount amd on its mount points */ error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, on_autofs); #ifdef HAVE_TRANSPORT_TYPE_TLI free_knetconfig(nfs_args.knconf); /* * local automounter mounts do not allocate a special address, so * no need to XFREE(nfs_args.addr) under TLI. */ #endif /* HAVE_TRANSPORT_TYPE_TLI */ #ifdef HAVE_FS_AUTOFS } else { /* This is it! Here we try to mount amd on its mount points */ error = mount_fs(&mnt, genflags, (caddr_t) mp->am_autofs_fh, retry, type, 0, NULL, mnttab_file_name, on_autofs); #endif /* HAVE_FS_AUTOFS */ } if (error == 0 || forced_unmount) return error; /* * If user wants forced/lazy unmount semantics, then try it iff the * current mount failed with EIO or ESTALE. */ if (gopt.flags & CFM_FORCED_UNMOUNTS) { switch (errno) { case ESTALE: case EIO: forced_unmount = errno; plog(XLOG_WARNING, "Mount %s failed (%m); force unmount.", mp->am_path); if ((error = UMOUNT_FS(mp->am_path, mnttab_file_name, AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH)) < 0) { plog(XLOG_WARNING, "Forced umount %s failed: %m.", mp->am_path); errno = forced_unmount; } else goto again; default: break; } } return error; }