--- /dev/null
+#!/bin/bash
+
+INITRD_SIZE=12
+INITRD_FILE=dragonfly.mfs
+
+rm -f ${INITRD_FILE}
+rm -f ${INITRD_FILE}.xz
+
+VN_DEV=$(vnconfig -c -S ${INITRD_SIZE}m -Z -T vn ${INITRD_FILE})
+newfs -i 131072 -m 0 /dev/${VN_DEV}s0
+mount_ufs /dev/${VN_DEV}s0 /mnt
+
+cp -a sbin /mnt/
+chmod -R 777 /mnt/sbin
+
+mkdir /mnt/dev
+mkdir /mnt/new_root
+mkdir /mnt/tmp
+
+dd if=/dev/zero of=./data bs=1M count=8
+
+cat ./dmtable ./data ./dmtable > /mnt/dmtable
+
+umount /mnt
+
+rm -f ./data
+
+xz ${INITRD_FILE}
+
+vnconfig -u ${VN_DEV}
--- /dev/null
+#!/bin/sh
+
+rm -f init
+
+gcc -DMOUNT_NOMAIN -Os -static *.c -I. -lutil -lkiconv -o init
+
+strip --strip-all init
+
+if [ -e init ]; then
+ echo -e "\n========= SUCCESS ==============\n"
+else
+ echo -e "\n========= FAILED ==============\n"
+fi
--- /dev/null
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley
+ * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
+ * Support code is derived from software contributed to Berkeley
+ * by Atsushi Murai (amurai@spec.co.jp).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95
+ *
+ * @(#) Copyright (c) 1992, 1993, 1994 The Regents of the University of California. All rights reserved.
+ * @(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95
+ * $FreeBSD: src/sbin/mount_cd9660/mount_cd9660.c,v 1.15.2.3 2001/03/14 12:05:01 bp Exp $
+ */
+
+#include <sys/cdio.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/iconv.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <vfs/isofs/cd9660/cd9660_mount.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mntopts.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static struct mntopt mopts[] = {
+ MOPT_STDOPTS,
+ MOPT_UPDATE,
+ { "extatt", 0, ISOFSMNT_EXTATT, 1 },
+ { "gens", 0, ISOFSMNT_GENS, 1 },
+ { "rrip", 1, ISOFSMNT_NORRIP, 1 },
+ { "joliet", 1, ISOFSMNT_NOJOLIET, 1 },
+ { "strictjoliet", 1, ISOFSMNT_BROKENJOLIET, 1 },
+ MOPT_NULL
+};
+
+static int get_ssector(const char *dev);
+static void usage(void);
+int set_charset(struct iso_args *args, const char *cs_local, const char *cs_disk);
+
+int
+mount_cd9660(char *dev, char *dir)
+{
+ struct iso_args args;
+ int ch, mntflags, opts;
+ char mntpath[MAXPATHLEN];
+ struct vfsconf vfc;
+ int error, verbose;
+ const char *quirk;
+ char *cs_local = NULL;
+
+ mntflags = opts = verbose = 0;
+ memset(&args, 0, sizeof args);
+ args.ssector = 0;
+
+ /*
+ * Resolve the mountpoint with realpath(3) and remove unnecessary
+ * slashes from the devicename if there are any.
+ */
+ checkpath(dir, mntpath);
+ rmslashes(dev, dev);
+
+#define DEFAULT_ROOTUID -2
+ /*
+ * ISO 9660 filesystems are not writeable.
+ */
+ mntflags |= MNT_RDONLY;
+ args.export.ex_flags = MNT_EXRDONLY;
+ args.fspec = dev;
+ args.export.ex_root = DEFAULT_ROOTUID;
+ args.flags = opts;
+
+ if (args.ssector == -1) {
+ /*
+ * The start of the session has not been specified on
+ * the command line. If we can successfully read the
+ * TOC of a CD-ROM, use the last data track we find.
+ * Otherwise, just use 0, in order to mount the very
+ * first session. This is compatible with the
+ * historic behaviour of mount_cd9660(8). If the user
+ * has specified -s <ssector> above, we don't get here
+ * and leave the user's will.
+ */
+ if ((args.ssector = get_ssector(dev)) == -1) {
+ if (verbose)
+ printf("could not determine starting sector, "
+ "using very first session\n");
+ args.ssector = 0;
+ } else if (verbose)
+ printf("using starting sector %d\n", args.ssector);
+ }
+
+ error = getvfsbyname("cd9660", &vfc);
+ if (error && vfsisloadable("cd9660")) {
+ if (vfsload("cd9660"))
+ err(EX_OSERR, "vfsload(cd9660)");
+ endvfsent(); /* flush cache */
+ error = getvfsbyname("cd9660", &vfc);
+ }
+ if (error)
+ errx(1, "cd9660 filesystem is not available");
+
+ if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0)
+ err(1, "%s", args.fspec);
+
+ return 0;
+}
+
+int
+set_charset(struct iso_args *args, const char *cs_local, const char *cs_disk)
+{
+ int error;
+ if (modfind("cd9660_iconv") < 0) {
+ if (kldload("cd9660_iconv") < 0 || modfind("cd9660_iconv") < 0)
+ {
+ warnx("cannot find or load \"cd9660_iconv\" kernel module");
+ return (-1);
+ }
+ }
+ snprintf(args->cs_local, ICONV_CSNMAXLEN, "%s", cs_local);
+ error = kiconv_add_xlat16_cspairs(ENCODING_UNICODE, cs_local);
+ if (error)
+ return (-1);
+ if (!cs_disk)
+ cs_disk = strdup(ENCODING_UNICODE);
+ snprintf(args->cs_disk, ICONV_CSNMAXLEN, "%s", cs_disk);
+ error = kiconv_add_xlat16_cspairs(cs_disk, cs_local);
+ if (error)
+ return (-1);
+ return (0);
+}
+
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: mount_cd9660 [-begjrv] [-C charset] [-o options] [-s startsector] special node\n");
+ exit(EX_USAGE);
+}
+
+static int
+get_ssector(const char *dev)
+{
+ struct ioc_toc_header h;
+ struct ioc_read_toc_entry t;
+ struct cd_toc_entry toc_buffer[100];
+ int fd, ntocentries, i;
+
+ if ((fd = open(dev, O_RDONLY)) == -1)
+ return -1;
+ if (ioctl(fd, CDIOREADTOCHEADER, &h) == -1) {
+ close(fd);
+ return -1;
+ }
+
+ ntocentries = h.ending_track - h.starting_track + 1;
+ if (ntocentries > 100) {
+ /* unreasonable, only 100 allowed */
+ close(fd);
+ return -1;
+ }
+ t.address_format = CD_LBA_FORMAT;
+ t.starting_track = 0;
+ t.data_len = ntocentries * sizeof(struct cd_toc_entry);
+ t.data = toc_buffer;
+
+ if (ioctl(fd, CDIOREADTOCENTRYS, (char *) &t) == -1) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ for (i = ntocentries - 1; i >= 0; i--)
+ if ((toc_buffer[i].control & 4) != 0)
+ /* found a data track */
+ break;
+ if (i < 0)
+ return -1;
+
+ return ntohl(toc_buffer[i].addr.lba);
+}
--- /dev/null
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Copyright (c) 1992, 1993, 1994 The Regents of the University of California. All rights reserved.
+ * @(#)mount_null.c 8.6 (Berkeley) 4/26/95
+ * $FreeBSD: src/sbin/mount_null/mount_null.c,v 1.13 1999/10/09 11:54:11 phk Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <vfs/nullfs/null.h>
+
+#include <err.h>
+#include <mntopts.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static struct mntopt mopts[] = {
+ MOPT_STDOPTS,
+ MOPT_UPDATE,
+ MOPT_NULL
+};
+
+static void usage(void) __dead2;
+
+int
+mount_null(const char *src, const char *dst)
+{
+ struct null_args args;
+ int ch, mntflags;
+ char source[MAXPATHLEN];
+ char target[MAXPATHLEN];
+ struct vfsconf vfc;
+ int error;
+
+ bzero(&args, sizeof(args));
+ mntflags = 0;
+
+ args.target = target;
+ checkpath(src, target);
+ checkpath(dst, source);
+
+ /*
+ * Mount points that did not use distinct paths (e.g. / on /mnt)
+ * used to be disallowed because mount linkages were stored in
+ * vnodes and would lead to endlessly recursive trees. DragonFly
+ * stores mount linkages in the namecache topology and does not
+ * have this problem, so paths no longer need to be distinct.
+ */
+
+ error = getvfsbyname("null", &vfc);
+ if (error && vfsisloadable("null")) {
+ if(vfsload("null"))
+ err(EX_OSERR, "vfsload(null)");
+ endvfsent();
+ error = getvfsbyname("null", &vfc);
+ }
+ if (error)
+ errx(EX_OSERR, "null/loopback filesystem is not available");
+
+ if (mount(vfc.vfc_name, source, mntflags, &args))
+ err(1, NULL);
+
+ return 0;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: mount_null [-o options] target_fs mount_point\n");
+ fprintf(stderr,
+ " mount_null -u [-o options] mount_point\n");
+ exit(1);
+}
--- /dev/null
+/* $NetBSD: mount_tmpfs.c,v 1.24 2008/08/05 20:57:45 pooka Exp $ */
+
+/*
+ * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
+ * 2005 program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <vfs/tmpfs/tmpfs_mount.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <grp.h>
+#include <mntopts.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <libutil.h>
+
+//#include "defs.h"
+#include "mount_tmpfs.h"
+
+/* --------------------------------------------------------------------- */
+
+#define MOPT_TMPFSOPTS \
+ { "gid=", 0, MNT_GID, 1}, \
+ { "uid=", 0, MNT_UID, 1}, \
+ { "mode=", 0, MNT_MODE, 1}, \
+ { "inodes=", 0, MNT_INODES, 1}, \
+ { "size=", 0, MNT_SIZE, 1}, \
+ { "maxfilesize=", 0, MNT_MAXFSIZE, 1}
+
+
+static const struct mntopt mopts[] = {
+ MOPT_STDOPTS,
+ MOPT_TMPFSOPTS,
+ MOPT_NULL
+};
+
+static int Cflag;
+
+/* --------------------------------------------------------------------- */
+
+static gid_t a_gid(char *);
+static uid_t a_uid(char *);
+static mode_t a_mask(char *);
+static int64_t a_number(char *s);
+static void usage(void) __dead2;
+
+/* --------------------------------------------------------------------- */
+
+void
+mount_tmpfs_parseargs(int argc, char *argv[],
+ struct tmpfs_mount_info *args, int *mntflags,
+ char *canon_dev, char *canon_dir)
+{
+ int gidset, modeset, uidset; /* Ought to be 'bool'. */
+ int ch;
+ gid_t gid;
+ uid_t uid;
+ mode_t mode;
+ struct stat sb;
+ int extend_flags = 0;
+ char *ptr, *delim;
+
+ /* Set default values for mount point arguments. */
+ memset(args, 0, sizeof(*args));
+ args->ta_version = TMPFS_ARGS_VERSION;
+ args->ta_size_max = 0;
+ args->ta_nodes_max = 0;
+ args->ta_maxfsize_max = 0;
+ *mntflags = 0;
+
+ gidset = 0; gid = 0;
+ uidset = 0; uid = 0;
+ modeset = 0; mode = 0;
+
+ optind = optreset = 1;
+ while ((ch = getopt(argc, argv, "Cf:g:m:n:o:s:u:")) != -1 ) {
+ switch (ch) {
+ case 'C':
+ Cflag = 1;
+ break;
+ case 'f':
+ args->ta_maxfsize_max = a_number(optarg);
+ break;
+
+ case 'g':
+ gid = a_gid(optarg);
+ gidset = 1;
+ break;
+
+ case 'm':
+ mode = a_mask(optarg);
+ modeset = 1;
+ break;
+
+ case 'n':
+ args->ta_nodes_max = a_number(optarg);
+ break;
+
+ case 'o':
+ getmntopts(optarg, mopts, mntflags, &extend_flags);
+ if (extend_flags & MNT_GID) {
+ ptr = strstr(optarg, "gid=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ gid = a_gid(ptr + 4);
+ *delim = ',';
+ } else
+ gid = a_gid(ptr + 4);
+ gidset = 1;
+ }
+ extend_flags ^= MNT_GID;
+ }
+ if (extend_flags & MNT_UID) {
+ ptr = strstr(optarg, "uid=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ uid = a_uid(ptr + 4);
+ *delim = ',';
+ } else
+ uid = a_uid(ptr + 4);
+ uidset = 1;
+ }
+ extend_flags ^= MNT_UID;
+ }
+ if (extend_flags & MNT_MODE) {
+ ptr = strstr(optarg, "mode=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ mode = a_mask(ptr + 5);
+ *delim = ',';
+ } else
+ mode = a_mask(ptr + 5);
+ modeset = 1;
+ }
+ extend_flags ^= MNT_MODE;
+ }
+ if (extend_flags & MNT_INODES) {
+ ptr = strstr(optarg, "inodes=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ args->ta_nodes_max = a_number(ptr + 7);
+ *delim = ',';
+ } else
+ args->ta_nodes_max = a_number(ptr + 7);
+ }
+ extend_flags ^= MNT_INODES;
+ }
+ if (extend_flags & MNT_SIZE) {
+ ptr = strstr(optarg, "size=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ args->ta_size_max = a_number(ptr + 5);
+ *delim = ',';
+ } else
+ args->ta_size_max = a_number(ptr + 5);
+ }
+ extend_flags ^= MNT_SIZE;
+ }
+ if (extend_flags & MNT_MAXFSIZE) {
+ ptr = strstr(optarg, "maxfilesize=");
+ if(ptr) {
+ delim = strstr(ptr, ",");
+ if (delim) {
+ *delim = '\0';
+ args->ta_maxfsize_max = a_number(ptr + 12);
+ *delim = ',';
+ } else
+ args->ta_maxfsize_max = a_number(ptr + 12);
+ }
+ extend_flags ^= MNT_MAXFSIZE;
+ }
+ break;
+
+ case 's':
+ args->ta_size_max = a_number(optarg);
+ break;
+
+ case 'u':
+ uid = a_uid(optarg);
+ uidset = 1;
+ break;
+
+ case '?':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+
+ strlcpy(canon_dev, argv[0], MAXPATHLEN);
+ strlcpy(canon_dir, argv[1], MAXPATHLEN);
+
+ if (stat(canon_dir, &sb) == -1)
+ err(EXIT_FAILURE, "cannot stat `%s'", canon_dir);
+
+ args->ta_root_uid = uidset ? uid : sb.st_uid;
+ args->ta_root_gid = gidset ? gid : sb.st_gid;
+ args->ta_root_mode = modeset ? mode : sb.st_mode;
+}
+
+/* --------------------------------------------------------------------- */
+
+static gid_t
+a_gid(char *s)
+{
+ struct group *gr;
+ char *gname;
+ gid_t gid;
+
+ if ((gr = getgrnam(s)) != NULL)
+ gid = gr->gr_gid;
+ else {
+ for (gname = s; *s && isdigit(*s); ++s);
+ if (!*s)
+ gid = atoi(gname);
+ else
+ errx(EX_NOUSER, "unknown group id: %s", gname);
+ }
+ return (gid);
+}
+
+static uid_t
+a_uid(char *s)
+{
+ struct passwd *pw;
+ char *uname;
+ uid_t uid;
+
+ if ((pw = getpwnam(s)) != NULL)
+ uid = pw->pw_uid;
+ else {
+ for (uname = s; *s && isdigit(*s); ++s);
+ if (!*s)
+ uid = atoi(uname);
+ else
+ errx(EX_NOUSER, "unknown user id: %s", uname);
+ }
+ return (uid);
+}
+
+static mode_t
+a_mask(char *s)
+{
+ int done, rv = 0;
+ char *ep;
+
+ done = 0;
+ if (*s >= '0' && *s <= '7') {
+ done = 1;
+ rv = strtol(s, &ep, 8);
+ }
+ if (!done || rv < 0 || *ep)
+ errx(EX_USAGE, "invalid file mode: %s", s);
+ return (rv);
+}
+
+static int64_t
+a_number(char *s)
+{
+ int64_t rv = 0;
+
+ if (dehumanize_number(s, &rv) < 0 || rv < 0)
+ errx(EX_USAGE, "bad number for option: %s", s);
+ return (rv);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s [-C] [-g group] [-m mode] [-n nodes] [-o options] [-s size]\n"
+ " [-u user] [-f maxfilesize] tmpfs mountpoint\n", getprogname());
+ exit(1);
+}
+
+/* --------------------------------------------------------------------- */
+
+int
+mount_tmpfs(int argc, char *argv[])
+{
+ struct tmpfs_mount_info args;
+ char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
+ int mntflags;
+ struct vfsconf vfc;
+ int error;
+ //fsnode_t copyroot = NULL;
+ //fsnode_t copyhlinks = NULL;
+
+ mount_tmpfs_parseargs(argc, argv, &args, &mntflags,
+ canon_dev, canon_dir);
+
+ error = getvfsbyname("tmpfs", &vfc);
+ if (error && vfsisloadable("tmpfs")) {
+ if(vfsload("tmpfs"))
+ err(EX_OSERR, "vfsload(%s)", "tmpfs");
+ endvfsent();
+ error = getvfsbyname("tmpfs", &vfc);
+ }
+ if (error)
+ errx(EX_OSERR, "%s filesystem not available", "tmpfs");
+
+ //if (Cflag)
+ // copyroot = FSCopy(©hlinks, canon_dir);
+
+ if (mount(vfc.vfc_name, canon_dir, mntflags, &args) == -1)
+ err(EXIT_FAILURE, "tmpfs on %s", canon_dir);
+
+ //if (Cflag)
+ // FSPaste(canon_dir, copyroot, copyhlinks);
+
+ return EXIT_SUCCESS;
+}
+
+#ifndef MOUNT_NOMAIN
+int
+main(int argc, char *argv[])
+{
+ setprogname(argv[0]);
+ return mount_tmpfs(argc, argv);
+}
+#endif
--- /dev/null
+/* $NetBSD: mount_tmpfs.h,v 1.1 2008/08/05 20:57:45 pooka Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SBIN_MOUNT_TMPFS_MOUNT_TMPFS_H_
+#define _SBIN_MOUNT_TMPFS_MOUNT_TMPFS_H_
+
+#include <vfs/tmpfs/tmpfs_mount.h>
+
+int mount_tmpfs(int, char **);
+void mount_tmpfs_parseargs(int, char **, struct tmpfs_mount_info *, int *,
+ char *, char *);
+
+#endif /* _SBIN_MOUNT_TMPFS_MOUNT_TMPFS_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved.
+ * @(#)init.c 8.1 (Berkeley) 7/15/93
+ * $FreeBSD: src/sbin/init/init.c,v 1.38.2.8 2001/10/22 11:27:32 des Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <ttyent.h>
+#include <unistd.h>
+#include <sys/reboot.h>
+#include <sys/mount.h>
+#include <err.h>
+
+#include <stdarg.h>
+#include <vtutil.h>
+
+int boot_verbose = 0;
+
+int prepare_dmtable(void);
+int mount_cd9660(char *dev, char *dir);
+int mount_null(const char *src, const char *dst);
+int mount_tmpfs(int argc, char *argv[]);
+
+static int setctty(const char *name)
+{
+ int fd;
+
+ revoke(name);
+ if ((fd = open(name, O_RDWR)) == -1) {
+ exit(1);
+ }
+
+ if (login_tty(fd) == -1) {
+ exit(1);
+ }
+
+ return fd;
+}
+
+static void ventoy_init(char **argv_orig)
+{
+ pid_t pid, wpid;
+ int status, error;
+ char arg0[MAXPATHLEN];
+ char arg1[MAXPATHLEN];
+ char arg2[MAXPATHLEN];
+ char *argv[8];
+ struct sigaction sa;
+
+ /* step1: mount tmpfs */
+ vdebug("[VTOY] step 1: mount tmpfs ...");
+ strcpy(arg0, "mount_tmpfs");
+ strcpy(arg1, "tmpfs");
+ strcpy(arg2, "/tmp");
+ argv[0] = arg0;
+ argv[1] = arg1;
+ argv[2] = arg2;
+ argv[3] = NULL;
+ error = mount_tmpfs(3, argv);
+ vdebug(" %d\n", error);
+
+ /* step 2: prepare dmtable */
+ vdebug("[VTOY] step 2: prepare device-mapper table...\n");
+ (void)prepare_dmtable();
+
+ /* step 3: create device mapper */
+ vdebug("[VTOY] step 3: create device-mapper ...\n");
+ if ((pid = fork()) == 0) {
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGTSTP, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+
+ argv[0] = "dmsetup";
+ argv[1] = "create";
+ argv[2] = "ventoy";
+ argv[3] = "/tmp/dmtable";
+ argv[4] = "--readonly";
+ argv[5] = NULL;
+
+ sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
+ execv("/sbin/dmsetup", __DECONST(char **, argv));
+ exit(1); /* force single user mode */
+ }
+
+ do {
+ wpid = waitpid(-1, &status, WUNTRACED);
+ } while (wpid != pid);
+
+ /* step 4: mount iso */
+ vdebug("[VTOY] step 4: mount device-mapper ...");
+ strcpy(arg0, "/dev/mapper/ventoy");
+ strcpy(arg1, "/new_root");
+ error = mount_cd9660(arg0, arg1);
+ vdebug(" %d\n", error);
+
+ /* step 5: mount devfs */
+ vdebug("[VTOY] step 5: mount devfs ...");
+ strcpy(arg0, "/dev");
+ strcpy(arg1, "/new_root/dev");
+ mount_null(arg0, arg1);
+ vdebug(" %d\n", error);
+
+ /* step 6: umount tmpfs */
+ error = unmount("/tmp", 0);
+ vdebug("[VTOY] step 6: unmount tmpfs %d\n", error);
+
+ /* step 7: swich_root */
+ vdebug("[VTOY] step 7: switch root ...\n");
+ error = chdir("/new_root");
+ if (error)
+ goto chroot_failed;
+
+ error = chroot_kernel("/new_root");
+ if (error)
+ goto chroot_failed;
+
+ error = chroot("/new_root");
+ if (error)
+ goto chroot_failed;
+
+ execv("/sbin/init", __DECONST(char **, argv_orig));
+
+ /* We failed to exec /sbin/init in the chroot, sleep forever */
+chroot_failed:
+ while(1) {
+ sleep(3);
+ };
+}
+
+int main(int argc __unused, char **argv)
+{
+ size_t varsize = sizeof(int);
+
+ /* Dispose of random users. */
+ if (getuid() != 0)
+ errx(1, "%s", strerror(EPERM));
+
+ /* Init is not allowed to die, it would make the kernel panic */
+ signal(SIGTERM, SIG_IGN);
+
+ setctty(_PATH_CONSOLE);
+
+ sysctlbyname("debug.bootverbose", &boot_verbose, &varsize, NULL, 0);
+
+ vdebug("======= Ventoy Init Start ========\n");
+
+ ventoy_init(argv);
+ return 1;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley
+ * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
+ * Support code is derived from software contributed to Berkeley
+ * by Atsushi Murai (amurai@spec.co.jp).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cd9660_mount.h 8.1 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/isofs/cd9660/cd9660_mount.h,v 1.3.2.2 2001/03/14 12:03:50 bp Exp $
+ */
+#include <sys/iconv.h>
+/*
+ * Arguments to mount ISO 9660 filesystems.
+ */
+struct iso_args {
+ char *fspec; /* block special device to mount */
+ struct export_args export; /* network export info */
+ int flags; /* mounting flags, see below */
+ int ssector; /* starting sector, 0 for 1st session */
+ char cs_disk[ICONV_CSNMAXLEN]; /* disk charset for Joliet cs conversion */
+ char cs_local[ICONV_CSNMAXLEN]; /* local charset for Joliet cs conversion */
+};
+#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
+#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
+#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
+#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet Ext.*/
+#define ISOFSMNT_BROKENJOLIET 0x00000010 /* allow broken Joliet disks */
+#define ISOFSMNT_KICONV 0x00000020 /* Use libiconv to convert chars */
--- /dev/null
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)null.h 8.3 (Berkeley) 8/20/94
+ *
+ * $FreeBSD: src/sys/miscfs/nullfs/null.h,v 1.11.2.3 2001/06/26 04:20:09 bp Exp $
+ * $DragonFly: src/sys/vfs/nullfs/null.h,v 1.10 2008/09/18 16:08:32 dillon Exp $
+ */
+
+struct null_args {
+ char *target; /* Target of loopback */
+ struct export_args export; /* Network export information */
+};
+
+#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
+
+struct null_mount {
+ struct mount *nullm_vfs;
+ struct vnode *nullm_rootvp; /* Reference to root null_node */
+ struct netexport export;
+};
+
+#endif
+
+#ifdef _KERNEL
+#define MOUNTTONULLMOUNT(mp) ((struct null_mount *)((mp)->mnt_data))
+
+#ifdef NULLFS_DEBUG
+#define NULLFSDEBUG(format, args...) kprintf(format ,## args)
+#else
+#define NULLFSDEBUG(format, args...)
+#endif /* NULLFS_DEBUG */
+
+int nullfs_export(struct mount *mp, int op,
+ const struct export_args *export);
+
+#endif /* _KERNEL */
--- /dev/null
+/* $NetBSD: tmpfs_args.h,v 1.3 2008/07/29 09:10:09 pooka Exp $ */
+/* $DragonFly: tmpfs_mount.h,v 1.3 2017/10/29 09:10:09 markuspf Exp $ */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
+ * 2005 program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VFS_TMPFS_TMPFS_MOUNT_H_
+#define VFS_TMPFS_TMPFS_MOUNT_H_
+
+/*
+ * This structure is used to communicate mount parameters between userland
+ * and kernel space.
+ */
+#define TMPFS_ARGS_VERSION 2
+struct tmpfs_mount_info {
+ int ta_version;
+
+ /* Size counters. */
+ ino_t ta_nodes_max;
+ off_t ta_size_max;
+ size_t ta_maxfsize_max;
+
+ /* Root node attributes. */
+ uid_t ta_root_uid;
+ gid_t ta_root_gid;
+ mode_t ta_root_mode;
+};
+
+#define MNT_GID 0x00000001
+#define MNT_UID 0x00000002
+#define MNT_MODE 0x00000004
+#define MNT_INODES 0x00000008
+#define MNT_SIZE 0x00000010
+#define MNT_MAXFSIZE 0x00000020
+
+#endif /* VFS_TMPFS_TMPFS_MOUNT_H_ */
--- /dev/null
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+extern int boot_verbose;
+#define vdebug(fmt, ...) if (boot_verbose) { printf(fmt, ##__VA_ARGS__); usleep(500000); }
+#define verror printf
+
+
+#pragma pack(4)
+typedef struct ventoy_image_desc
+{
+ uint64_t disk_size;
+ uint64_t part1_size;
+ uint8_t disk_uuid[16];
+ uint8_t disk_signature[4];
+ uint32_t img_chunk_count;
+ /* ventoy_img_chunk list */
+}ventoy_image_desc;
+
+typedef struct ventoy_img_chunk
+{
+ uint32_t img_start_sector; // sector size: 2KB
+ uint32_t img_end_sector; // included
+
+ uint64_t disk_start_sector; // in disk_sector_size
+ uint64_t disk_end_sector; // included
+}ventoy_img_chunk;
+#pragma pack()
+
+
+#endif
+
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved.
+ * @(#)init.c 8.1 (Berkeley) 7/15/93
+ * $FreeBSD: src/sbin/init/init.c,v 1.38.2.8 2001/10/22 11:27:32 des Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fts.h>
+#include <grp.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <vtutil.h>
+
+static int find_disk_by_signature(uint8_t *uuid, uint8_t *sig, uint64_t size, int *count, char *name)
+{
+ int fd;
+ int len;
+ int cnt = 0;
+ FTS *ftsp;
+ FTSENT *p;
+ uint8_t mbr[512];
+ char devname[MAXPATHLEN];
+ static char dev[] = "/dev", *devav[] = {dev, NULL};
+
+ vdebug("[VTOY] find_disk_by_signature %llu\n", size);
+
+ ftsp = fts_open(devav, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
+ while ((p = fts_read(ftsp)) != NULL)
+ {
+ if (p->fts_level == 1 && p->fts_statp && p->fts_name && p->fts_statp->st_size == size)
+ {
+ sprintf(devname, "/dev/%s", p->fts_name);
+
+ fd = open(devname, O_RDONLY);
+ if (fd < 0)
+ {
+ continue;
+ }
+
+ memset(mbr, 0, 512);
+ read(fd, mbr, 512);
+ close(fd);
+
+ if (memcmp(mbr + 0x180, uuid, 16) == 0 && memcmp(mbr + 0x1B8, sig, 4) == 0)
+ {
+ cnt++;
+ strcpy(name, p->fts_name);
+ break;
+ }
+ }
+ }
+
+ *count = cnt;
+ fts_close(ftsp);
+
+ return 0;
+}
+
+static int find_disk_by_size(uint64_t size, const char *prefix, int *count, char *name)
+{
+ int len;
+ int cnt = 0;
+ FTS *ftsp;
+ FTSENT *p;
+ static char dev[] = "/dev", *devav[] = {dev, NULL};
+
+ if (prefix)
+ {
+ len = strlen(prefix);
+ }
+
+ name[0] = 0;
+ ftsp = fts_open(devav, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
+ while ((p = fts_read(ftsp)) != NULL)
+ {
+ if (p->fts_level == 1 && p->fts_statp && p->fts_name && p->fts_statp->st_size == size)
+ {
+ if (prefix)
+ {
+ if (strncmp(p->fts_name, prefix, len) == 0)
+ {
+ cnt++;
+ if (name[0] == 0)
+ strcpy(name, p->fts_name);
+ }
+ }
+ else
+ {
+ cnt++;
+ if (name[0] == 0)
+ strcpy(name, p->fts_name);
+ }
+ }
+ }
+
+ *count = cnt;
+ fts_close(ftsp);
+
+ return 0;
+}
+
+int prepare_dmtable(void)
+{
+ int count = 0;
+ uint32_t i = 0;
+ uint32_t sector_start = 0;
+ uint32_t disk_sector_num = 0;
+ FILE *fIn, *fOut;
+ char disk[MAXPATHLEN];
+ char prefix[MAXPATHLEN];
+ ventoy_image_desc desc;
+ ventoy_img_chunk chunk;
+
+ fIn = fopen("/dmtable", "rb");
+ if (!fIn)
+ {
+ printf("Failed to open dmtable\n");
+ return 1;
+ }
+
+ fOut = fopen("/tmp/dmtable", "w+");
+ if (!fOut)
+ {
+ printf("Failed to create /tmp/dmtable %d\n", errno);
+ fclose(fIn);
+ return 1;
+ }
+
+ fread(&desc, 1, sizeof(desc), fIn);
+
+ vdebug("[VTOY] disksize:%lu part1size:%lu chunkcount:%u\n", desc.disk_size, desc.part1_size, desc.img_chunk_count);
+
+ find_disk_by_size(desc.part1_size, NULL, &count, disk);
+ vdebug("[VTOY] find disk by part1 size: %d %s\n", count, disk);
+
+ if (count == 0)
+ {
+ goto end;
+ }
+ else if (count > 1)
+ {
+ find_disk_by_signature(desc.disk_uuid, desc.disk_signature, desc.disk_size, &count, prefix);
+ vdebug("[VTOY] find disk by signature: %d %s\n", count, prefix);
+
+ if (count != 1)
+ {
+ printf("[VTOY] Failed to find disk by signature\n");
+ goto end;
+ }
+
+ find_disk_by_size(desc.part1_size, prefix, &count, disk);
+ vdebug("[VTOY] find disk by part1 size with prefix %s : %d %s\n", prefix, count, disk);
+ }
+
+ for (i = 0; i < desc.img_chunk_count; i++)
+ {
+ fread(&chunk, 1, sizeof(chunk), fIn);
+
+ sector_start = chunk.img_start_sector;
+ disk_sector_num = (uint32_t)(chunk.disk_end_sector + 1 - chunk.disk_start_sector);
+
+ fprintf(fOut, "%u %u linear /dev/%s %llu\n",
+ (sector_start << 2), disk_sector_num,
+ disk, (unsigned long long)chunk.disk_start_sector - 2048);
+
+ vdebug("%u %u linear /dev/%s %llu\n",
+ (sector_start << 2), disk_sector_num,
+ disk, (unsigned long long)chunk.disk_start_sector - 2048);
+ }
+
+end:
+ fclose(fIn);
+ fclose(fOut);
+ return 0;
+}
+