Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/*
 * 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;
}