diff options
Diffstat (limited to 'sbin/newfs/mfs.c')
| -rw-r--r-- | sbin/newfs/mfs.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/sbin/newfs/mfs.c b/sbin/newfs/mfs.c new file mode 100644 index 000000000000..ce265f6fcf9b --- /dev/null +++ b/sbin/newfs/mfs.c @@ -0,0 +1,128 @@ +#ifdef MFS + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/signal.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/mount.h> + + + +static void +sighandler() +{ + /* + * kernel notifies us that the FS has been mounted successfully. + */ + exit(0); +} + + +void +mfs_mount(addr, len, name, dir, flags) +caddr_t addr; +unsigned long len; +char *name, *dir; +int flags; +{ + struct mfs_args margs; + char nmbuf[16]; + int pfeife[2]; + char buf[1024]; + int red; + + + + signal(SIGUSR1, sighandler); + if (pipe(pfeife) == -1) + fatal("cannot create pipe: %s", strerror(errno)); + switch (fork()) { + case -1: + fatal("cannot fork: %s", strerror(errno)); + case 0: + /* + * child: disassociate from controlling terminal, + * and mount the filesystem. + */ + dup2(pfeife[1], 2); + close(0); + close(1); + if (pfeife[0] != 2) close(pfeife[0]); + if (pfeife[1] != 2) close(pfeife[1]); + setsid(); + (void)chdir("/"); + if (name == 0) { + sprintf(nmbuf, "MFS:%d", getpid()); + name = nmbuf; + } + margs.name = name; + margs.base = addr; + margs.size = len; + margs.flags = MFSMNT_SIGPPID; + if (mount(MOUNT_MFS, dir, flags, &margs) == -1) + fatal("mounting MFS: %s", strerror(errno)); + default: + /* + * parent; if the mount system call fails, the + * child will write error messages to the pipe. + * We duplicate those messages to our stdout. + * If the mount succeedet, we will receive a SIGUSR1 + * (and exit with status 0). + */ + close(pfeife[1]); + while ((red = read(pfeife[0], buf, sizeof(buf))) > 0) + write(2, buf, red); + exit(1); + } + /* NOTREACHED */ +} + + +caddr_t +mfs_malloc(size) +unsigned long size; +{ + caddr_t addr; + + addr = mmap(0, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0); + if (addr == (caddr_t)-1) + fatal("cannot allocate memory: %s", strerror(errno)); + return(addr); +} + +void +mfs_mountfile(file, dir, flags) +char *file, *dir; +int flags; +{ + caddr_t addr; + int fd; + struct stat st; + + + fd = open(file, O_RDWR | O_EXLOCK); + if ((fd == -1) || (fstat(fd, &st) == -1)) + fatal("%s: %s", file, strerror(errno)); + addr = mmap(0, st.st_size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + if (addr == (caddr_t) -1) + fatal("cannot mmap file: %s", strerror(errno)); + mfs_mount(addr, st.st_size, file, dir, flags); +} + +#else +caddr_t +mfs_malloc() +{ + fatal("compiled without MFS support"); + return(0); +} +void mfs_mount() {} +void mfs_mountfile() {mfs_malloc();} +#endif |
