minix/lib/libc/sys-minix/mount.c
Ben Gras 2fe8fb192f Full switch to clang/ELF. Drop ack. Simplify.
There is important information about booting non-ack images in
docs/UPDATING. ack/aout-format images can't be built any more, and
booting clang/ELF-format ones is a little different. Updating to the
new boot monitor is recommended.

Changes in this commit:

	. drop boot monitor -> allowing dropping ack support
	. facility to copy ELF boot files to /boot so that old boot monitor
	  can still boot fairly easily, see UPDATING
	. no more ack-format libraries -> single-case libraries
	. some cleanup of OBJECT_FMT, COMPILER_TYPE, etc cases
	. drop several ack toolchain commands, but not all support
	  commands (e.g. aal is gone but acksize is not yet).
	. a few libc files moved to netbsd libc dir
	. new /bin/date as minix date used code in libc/
	. test compile fix
	. harmonize includes
	. /usr/lib is no longer special: without ack, /usr/lib plays no
	  kind of special bootstrapping role any more and bootstrapping
	  is done exclusively through packages, so releases depend even
	  less on the state of the machine making them now.
	. rename nbsd_lib* to lib*
	. reduce mtree
2012-02-14 14:52:02 +01:00

195 lines
4.3 KiB
C

#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <string.h>
#include <sys/mount.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <minix/syslib.h>
#include <minix/rs.h>
#include <paths.h>
#include <unistd.h>
#define OK 0
#ifdef __weak_alias
__weak_alias(mount, _mount)
__weak_alias(umount, _umount)
__weak_alias(umount2, _umount2)
#endif
#define FSDEFAULT "mfs"
static char fspath[] = "/sbin/:/usr/pkg/bin/"; /* Must include trailing '/' */
PRIVATE int rs_down(char *label)
{
char cmd[200];
if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd))
return -1;
sprintf(cmd, _PATH_SERVICE " down '%s'", label);
return system(cmd);
}
PUBLIC int mount(special, name, mountflags, type, args)
char *name, *special, *type, *args;
int mountflags;
{
int r;
message m;
struct stat statbuf;
char label[16];
char path[PATH_MAX];
char cmd[200];
char *p;
int reuse = 0;
int use_existing = 0;
/* Default values. */
if (type == NULL) type = __UNCONST(FSDEFAULT);
if (args == NULL) args = __UNCONST("");
reuse = 0;
memset(path, '\0', sizeof(path));
/* Check mount flags */
if(mountflags & MS_REUSE) {
reuse = 1;
mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
}
if(mountflags & MS_EXISTING) {
use_existing = 1;
mountflags &= ~MS_EXISTING; /* Temporary: turn off to not confuse VFS */
}
/* Make a label for the file system process. This label must be unique and
* may currently not exceed 16 characters including terminating null. For
* requests with an associated block device, we use the last path component
* name of the block special file (truncated to 12 characters, which is
* hopefully enough). For requests with no associated block device, we use
* the device number and inode of the mount point, in hexadecimal form.
*/
if (!use_existing) {
if (special) {
p = strrchr(special, '/');
p = p ? p + 1 : special;
if (strchr(p, '\'')) {
errno = EINVAL;
return -1;
}
sprintf(label, "fs_%.12s", p);
} else {
if (stat(name, &statbuf) < 0) return -1;
sprintf(label, "fs_%04x%llx", statbuf.st_dev, statbuf.st_ino);
}
} else {
/* label to long? */
if (strlen(type) < 16) {
sprintf(label, "%s", type);
} else {
errno = ENOMEM;
return -1;
}
}
/* Tell VFS that we are passing in a 16-byte label. */
mountflags |= MS_LABEL16;
/* Sanity check on user input. */
if(strchr(args, '\'')) {
errno = EINVAL;
return -1;
}
/* start the fs-server if not using existing one */
if (!use_existing) {
/* See if the given type is even remotely valid. */
char *testpath;
testpath = strtok(fspath, ":");
do {
if (strlen(testpath) + strlen(type) >= sizeof(path)) {
errno = E2BIG;
return(-1);
}
strcpy(path, testpath);
strcat(path, type);
if (access(path, F_OK) == 0) break;
} while ((testpath = strtok(NULL, ":")) != NULL);
if (testpath == NULL) {
/* We were not able to find type somewhere in "fspath" */
errno = EINVAL;
return(-1);
}
if (strlen(_PATH_SERVICE) + strlen(path) + strlen(label) +
strlen(args) + 50 >= sizeof(cmd)) {
errno = E2BIG;
return -1;
}
sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -args '%s %s %s%s'",
reuse ? "-r ": "", path, label, special, name,
args[0] ? "-o " : "", args);
if ((r = system(cmd)) != 0) {
fprintf(stderr, "mount: couldn't run %s\n", cmd);
errno = r;
return -1;
}
}
/* Now perform mount(). */
m.m1_i1 = special ? strlen(special) + 1 : 0;
m.m1_i2 = strlen(name) + 1;
m.m1_i3 = mountflags;
m.m1_p1 = special;
m.m1_p2 = name;
m.m1_p3 = label;
r = _syscall(VFS_PROC_NR, MOUNT, &m);
if (r != OK && !use_existing) {
/* If mount() failed, tell RS to shutdown FS process.
* No error check - won't do anything with this error anyway.
*/
rs_down(label);
}
return r;
}
PUBLIC int umount(name)
_CONST char *name;
{
return umount2(name, 0);
}
PUBLIC int umount2(name, flags)
_CONST char *name;
int flags;
{
message m;
int r;
_loadname(name, &m);
r = _syscall(VFS_PROC_NR, UMOUNT, &m);
/* don't shut down the driver when exist flag is set */
if (!(flags & MS_EXISTING)) {
if (r == OK) {
/* VFS returns the label of the unmounted file system in the reply.
* As of writing, the size of the m3_ca1 field is 16 bytes.
*/
rs_down(m.m3_ca1);
}
}
return r;
}