/etc/rc: use mount -a instead of manual parsing

The rc script manually parses /etc/fstab to mount all file systems.
To do that it needs /bin/sed which does not exist anymore. mount(8)
now supports the -a flag which causes it to mount all file systems
listed in /etc/fstab except for '/'. File systems marked with 'noauto'
are skipped.
This commit is contained in:
Thomas Veerman 2012-06-19 16:03:11 +00:00
parent eecd451343
commit 6759b24c57
6 changed files with 109 additions and 85 deletions

View file

@ -15,24 +15,27 @@
#include <sys/svrctl.h>
#include <stdio.h>
#include "mfs/const.h"
#include <fstab.h>
#define MINIX_FS_TYPE "mfs"
int main(int argc, char **argv);
void list(void);
void usage(void);
void update_mtab(char *dev, char *mountpoint, char *fstype, int mountflags);
int mount_all(void);
static int write_mtab = 1;
int main(argc, argv)
int argc;
char *argv[];
{
int i, n, v = 0, mountflags, write_mtab;
char **ap, *vs, *opt, *err, *type, *args, *device;
char special[PATH_MAX], mounted_on[PATH_MAX], version[10], rw_flag[10];
int all = 0, i, v = 0, mountflags;
char **ap, *opt, *err, *type, *args, *device;
if (argc == 1) list(); /* just list /etc/mtab */
mountflags = 0;
write_mtab = 1;
type = NULL;
args = NULL;
ap = argv+1;
@ -50,6 +53,7 @@ char *argv[];
case 'o': if (++i == argc) usage();
args = argv[i];
break;
case 'a': all = 1; break;
default: usage();
}
} else {
@ -59,7 +63,10 @@ char *argv[];
*ap = NULL;
argc = (ap - argv);
if (argc != 3 || *argv[1] == 0) usage();
if (!all && (argc != 3 || *argv[1] == 0)) usage();
if (all == 1) {
return mount_all();
}
device = argv[1];
if (!strcmp(device, "none")) device = NULL;
@ -79,7 +86,7 @@ char *argv[];
err = strerror(errno);
fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
argv[1], argv[2], err);
exit(1);
return(EXIT_FAILURE);
}
/* The mount has completed successfully. Tell the user. */
@ -87,11 +94,23 @@ char *argv[];
argv[1], mountflags & MS_RDONLY ? "only" : "write", argv[2]);
/* Update /etc/mtab. */
if (!write_mtab) return 0;
update_mtab(argv[1], argv[2], type, mountflags);
return(EXIT_SUCCESS);
}
void
update_mtab(char *dev, char *mountpoint, char *fstype, int mountflags)
{
int n;
char *vs;
char special[PATH_MAX], mounted_on[PATH_MAX], version[10], rw_flag[10];
if (!write_mtab) return;
n = load_mtab("mount");
if (n < 0) exit(1); /* something is wrong. */
/* Loop on all the /etc/mtab entries, copying each one to the output buf. */
/* Loop on all the /etc/mtab entries, copying each one to the output
* buf. */
while (1) {
n = get_mtab_entry(special, mounted_on, version, rw_flag);
if (n < 0) break;
@ -102,21 +121,14 @@ char *argv[];
}
}
/* For MFS, use a version number. Otherwise, use the FS type name. */
if (!strcmp(type, MINIX_FS_TYPE)) {
switch (v) {
case FSVERSION_MFS1: vs = "MFSv1"; break;
case FSVERSION_MFS2: vs = "MFSv2"; break;
case FSVERSION_MFS3: vs = "MFSv3"; break;
default: vs = "0"; break;
}
if (!strcmp(fstype, MINIX_FS_TYPE)) {
vs = "MFSv3";
} else if (strlen(fstype) < sizeof(version)) {
vs = fstype;
} else {
/* Keep the version field sufficiently short. */
if (strlen(type) < sizeof(version))
vs = type;
else
vs = "-";
}
n = put_mtab_entry(argv[1], argv[2], vs,
n = put_mtab_entry(dev, mountpoint, vs,
(mountflags & MS_RDONLY ? "ro" : "rw") );
if (n < 0) {
std_err("mount: /etc/mtab has grown too large\n");
@ -124,10 +136,8 @@ char *argv[];
}
n = rewrite_mtab("mount");
return(0);
}
void list()
{
int n;
@ -147,9 +157,58 @@ void list()
exit(0);
}
int
has_opt(char *mntopts, char *option)
{
char *optbuf, *opt;
int found = 0;
optbuf = strdup(mntopts);
for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
if (!strcmp(opt, option)) found = 1;
}
free (optbuf);
return(found);
}
int
mount_all()
{
struct fstab *fs;
char mountpoint[PATH_MAX];
while ((fs = getfsent()) != NULL) {
int ro = 0;
int mountflags = 0;
if (realpath(fs->fs_file, mountpoint) == NULL) {
fprintf(stderr, "Can't mount on %s\n", fs->fs_file);
return(EXIT_FAILURE);
}
if (has_opt(fs->fs_mntops, "noauto"))
continue;
if (!strcmp(mountpoint, "/"))
continue; /* Not remounting root */
if (has_opt(fs->fs_mntops, "ro"))
ro = 1;
if (ro) {
mountflags |= MS_RDONLY;
}
if (mount(fs->fs_spec, mountpoint, mountflags, fs->fs_vfstype,
NULL) == 0) {
update_mtab(fs->fs_spec, fs->fs_file, fs->fs_vfstype,
mountflags);
} else {
return(EXIT_FAILURE);
}
}
return(EXIT_SUCCESS);
}
void usage()
{
std_err("Usage: mount [-r] [-e] [-t type] [-o options] special name\n");
std_err("Usage: mount [-a] [-r] [-e] [-t type] [-o options] special name\n");
exit(1);
}

View file

@ -13,7 +13,7 @@ FILES1=group hostname.file inet.conf motd.install mtab profile \
protocols rc services termcap utmp rc.cd \
syslog.conf rc.daemons.dist \
rs.inet rs.single make.conf system.conf ttys resolv.conf rc.conf \
rc.subr rc.subr.minix man.conf shells boot.cfg.default \
rc.subr man.conf shells boot.cfg.default \
devmand/scripts/block devmand/scripts/singlechar
#
@ -53,7 +53,7 @@ install: installpw # installpw needed to bootstrap pw db
@echo "Installing fonts.."
${INSTALL_FILE} -m 644 -o root -g operator fonts/*.fnt ${DESTDIR}/usr/lib/fonts/
installforce:: $(ETC)/rc $(ETC)/rs.inet $(ETC)/rs.single $(ETC)/system.conf $(ETC)/rc.subr.minix $(USRETC)/rc $(USR)/Makefile installpw
installforce:: $(ETC)/rc $(ETC)/rs.inet $(ETC)/rs.single $(ETC)/system.conf $(USRETC)/rc $(USR)/Makefile installpw
installpw::
if [ ! -d $(ETC) ]; then ${INSTALL_DIR} $(ETC); chmod 755 $(ETC); fi
@ -72,9 +72,6 @@ $(ETC)/rs.single: rs.single .PHONY
$(ETC)/system.conf: system.conf .PHONY
${INSTALL_FILE} -m 644 -o root -g operator $> $@
$(ETC)/rc.subr.minix: rc.subr.minix .PHONY
${INSTALL_FILE} -m 644 -o root -g operator $> $@
$(USRETC)/rc: usr/rc .PHONY
${INSTALL_FILE} -m 755 -o root -g operator $> $@

4
etc/rc
View file

@ -1,7 +1,5 @@
# /etc/rc - System startup script run by init before going multiuser.
. /etc/rc.subr.minix
exec >/dev/log
exec 2>/dev/log
exec </dev/null
@ -147,7 +145,7 @@ start)
if [ "$fstabline" = "# Poor man's File System Table." ]
then mountfstab_poorman # Old minix /etc/fstab
else fsck -x / $fflag $fsckopts
mountfstab $FSTAB
mount -a
fi
fi

View file

@ -1,33 +0,0 @@
mountfstab()
{
fstabfile="$1"
if [ ! -f $fstabfile ]
then echo "mountfstab: $fstabfile not found"
return 1
fi
cat $fstabfile | sed 's/#.*//' | while read fsline
do set "" $fsline
shift
if [ $# -eq 0 ]; then continue; fi
if [ $# -lt 3 ]
then echo "$fstabfile: short line"
continue
fi
# This line's parameters
dev="$1"; mp="$2"; fstype="$3"
# Don't mount / as it's already mounted
if [ "$mp" = "/" ]; then continue; fi
# Sanity checks
if [ ! -b $dev ]; then echo "$dev missing"; continue; fi
if [ ! -d $mp ]; then echo "$mp missing"; continue; fi
# Do actual mount command
mount -t $fstype $dev $mp
done
}

View file

@ -97,10 +97,7 @@ up()
get_eth_labels() {
# Filter out the non-vlan ethernet entries from inet.conf.
# Produce as output a list of "drivername_instancenr"-formatted labels.
# The first sed is taken from /bin as older GNU sed versions don't know '\t'.
# /bin/sed is the minix sed, /usr/bin/sed is the netbsd sed. Earlier versions
# of this script used \t that only the minix sed understands.
/bin/sed 's/\008/ /g' /etc/inet.conf | \
sed 's/\008/ /g' /etc/inet.conf | \
sed -n 's/^ *eth[0-9][0-9]* *\([^ ][^ ]*\) *\([0-9][0-9]*\).*$/\1_\2/p' | \
grep -v '^vlan_'
}

View file

@ -16,6 +16,9 @@ mount \- mount a file system
..
.SH OPTIONS
.TP 5
.B \-a
# All file systems in /etc/fstab except \/ are mounted. File systems marked 'noauto' are skipped
.TP 5
.B \-r
# File system is mounted read-only
.TP 5
@ -34,6 +37,9 @@ mount \- mount a file system
.TP 20
.B mount \-t procfs none /proc
# Mount proc file system on \fI/proc\fP
.TP 20
.B mount \-a
# Mount all file systems listed in /etc/fstab except \/.
.SH DESCRIPTION
.PP
The file system contained on the special file \fIspecial\fP is mounted on