From fe8c612aa46a2cce706e09bd498ad0ad6310110d Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Wed, 13 May 2009 15:39:44 +0000 Subject: [PATCH] support in 'mount' for specifying file system type and options --- commands/simple/badblocks.c | 4 +-- commands/simple/mount.c | 44 ++++++++++++++++++------- commands/simple/newroot.c | 2 +- include/unistd.h | 3 +- lib/posix/_mount.c | 64 ++++++++++++++++++++++++++----------- man/man1/mount.1 | 12 ++++++- man/man2/mount.2 | 9 +++++- 7 files changed, 102 insertions(+), 36 deletions(-) diff --git a/commands/simple/badblocks.c b/commands/simple/badblocks.c index 36682c377..e5d59e9ca 100755 --- a/commands/simple/badblocks.c +++ b/commands/simple/badblocks.c @@ -294,7 +294,7 @@ char *argv[]; } /* Mount device. This call may fail. */ - mount(dev_name, dir_name, 0); + mount(dev_name, dir_name, 0, NULL, NULL); /* Succes. dev was mounted, try to umount */ /* Umount device. Playing with the file system while other processes @@ -309,7 +309,7 @@ char *argv[]; strcat(file_name, "/"); strcat(file_name, f_name); - if (mount(dev_name, dir_name, 0) == -1) { /* this call should work */ + if (mount(dev_name, dir_name, 0, NULL, NULL) == -1) { /* this call should work */ fprintf(stderr, "Could not mount device anymore\n"); done(HARMLESS); } diff --git a/commands/simple/mount.c b/commands/simple/mount.c index 2bf4277cd..3ee188eaf 100755 --- a/commands/simple/mount.c +++ b/commands/simple/mount.c @@ -16,6 +16,8 @@ #include #include "../../servers/mfs/const.h" +#define MINIX_FS_TYPE "mfs" + _PROTOTYPE(int main, (int argc, char **argv)); _PROTOTYPE(void list, (void)); _PROTOTYPE(void usage, (void)); @@ -29,12 +31,14 @@ int argc; char *argv[]; { int i, ro, swap, n, v; - char **ap, *vs, *opt, *err; + char **ap, *vs, *opt, *err, *type, *args; char special[PATH_MAX+1], mounted_on[PATH_MAX+1], version[10], rw_flag[10]; if (argc == 1) list(); /* just list /etc/mtab */ ro = 0; swap = 0; + type = NULL; + args = NULL; ap = argv+1; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { @@ -42,6 +46,12 @@ char *argv[]; while (*opt != 0) switch (*opt++) { case 'r': ro = 1; break; case 's': swap = 1; break; + case 't': if (++i == argc) usage(); + type = argv[i]; + break; + case 'o': if (++i == argc) usage(); + args = argv[i]; + break; default: usage(); } } else { @@ -60,7 +70,7 @@ char *argv[]; tell(" is swapspace\n"); } else { if (argc != 3) usage(); - if (mount(argv[1], argv[2], ro) < 0) { + if (mount(argv[1], argv[2], ro, type, args) < 0) { err = strerror(errno); std_err("mount: Can't mount "); std_err(argv[1]); @@ -97,15 +107,24 @@ char *argv[]; if (swap) { vs = "swap"; } else { - v = fsversion(argv[1], "mount"); - if (v == 1) - vs = "1"; - else if (v == 2) - vs = "2"; - else if (v == 3) - vs = "3"; - else - vs = "0"; + /* For MFS, use a version number. Otherwise, use the FS type name. */ + if (type == NULL || !strcmp(type, MINIX_FS_TYPE)) { + v = fsversion(argv[1], "mount"); + if (v == 1) + vs = "1"; + else if (v == 2) + vs = "2"; + else if (v == 3) + vs = "3"; + else + vs = "0"; + } else { + /* Keep the version field sufficiently short. */ + if (strlen(type) < sizeof(version)) + vs = type; + else + vs = "-"; + } } n = put_mtab_entry(argv[1], swap ? "swap" : argv[2], vs, (ro ? "ro" : "rw") ); if (n < 0) { @@ -147,7 +166,8 @@ void list() void usage() { - std_err("Usage: mount [-r] special name\n mount -s special\n"); + std_err("Usage: mount [-r] [-t type] [-o options] special name\n" + " mount -s special\n"); exit(1); } diff --git a/commands/simple/newroot.c b/commands/simple/newroot.c index 4a9a04756..f979dabe0 100644 --- a/commands/simple/newroot.c +++ b/commands/simple/newroot.c @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) exit(1); } dev= argv[1]; - r= mount(dev, "/", 0 /* !ro */); + r= mount(dev, "/", 0 /* !ro */, NULL, NULL); if (r != 0) { fprintf(stderr, "newroot: mount failed: %s\n", strerror(errno)); diff --git a/include/unistd.h b/include/unistd.h index d86bdf1d6..0e52d10f2 100755 --- a/include/unistd.h +++ b/include/unistd.h @@ -171,7 +171,8 @@ _PROTOTYPE( int mknod, (const char *_name, _mnx_Mode_t _mode, Dev_t _addr) ); _PROTOTYPE( int mknod4, (const char *_name, _mnx_Mode_t _mode, Dev_t _addr, long _size) ); _PROTOTYPE( char *mktemp, (char *_template) ); -_PROTOTYPE( int mount, (char *_spec, char *_name, int _flag) ); +_PROTOTYPE( int mount, (char *_spec, char *_name, int _flag, + char *type, char *args) ); _PROTOTYPE( long ptrace, (int _req, pid_t _pid, long _addr, long _data) ); _PROTOTYPE( char *sbrk, (int _incr) ); _PROTOTYPE( int sync, (void) ); diff --git a/lib/posix/_mount.c b/lib/posix/_mount.c index 5d38b471e..8d7adda29 100755 --- a/lib/posix/_mount.c +++ b/lib/posix/_mount.c @@ -12,8 +12,8 @@ #include #define OK 0 -#define MFSNAME "mfs" -#define MFSPATH "/sbin/" +#define FSPATH "/sbin/" +#define FSDEFAULT "mfs" PRIVATE int rs_down(char *label) { @@ -21,7 +21,7 @@ PRIVATE int rs_down(char *label) message m; if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd)) return -1; - sprintf(cmd, _PATH_SERVICE " down %s", label); + sprintf(cmd, _PATH_SERVICE " down '%s'", label); return system(cmd); } @@ -34,39 +34,68 @@ PRIVATE char *makelabel(_CONST char *special) dev = strrchr(special, '/'); if(dev) dev++; else dev = special; - if(strlen(dev)+strlen(MFSNAME)+3 >= sizeof(label)) + if(strchr(dev, '\'') != NULL) { + errno = EINVAL; + return NULL; + } + if(strlen(dev)+4 >= sizeof(label)) { + errno = E2BIG; return NULL; - sprintf(label, MFSNAME "_%s", dev); + } + sprintf(label, "fs_%s", dev); return label; } -PUBLIC int mount(special, name, rwflag) -char *name, *special; +PUBLIC int mount(special, name, rwflag, type, args) +char *name, *special, *type, *args; int rwflag; { int r; message m; struct rs_start rs_start; + struct stat statbuf; char *label; + char path[60]; char cmd[200]; FILE *pipe; int ep; - /* Make MFS process label for RS from special name. */ + /* Default values. */ + if (type == NULL) type = FSDEFAULT; + if (args == NULL) args = ""; + + /* Make FS process label for RS from special name. */ if(!(label=makelabel(special))) { + return -1; + } + + /* See if the given type is even remotely valid. */ + if(strlen(FSPATH)+strlen(type) >= sizeof(path)) { + errno = E2BIG; + return -1; + } + strcpy(path, FSPATH); + strcat(path, type); + if(stat(path, &statbuf) != 0) { + errno = EINVAL; + return -1; + } + + /* Sanity check on user input. */ + if(strchr(args, '\'')) { + errno = EINVAL; + return -1; + } + + if(strlen(_PATH_SERVICE)+strlen(path)+strlen(label)+ + strlen(_PATH_DRIVERS_CONF)+strlen(args)+50 >= sizeof(cmd)) { errno = E2BIG; return -1; } - if(strlen(_PATH_SERVICE)+strlen(MFSPATH)+strlen(MFSNAME)+ - strlen(label)+50 >= sizeof(cmd)) { - errno = E2BIG; - return -1; - } - - sprintf(cmd, _PATH_SERVICE " up " MFSPATH MFSNAME - " -label \"%s\" -config " _PATH_DRIVERS_CONF " -printep yes", - label); + sprintf(cmd, _PATH_SERVICE " up %s -label '%s' -config " _PATH_DRIVERS_CONF + " -args '%s%s' -printep yes", + path, label, args[0] ? "-o " : "", args); if(!(pipe = popen(cmd, "r"))) { fprintf(stderr, "mount: couldn't run %s\n", cmd); @@ -108,7 +137,6 @@ _CONST char *name; /* Make MFS process label for RS from special name. */ if(!(label=makelabel(name))) { - errno = E2BIG; return -1; } diff --git a/man/man1/mount.1 b/man/man1/mount.1 index 7ef18fd15..1f63dca63 100644 --- a/man/man1/mount.1 +++ b/man/man1/mount.1 @@ -2,7 +2,7 @@ .SH NAME mount \- mount a file system .SH SYNOPSIS -\fBmount [\fB\-r\fR] \fIspecial \fIfile\fR +\fBmount [\fB\-r\fR] [\fB\-t \fItype\fR] [\fB\-o \fIoptions\fR] \fIspecial \fIfile\fR .br \fBmount [\fB\-s\fR] \fIswapfile\fR .br @@ -18,6 +18,8 @@ mount \- mount a file system .. .SH OPTIONS .FL "\-r" "File system is mounted read-only" +.FL "\-t" "File system type" +.FL "\-o" "Options passed to FS server" .FL "\-s" "Mount swap space" .SH EXAMPLES .EX "mount /dev/fd1 /user" "Mount diskette 1 on \fI/user\fP" @@ -31,6 +33,14 @@ after the mount. When the file system is no longer needed, it must be unmounted before being removed from the drive. .PP +The +.B \-t +parameter may be used to mount a file system of a type other than the default. +The +.B \-o +flag may be used to pass options to the file system server. +The interpretation of these options is up to the server. +.PP With the .B \-s flag a device or file is mounted as swap space. diff --git a/man/man2/mount.2 b/man/man2/mount.2 index d2711355f..fa7780823 100644 --- a/man/man2/mount.2 +++ b/man/man2/mount.2 @@ -7,7 +7,7 @@ mount, umount \- mount or umount a file system #include #include -int mount(char *\fIspecial\fP, char *\fIname\fP, int \fIflag\fP) +int mount(char *\fIspecial\fP, char *\fIname\fP, int \fIflag\fP, char *\fItype\fP, char *\fIargs\fP) int umount(char *\fIname\fP) .fi .ft P @@ -34,6 +34,13 @@ mounts a normal file or directory is used for which must be seen as the root of a virtual device. .I Flag is 0 for a read-write mount, 1 for read-only. +.I Type +is the type of the file system (e.g. "mfs"), used to pick a file system server. +If this parameter is NULL, the default type is used. +.I Args +is a string with arguments passed to the file system server. +Their interpretation is up to the server. +This parameter may be NULL as well. .PP .B Umount() removes the connection between a device and a mount point,