smount() { register struct a { char *fspec; char *freg; int ronly; } *uap = (struct a *)u.u_ap; dev_t dev; register struct inode *ip; register struct fs *fs; register struct nameidata *ndp = &u.u_nd; u_int len; u.u_error = getmdev(&dev, uap->fspec); if (u.u_error) return; ndp->ni_nameiop = LOOKUP | FOLLOW; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = (caddr_t)uap->freg; ip = namei(ndp); if (ip == NULL) return; if (ip->i_count != 1) { iput(ip); u.u_error = EBUSY; return; } if ((ip->i_mode&IFMT) != IFDIR) { iput(ip); u.u_error = ENOTDIR; return; } fs = mountfs(dev, uap->ronly, ip); if (fs == 0) return; (void) copyinstr(uap->freg, fs->fs_fsmnt, sizeof(fs->fs_fsmnt)-1, &len); bzero(fs->fs_fsmnt + len, sizeof (fs->fs_fsmnt) - len); }
int main(int argc, char *argv[]) { const char *mntfromname, **vfslist, *vfstype; struct fstab *fs; struct statfs *mntbuf; int all, ch, i, init_flags, late, failok, mntsize, rval, have_fstab, ro; int onlylate; char *cp, *ep, *options; all = init_flags = late = onlylate = 0; ro = 0; options = NULL; vfslist = NULL; vfstype = "ufs"; while ((ch = getopt(argc, argv, "adF:fLlno:prt:uvw")) != -1) switch (ch) { case 'a': all = 1; break; case 'd': debug = 1; break; case 'F': setfstab(optarg); break; case 'f': init_flags |= MNT_FORCE; break; case 'L': onlylate = 1; late = 1; break; case 'l': late = 1; break; case 'n': /* For compatibility with the Linux version of mount. */ break; case 'o': if (*optarg) { options = catopt(options, optarg); if (specified_ro(optarg)) ro = 1; } break; case 'p': fstab_style = 1; verbose = 1; break; case 'r': options = catopt(options, "ro"); ro = 1; break; case 't': if (vfslist != NULL) errx(1, "only one -t option may be specified"); vfslist = makevfslist(optarg); vfstype = optarg; break; case 'u': init_flags |= MNT_UPDATE; break; case 'v': verbose = 1; break; case 'w': options = catopt(options, "noro"); break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; #define BADTYPE(type) \ (strcmp(type, FSTAB_RO) && \ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) if ((init_flags & MNT_UPDATE) && (ro == 0)) options = catopt(options, "noro"); rval = 0; switch (argc) { case 0: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) err(1, "getmntinfo"); if (all) { while ((fs = getfsent()) != NULL) { if (BADTYPE(fs->fs_type)) continue; if (checkvfsname(fs->fs_vfstype, vfslist)) continue; if (hasopt(fs->fs_mntops, "noauto")) continue; if (!hasopt(fs->fs_mntops, "late") && onlylate) continue; if (hasopt(fs->fs_mntops, "late") && !late) continue; if (hasopt(fs->fs_mntops, "failok")) failok = 1; else failok = 0; if (!(init_flags & MNT_UPDATE) && ismounted(fs, mntbuf, mntsize)) continue; options = update_options(options, fs->fs_mntops, mntbuf->f_flags); if (mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops) && !failok) rval = 1; } } else if (fstab_style) { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; putfsent(&mntbuf[i]); } } else { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; if (!verbose && (mntbuf[i].f_flags & MNT_IGNORE) != 0) continue; prmount(&mntbuf[i]); } } exit(rval); case 1: if (vfslist != NULL) usage(); rmslashes(*argv, *argv); if (init_flags & MNT_UPDATE) { mntfromname = NULL; have_fstab = 0; if ((mntbuf = getmntpt(*argv)) == NULL) errx(1, "not currently mounted %s", *argv); /* * Only get the mntflags from fstab if both mntpoint * and mntspec are identical. Also handle the special * case where just '/' is mounted and 'spec' is not * identical with the one from fstab ('/dev' is missing * in the spec-string at boot-time). */ if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) { if (strcmp(fs->fs_spec, mntbuf->f_mntfromname) == 0 && strcmp(fs->fs_file, mntbuf->f_mntonname) == 0) { have_fstab = 1; mntfromname = mntbuf->f_mntfromname; } else if (argv[0][0] == '/' && argv[0][1] == '\0') { fs = getfsfile("/"); have_fstab = 1; mntfromname = fs->fs_spec; } } if (have_fstab) { options = update_options(options, fs->fs_mntops, mntbuf->f_flags); } else { mntfromname = mntbuf->f_mntfromname; options = update_options(options, NULL, mntbuf->f_flags); } rval = mountfs(mntbuf->f_fstypename, mntfromname, mntbuf->f_mntonname, init_flags, options, 0); break; } if ((fs = getfsfile(*argv)) == NULL && (fs = getfsspec(*argv)) == NULL) errx(1, "%s: unknown special file or file system", *argv); if (BADTYPE(fs->fs_type)) errx(1, "%s has unknown file system type", *argv); rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops); break; case 2: /* * If -t flag has not been specified, the path cannot be * found, spec contains either a ':' or a '@', then assume * that an NFS file system is being specified ala Sun. * Check if the hostname contains only allowed characters * to reduce false positives. IPv6 addresses containing * ':' will be correctly parsed only if the separator is '@'. * The definition of a valid hostname is taken from RFC 1034. */ if (vfslist == NULL && ((ep = strchr(argv[0], '@')) != NULL || (ep = strchr(argv[0], ':')) != NULL)) { if (*ep == '@') { cp = ep + 1; ep = cp + strlen(cp); } else cp = argv[0]; while (cp != ep) { if (!isdigit(*cp) && !isalpha(*cp) && *cp != '.' && *cp != '-' && *cp != ':') break; cp++; } if (cp == ep) vfstype = "nfs"; } rval = mountfs(vfstype, argv[0], argv[1], init_flags, options, NULL); break; default: usage(); /* NOTREACHED */ } /* * If the mount was successfully, and done by root, tell mountd the * good news. */ if (rval == 0 && getuid() == 0) restart_mountd(); exit(rval); }
int main(int argc, char **argv) { const char *mntfromname, **vfslist, *vfstype; struct fstab *fs; struct statfs *mntbuf; FILE *mountdfp; pid_t pid; int all, ch, i, init_flags, mntsize, rval, have_fstab; char *options; all = init_flags = 0; options = NULL; vfslist = NULL; vfstype = "ufs"; while ((ch = getopt(argc, argv, "adF:fo:prwt:uv")) != -1) { switch (ch) { case 'a': all = 1; break; case 'd': debug = 1; break; case 'F': setfstab(optarg); break; case 'f': init_flags |= MNT_FORCE; break; case 'o': if (*optarg) options = catopt(options, optarg); break; case 'p': fstab_style = 1; verbose = 1; break; case 'r': options = catopt(options, "ro"); break; case 't': if (vfslist != NULL) errx(1, "only one -t option may be specified"); vfslist = makevfslist(optarg); vfstype = optarg; break; case 'u': init_flags |= MNT_UPDATE; break; case 'v': verbose = 1; break; case 'w': options = catopt(options, "noro"); break; case '?': default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; #define BADTYPE(type) \ (strcmp(type, FSTAB_RO) && \ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) rval = 0; switch (argc) { case 0: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) err(1, "getmntinfo"); if (all) { while ((fs = getfsent()) != NULL) { if (BADTYPE(fs->fs_type)) continue; if (checkvfsname(fs->fs_vfstype, vfslist)) continue; if (hasopt(fs->fs_mntops, "noauto")) continue; if (!(init_flags & MNT_UPDATE) && ismounted(fs, mntbuf, mntsize)) continue; options = update_options(options, fs->fs_mntops, mntbuf->f_flags); if (mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops)) rval = 1; } } else if (fstab_style) { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; putfsent(&mntbuf[i]); } } else { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; prmount(&mntbuf[i]); } } exit(rval); case 1: if (vfslist != NULL) usage(); rmslashes(*argv, *argv); if (init_flags & MNT_UPDATE) { mntfromname = NULL; have_fstab = 0; if ((mntbuf = getmntpt(*argv)) == NULL) errx(1, "not currently mounted %s", *argv); /* * Only get the mntflags from fstab if both mntpoint * and mntspec are identical. Also handle the special * case where just '/' is mounted and 'spec' is not * identical with the one from fstab ('/dev' is missing * in the spec-string at boot-time). */ if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) { if (strcmp(fs->fs_spec, mntbuf->f_mntfromname) == 0 && strcmp(fs->fs_file, mntbuf->f_mntonname) == 0) { have_fstab = 1; mntfromname = mntbuf->f_mntfromname; } else if (argv[0][0] == '/' && argv[0][1] == '\0') { fs = getfsfile("/"); have_fstab = 1; mntfromname = fs->fs_spec; } } if (have_fstab) { options = update_options(options, fs->fs_mntops, mntbuf->f_flags); } else { mntfromname = mntbuf->f_mntfromname; options = update_options(options, NULL, mntbuf->f_flags); } rval = mountfs(mntbuf->f_fstypename, mntfromname, mntbuf->f_mntonname, init_flags, options, 0); break; } if ((fs = getfsfile(*argv)) == NULL && (fs = getfsspec(*argv)) == NULL) errx(1, "%s: unknown special file or file system", *argv); if (BADTYPE(fs->fs_type)) errx(1, "%s has unknown file system type", *argv); rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops); break; case 2: /* * If -t flag has not been specified, the path cannot be * found. * * If the spec is not a file and contains a ':' then assume * NFS. * * If the spec is a cdev attempt to extract the fstype from * the label. * * When all else fails ufs is assumed. */ if (vfslist == NULL) { if (strpbrk(argv[0], ":") != NULL && access(argv[0], 0) == -1) { vfstype = "nfs"; } else { checkdisklabel(argv[0], &vfstype); } } rval = mountfs(vfstype, getdevpath(argv[0], 0), argv[1], init_flags, options, NULL); break; default: usage(); /* NOTREACHED */ } /* * If the mount was successfully, and done by root, tell mountd the * good news. Pid checks are probably unnecessary, but don't hurt. */ if (rval == 0 && getuid() == 0 && (mountdfp = fopen(_PATH_MOUNTDPID, "r")) != NULL) { if (fscanf(mountdfp, "%d", &pid) == 1 && pid > 0 && kill(pid, SIGHUP) == -1 && errno != ESRCH) err(1, "signal mountd"); fclose(mountdfp); } exit(rval); }
/* * Initialization code. * Called from cold start routine as * soon as a stack and segmentation * have been established. * Functions: * clear and free user core * turn on clock * hand craft 0th process * call all initialization routines * fork - process 0 to schedule * - process 1 execute bootstrap */ int main() { register struct proc *p; register int i; register struct fs *fs = NULL; char inbuf[4]; char inch; int s __attribute__((unused)); startup(); printf ("\n%s", version); cpuidentify(); cnidentify(); /* * Set up system process 0 (swapper). */ p = &proc[0]; p->p_addr = (size_t) &u; p->p_stat = SRUN; p->p_flag |= SLOAD | SSYS; p->p_nice = NZERO; u.u_procp = p; /* init user structure */ u.u_cmask = CMASK; u.u_lastfile = -1; for (i = 1; i < NGROUPS; i++) u.u_groups[i] = NOGROUP; for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = RLIM_INFINITY; /* Initialize signal state for process 0 */ siginit (p); /* * Initialize tables, protocols, and set up well-known inodes. */ #ifdef LOG_ENABLED loginit(); #endif coutinit(); cinit(); pqinit(); ihinit(); bhinit(); binit(); nchinit(); clkstart(); s = spl0(); rdisk_init(); pipedev = rootdev = get_boot_device(); swapdev = get_swap_device(); /* Mount a root filesystem. */ for (;;) { if(rootdev!=-1) { fs = mountfs (rootdev, (boothowto & RB_RDONLY) ? MNT_RDONLY : 0, (struct inode*) 0); } if (fs) break; printf ("No root filesystem available!\n"); // rdisk_list_partitions(RDISK_FS); retry: printf ("Please enter device to boot from (press ? to list): "); inch=0; inbuf[0] = inbuf[1] = inbuf[2] = inbuf[3] = 0; while((inch=cngetc()) != '\r') { switch(inch) { case '?': printf("?\n"); rdisk_list_partitions(RDISK_FS); printf ("Please enter device to boot from (press ? to list): "); break; default: printf("%c",inch); inbuf[0] = inbuf[1]; inbuf[1] = inbuf[2]; inbuf[2] = inbuf[3]; inbuf[3] = inch; break; } } inch = 0; if(inbuf[0]=='r' && inbuf[1]=='d') { if(inbuf[2]>='0' && inbuf[2] < '0'+rdisk_num_disks()) { if(inbuf[3]>='a' && inbuf[3]<='d') { rootdev=makedev(inbuf[2]-'0',inbuf[3]-'a'+1); inch = 1; } } } else if(inbuf[1]=='r' && inbuf[2]=='d') { if(inbuf[3]>='0' && inbuf[3] < '0'+rdisk_num_disks()) { rootdev=makedev(inbuf[3]-'0',0); inch = 1; } } else if(inbuf[3] == 0) { inch = 1; } if(inch==0) { printf("\nUnknown device.\n\n"); goto retry; } printf ("\n\n"); } printf ("phys mem = %u kbytes\n", physmem / 1024); printf ("user mem = %u kbytes\n", MAXMEM / 1024); if(minor(rootdev)==0) { printf ("root dev = rd%d (%d,%d)\n", major(rootdev), major(rootdev), minor(rootdev) ); } else { printf ("root dev = rd%d%c (%d,%d)\n", major(rootdev), 'a'+minor(rootdev)-1, major(rootdev), minor(rootdev) ); } printf ("root size = %u kbytes\n", fs->fs_fsize * DEV_BSIZE / 1024); mount[0].m_inodp = (struct inode*) 1; /* XXX */ mount_updname (fs, "/", "root", 1, 4); time.tv_sec = fs->fs_time; boottime = time; /* Find a swap file. */ swapstart = 1; while(swapdev == -1) { printf("Please enter swap device (press ? to list): "); inbuf[0] = inbuf[1] = inbuf[2] = inbuf[3] = 0; while((inch = cngetc())!='\r') { switch(inch) { case '?': printf("?\n"); rdisk_list_partitions(RDISK_SWAP); printf("Please enter swap device (press ? to list): "); break; default: printf("%c",inch); inbuf[0] = inbuf[1]; inbuf[1] = inbuf[2]; inbuf[2] = inbuf[3]; inbuf[3] = inch; break; } } inch = 0; if(inbuf[0]=='r' && inbuf[1]=='d') { if(inbuf[2]>='0' && inbuf[2] < '0'+rdisk_num_disks()) { if(inbuf[3]>='a' && inbuf[3]<='d') { swapdev=makedev(inbuf[2]-'0',inbuf[3]-'a'+1); inch = 1; } } } else if(inbuf[1]=='r' && inbuf[2]=='d') { if(inbuf[3]>='0' && inbuf[3] < '0'+rdisk_num_disks()) { swapdev=makedev(inbuf[3]-'0',0); inch = 1; } } if(minor(swapdev)!=0) { if(partition_type(swapdev)!=RDISK_SWAP) { printf("\nNot a swap partition!\n\n"); swapdev=-1; } } } nswap = rdsize(swapdev); if(minor(swapdev)==0) { printf ("swap dev = rd%d (%d,%d)\n", major(swapdev), major(swapdev), minor(swapdev) ); } else { printf ("swap dev = rd%d%c (%d,%d)\n", major(swapdev), 'a'+minor(swapdev)-1, major(swapdev), minor(swapdev) ); } (*bdevsw[major(swapdev)].d_open)(swapdev, FREAD|FWRITE, S_IFBLK); printf ("swap size = %u kbytes\n", nswap * DEV_BSIZE / 1024); if (nswap <= 0) panic ("zero swap size"); /* don't want to panic, but what ? */ mfree (swapmap, nswap, swapstart); /* Kick off timeout driven events by calling first time. */ schedcpu (0); /* Set up the root file system. */ rootdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO); iunlock (rootdir); u.u_cdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO); iunlock (u.u_cdir); u.u_rdir = NULL; /* * Make init process. */ if (newproc (0) == 0) { /* Parent process with pid 0: swapper. * No return from sched. */ sched(); } /* Child process with pid 1: init. */ s = splhigh(); p = u.u_procp; p->p_dsize = icodeend - icode; p->p_daddr = USER_DATA_START; p->p_ssize = 1024; /* one kbyte of stack */ p->p_saddr = USER_DATA_END - 1024; bcopy ((caddr_t) icode, (caddr_t) USER_DATA_START, icodeend - icode); /* * return goes to location 0 of user init code * just copied out. */ return 0; }