diff --git a/contrib/mfsbsd/.gitignore b/contrib/mfsbsd/.gitignore new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/.gitignore @@ -0,0 +1,18 @@ +*.gz +*.iso +*.img +mini/*.gz +mini/*.iso +mini/*.img +tmp/ +mini/tmp/ +packages/*.txz +mini/packages/*.txz +tools/pkg-static +tools/roothack/.depend +tools/roothack/.depend.roothack.o +tools/roothack/roothack +tools/roothack/roothack.debug +tools/roothack/roothack.full +tools/roothack/roothack.o +work diff --git a/contrib/mfsbsd/BUILD.md b/contrib/mfsbsd/BUILD.md new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/BUILD.md @@ -0,0 +1,84 @@ +# mfsBSD building instructions + +Copyright (c) 2019 Martin Matuska + +## Configuration +Read hints in the sample configuration files in the conf/ directory, copy +these files to files without .sample ending and make modifications to suit +your needs. + +The default root password is "mfsroot". You can pick a difrerent password +with the ROOTPW or ROOTPW_HASH make variables. + +## Additional packages and files +If you want any packages installed, copy the .tbz files that should be +automatically installed into the packages/ directory. + +Add any additional files into the customfiles/ directory. These will be copied +recursively into the root of the boot image. + +WARNING: +Your image should not exceed MFSROOT_MAXSIZE in total. +Please adjust the variable for larger images. + +## Distribution or custom world and kernel +You may choose to build from a FreeBSD distribution (e.g. CDROM), or by +using make buildworld / buildkernel from your own world and kernel +configuration. + +To use a distribution (e.g. FreeBSD cdrom), you need access to it +(e.g. a mounted FreeBSD ISO via mdconfig) and use BASE=/path/to/distribution + +To use your own but already built world and kernel, use CUSTOM=1 +If you want this script to do make buildworld and make buildkernel for you, +use BUILDWORLD=1 and BUILDKERNEL=1 + +## Creating images + +You may create three types of output: disc image for use by dd(1), +ISO image or a simple .tar.gz file + +##Examples + +1. disc image + + ```bash + make BASE=/cdrom/usr/freebsd-dist + make BASE=/cdrom/10.2-RELEASE + make CUSTOM=1 BUILDWORLD=1 BUILDKERNEL=1 + ``` + +2. bootable ISO file: + + ```bash + make iso BASE=/cdrom/usr/freebsd-dist + make iso BASE=/cdrom/10.2-RELEASE + make iso CUSTOM=1 BUILDWORLD=1 BUILDKERNEL=1 + ``` + +3. .tar.gz file: + + ```bash + make tar BASE=/cdrom/usr/freebsd-dist + make tar BASE=/cdrom/10.2-RELEASE + make tar CUSTOM=1 BUILDWORLD=1 BUILDKERNEL=1 + ``` + +4. roothack edition: + + ```bash + make iso CUSTOM=1 BUILDWORLD=1 BUILDKERNEL=1 ROOTHACK=1 + ``` + +5. special edition (with FreeBSD distribution): + + ```bash + make iso BASE=/cdrom/11.0-RELEASE RELEASE=11.0-RELEASE ARCH=amd64 + ``` + +6. GCE-compatible .tar.gz file: + + ```bash + make gce BASE=/cdrom/11.0-RELEASE + make gce CUSTOM=1 BUILDWORLD=1 BUILDKERNEL=1 + ``` diff --git a/contrib/mfsbsd/INSTALL.md b/contrib/mfsbsd/INSTALL.md new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/INSTALL.md @@ -0,0 +1,39 @@ +# mfsBSD installation (deployment) instructions + +Copyright (c) 2019 Martin Matuska + +## Build +For customized build please see the [BUILD](./BUILD.md) file + +## Deploy + +### Scenario 1 +You have a linux server without console access and want to install +FreeBSD on this server. + +1. modify your configuration files (do this properly, or no ssh access) +2. create an image file (e.g. make BASE=/cdrom/usr/freebsd-dist) +3. write image with dd to the bootable harddrive of the linux server +4. reboot +5. ssh to your machine and enjoy :) + +### Scenario 2 +You want a rescue CD-ROM with a minimal FreeBSD installation that doesn't +need to remain in the tray after booting. + +1. modify your configuration files +2. create an iso image file (e.g. make iso BASE=/cdrom/usr/freebsd-dist) +3. burn ISO image onto a writable CD +4. boot from the CD and enjoy :) + +### Scenario 3 +You want a rescue partition on your FreeBSD system so you can re-partition +all harddrives remotely. + +1. modify your configuration files +2. create an .tar.gz file (e.g. make tar BASE=/cdrom/usr/freebsd-dist) +3. create your UFS partition with sysinstall or gpart (e.g. ada0p2) +4. create a filesystem on the partition (e.g. newfs /dev/ada0p2) +5. mount the partition and extract your .tar.gz file on it +6. configure a bootmanager (e.g. gpart bootcode -b /poot/pmbr -p /boot/gptboot -i 1 ada0) +7. boot from your rescue system and enjoy :) diff --git a/contrib/mfsbsd/LICENSE b/contrib/mfsbsd/LICENSE new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2018, Martin Matuska +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diff --git a/contrib/mfsbsd/Makefile b/contrib/mfsbsd/Makefile new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/Makefile @@ -0,0 +1,668 @@ +# $Id$ +# +# mfsBSD +# Copyright (c) 2019 Martin Matuska + +# +# User-defined variables +# +BASE?= /cdrom/usr/freebsd-dist +KERNCONF?= GENERIC +MFSROOT_FREE_INODES?= 10% +MFSROOT_FREE_BLOCKS?= 10% +MFSROOT_MAXSIZE?= 4700m +ROOTPW_HASH?= $$6$$051DdQA7fTvLymkY$$Z5f6snVFQJKugWmGi8y0motBNaKn9em0y2K0ZsJMku3v9gkiYh8M.OTIIie3RvHpzT6udumtZUtc0kXwJcCMR1 + +# If you want to build your own kernel and make you own world, you need to set +# -DCUSTOM or CUSTOM=1 +# +# To make buildworld use +# -DCUSTOM -DBUILDWORLD or CUSTOM=1 BUILDWORLD=1 +# +# To make buildkernel use +# -DCUSTOM -DBUILDKERNEL or CUSTOM=1 BUILDKERNEL=1 +# +# For all of this use +# -DCUSTOM -DBUILDWORLD -DBUILDKERNEL or CUSTOM=1 BUILDKERNEL=1 BUILDWORLD=1 +# + +# +# Paths +# +SRC_DIR?= /usr/src +CFGDIR?= conf +SCRIPTSDIR?= scripts +PACKAGESDIR?= packages +CUSTOMFILESDIR?= customfiles +CUSTOMSCRIPTSDIR?= customscripts +TOOLSDIR?= tools +PRUNELIST?= ${TOOLSDIR}/prunelist +KERN_EXCLUDE?= ${TOOLSDIR}/kern_exclude +PKG_STATIC?= /usr/local/sbin/pkg-static +# +# Program defaults +# +MKDIR?= /bin/mkdir -p +CHOWN?= /usr/sbin/chown +CAT?= /bin/cat +PWD?= /bin/pwd +TAR?= /usr/bin/tar +GTAR?= /usr/local/bin/gtar +CP?= /bin/cp +MV?= /bin/mv +RM?= /bin/rm +RMDIR?= /bin/rmdir +CHFLAGS?= /bin/chflags +GZIP?= /usr/bin/gzip +TOUCH?= /usr/bin/touch +INSTALL?= /usr/bin/install +LS?= /bin/ls +LN?= /bin/ln +FIND?= /usr/bin/find +PW?= /usr/sbin/pw +SED?= /usr/bin/sed +UNAME?= /usr/bin/uname +BZIP2?= /usr/bin/bzip2 +XZ?= /usr/bin/xz +MAKEFS?= /usr/sbin/makefs +SSHKEYGEN?= /usr/bin/ssh-keygen +SYSCTL?= /sbin/sysctl +PKG?= /usr/local/sbin/pkg +OPENSSL?= /usr/bin/openssl +CUT?= /usr/bin/cut +# +WRKDIR?= ${.CURDIR}/work +# +BSDLABEL?= bsdlabel +# +DOFS?= ${TOOLSDIR}/doFS.sh +SCRIPTS?= mdinit mfsbsd interfaces packages +BOOTMODULES?= acpi ahci +.if defined(LOADER_4TH) +BOOTFILES?= defaults device.hints loader_4th *.rc *.4th +EFILOADER?= loader_4th.efi +.else +BOOTFILES?= defaults device.hints loader_lua lua +EFILOADER?= loader_lua.efi +.endif +MFSMODULES?= aesni crypto cryptodev ext2fs geom_eli geom_mirror geom_nop \ + ipmi ntfs nullfs opensolaris smbus snp tmpfs zfs +# Sometimes the kernel is compiled with a different destination. +KERNDIR?= kernel +# +XZ_FLAGS?= +# + +.if defined(V) +_v= +VERB=1 +.else +_v=@ +VERB= +.endif + +.if !defined(ARCH) +TARGET!= ${SYSCTL} -n hw.machine_arch +.else +TARGET= ${ARCH} +.endif + +.if !defined(RELEASE) +RELEASE!= ${UNAME} -r +.endif + +.if !defined(PKG_ABI) +PKG_ABI!= echo "FreeBSD:`${UNAME} -U | ${CUT} -c 1-2`:`${UNAME} -m`" +.endif + +.if !defined(SE) +IMAGE_PREFIX?= mfsbsd +.else +IMAGE_PREFIX?= mfsbsd-se +.endif + +IMAGE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.img +ISOIMAGE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.iso +TARFILE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.tar +GCEFILE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.tar.gz +_DISTDIR= ${WRKDIR}/dist/${RELEASE}-${TARGET} + +.if !defined(DEBUG) +EXCLUDE= --exclude *.symbols +.else +EXCLUDE= +.endif + +# Roothack stuff +.if !defined(NO_ROOTHACK) +. if defined(ROOTHACK_FILE) && exists(${ROOTHACK_FILE}) +ROOTHACK_PREBUILT=1 +. else +ROOTHACK_FILE= ${WRKDIR}/roothack/roothack +. endif +.endif + +# Check if we are installing FreeBSD 9 or higher +.if exists(${BASE}/base.txz) && exists(${BASE}/kernel.txz) +FREEBSD9?= yes +BASEFILE?= ${BASE}/base.txz +KERNELFILE?= ${BASE}/kernel.txz +.else +BASEFILE?= ${BASE}/base/base.?? +KERNELFILE?= ${BASE}/kernels/generic.?? +.endif + +.if defined(MAKEJOBS) +_MAKEJOBS= -j${MAKEJOBS} +.endif + +_ROOTDIR= ${WRKDIR}/mfs +_BOOTDIR= ${_ROOTDIR}/boot +.if !defined(NO_ROOTHACK) +_DESTDIR= ${_ROOTDIR}/rw +MFSROOT_FREE_INODES?=1% +MFSROOT_FREE_BLOCKS?=1% +.else +_DESTDIR= ${_ROOTDIR} +.endif + +.if !defined(SE) +# Environment for custom build +BUILDENV?= env \ + NO_FSCHG=1 \ + WITHOUT_CLANG=1 \ + WITHOUT_DICT=1 \ + WITHOUT_GAMES=1 \ + WITHOUT_LIB32=1 + +# Environment for custom install +INSTALLENV?= ${BUILDENV} \ + WITHOUT_TOOLCHAIN=1 +.endif + +# Environment for custom scripts +CUSTOMSCRIPTENV?= env \ + WRKDIR=${WRKDIR} \ + DESTDIR=${_DESTDIR} \ + DISTDIR=${_DISTDIR} \ + BASE=${BASE} + +.if defined(FULLDIST) +NO_PRUNE=1 +WITH_RESCUE=1 +.endif + +all: image + +destdir: ${_DESTDIR} ${_BOOTDIR} +${_DESTDIR}: + ${_v}${MKDIR} ${_DESTDIR} && ${CHOWN} root:wheel ${_DESTDIR} + +${_BOOTDIR}: + ${_v}${MKDIR} ${_BOOTDIR}/kernel ${_BOOTDIR}/modules && ${CHOWN} -R root:wheel ${_BOOTDIR} + +extract: destdir ${WRKDIR}/.extract_done +${WRKDIR}/.extract_done: +.if !defined(CUSTOM) + ${_v}if [ ! -d "${BASE}" ]; then \ + echo "Please set the environment variable BASE to a path"; \ + echo "with FreeBSD distribution files (e.g. /cdrom/9.2-RELEASE)"; \ + echo "Examples:"; \ + echo "make BASE=/cdrom/9.2-RELEASE"; \ + echo "make BASE=/cdrom/usr/freebsd-dist"; \ + exit 1; \ + fi +.if !defined(FREEBSD9) + ${_v}for DIR in base kernels; do \ + if [ ! -d "${BASE}/$$DIR" ]; then \ + echo "Cannot find directory \"${BASE}/$$DIR\""; \ + exit 1; \ + fi \ + done +.endif + @echo -n "Extracting base and kernel ..." + ${_v}${CAT} ${BASEFILE} | ${TAR} --unlink -xpzf - -C ${_DESTDIR} +.if !defined(FREEBSD9) + ${_v}${CAT} ${KERNELFILE} | ${TAR} --unlink -xpzf - -C ${_BOOTDIR} + ${_v}${MV} ${_BOOTDIR}/${KERNCONF}/* ${_BOOTDIR}/kernel + ${_v}${RMDIR} ${_BOOTDIR}/${KERNCONF} +.else + ${_v}${CAT} ${KERNELFILE} | ${TAR} --unlink -xpzf - -C ${_ROOTDIR} +.endif + @echo " done" +.endif + ${_v}${TOUCH} ${WRKDIR}/.extract_done + +build: extract ${WRKDIR}/.build_done +${WRKDIR}/.build_done: +.if defined(CUSTOM) +. if defined(BUILDWORLD) + @echo -n "Building world ..." + ${_v}cd ${SRC_DIR} && \ + ${BUILDENV} make ${_MAKEJOBS} buildworld TARGET=${TARGET} +. endif +. if defined(BUILDKERNEL) + @echo -n "Building kernel KERNCONF=${KERNCONF} ..." + ${_v}cd ${SRC_DIR} && make buildkernel KERNCONF=${KERNCONF} TARGET=${TARGET} +. endif +.endif + ${_v}${TOUCH} ${WRKDIR}/.build_done + +install: destdir build ${WRKDIR}/.install_done +${WRKDIR}/.install_done: +.if defined(CUSTOM) + @echo -n "Installing world and kernel KERNCONF=${KERNCONF} ..." + ${_v}cd ${SRC_DIR} && \ + ${INSTALLENV} make installworld distribution DESTDIR="${_DESTDIR}" TARGET=${TARGET} && \ + ${INSTALLENV} make installkernel KERNCONF=${KERNCONF} DESTDIR="${_ROOTDIR}" TARGET=${TARGET} +.endif +.if defined(SE) +. if !defined(CUSTOM) && exists(${BASE}/base.txz) && exists(${BASE}/kernel.txz) + @echo -n "Copying base.txz and kernel.txz ..." +. else + @echo -n "Creating base.txz and kernel.txz ..." +. endif + ${_v}${MKDIR} ${_DISTDIR} +. if !defined(NO_ROOTHACK) + ${_v}${CP} -rp ${_BOOTDIR}/${KERNDIR} ${_DESTDIR}/boot +. if "${KERNDIR}" != "kernel" + ${_v}${MV} -f ${_DESTDIR}/boot/${KERNDIR} ${_DESTDIR}/boot/kernel +. endif +. endif +. if !defined(CUSTOM) && exists(${BASE}/base.txz) && exists(${BASE}/kernel.txz) + ${_v}${CP} ${BASE}/base.txz ${_DISTDIR}/base.txz + ${_v}${CP} ${BASE}/kernel.txz ${_DISTDIR}/kernel.txz +. else + ${_v}${TAR} -c -C ${_DESTDIR} -J ${EXCLUDE} --exclude "boot/${KERNDIR}/*" -f ${_DISTDIR}/base.txz . + ${_v}${TAR} -c -C ${_DESTDIR} -J ${EXCLUDE} -f ${_DISTDIR}/kernel.txz boot/kernel +. endif + @echo " done" +. if !defined(NO_ROOTHACK) + ${_v}${RM} -rf ${_DESTDIR}/boot/${KERNDIR} +. endif +.endif + ${_v}${CHFLAGS} -R noschg ${_DESTDIR} > /dev/null 2> /dev/null || exit 0 +.if !defined(WITHOUT_RESCUE) && defined(RESCUE_LINKS) + ${_v}cd ${_DESTDIR} && \ + for FILE in `${FIND} rescue -type f`; do \ + FILE=$${FILE##rescue/}; \ + if [ -f bin/$$FILE ]; then \ + ${RM} bin/$$FILE && \ + ${LN} rescue/$$FILE bin/$$FILE; \ + elif [ -f sbin/$$FILE ]; then \ + ${RM} sbin/$$FILE && \ + ${LN} rescue/$$FILE sbin/$$FILE; \ + elif [ -f usr/bin/$$FILE ]; then \ + ${RM} usr/bin/$$FILE && \ + ${LN} -s ../../rescue/$$FILE usr/bin/$$FILE; \ + elif [ -f usr/sbin/$$FILE ]; then \ + ${RM} usr/sbin/$$FILE && \ + ${LN} -s ../../rescue/$$FILE usr/sbin/$$FILE; \ + fi; \ + done +.endif +.if defined(WITHOUT_RESCUE) + ${_v}cd ${_DESTDIR} && ${RM} -rf rescue +.endif + ${_v}${TOUCH} ${WRKDIR}/.install_done + +prune: install ${WRKDIR}/.prune_done +${WRKDIR}/.prune_done: +.if !defined(NO_PRUNE) + @echo -n "Removing selected files from distribution ..." + ${_v}if [ -f "${PRUNELIST}" ]; then \ + for FILE in `${CAT} ${PRUNELIST}`; do \ + if [ -n "$${FILE}" ]; then \ + ${RM} -rf ${_DESTDIR}/$${FILE}; \ + fi; \ + done; \ + fi + ${_v}${TOUCH} ${WRKDIR}/.prune_done + @echo " done" +.endif + +cdboot: install prune ${WRKDIR}/.cdboot_done +${WRKDIR}/.cdboot_done: + @echo -n "Copying out cdboot and EFI loader ..." + ${_v}${MKDIR} ${WRKDIR}/cdboot + ${_v}${CP} ${_DESTDIR}/boot/cdboot ${WRKDIR}/cdboot/ + ${_v}${CP} ${_DESTDIR}/boot/loader_4th.efi ${_DESTDIR}/boot/loader_lua.efi ${WRKDIR}/cdboot/ + ${_v}${TOUCH} ${WRKDIR}/.cdboot_done + @echo " done" + +packages: install prune cdboot ${WRKDIR}/.packages_done +${WRKDIR}/.packages_done: + @echo -n "Installing pkgng ..." +. if !exists(${PKG_STATIC}) + @echo "pkg-static not found at: ${PKG_STATIC}" + ${_v}exit 1 +. endif + ${_v}mkdir -p ${_DESTDIR}/usr/local/sbin + ${_v}${INSTALL} -o root -g wheel -m 0755 ${PKG_STATIC} ${_DESTDIR}/usr/local/sbin/ + ${_v}${LN} -sf pkg-static ${_DESTDIR}/usr/local/sbin/pkg + @echo " done" + @echo "Installing user packages ..." + ${_v}if [ -f "${TOOLSDIR}/packages" ]; then \ + _PKGS="${TOOLSDIR}/packages"; \ + elif [ -f "${TOOLSDIR}/packages.sample" ]; then \ + _PKGS="${TOOLSDIR}/packages.sample"; \ + fi; \ + if [ -n "$${_PKGS}" ]; then \ + env ASSUME_ALWAYS_YES=yes \ + PKG_ABI="${PKG_ABI}" \ + PKG_CACHEDIR=${WRKDIR}/pkgcache \ + ${PKG} -r ${_DESTDIR} install `${CAT} $${_PKGS}`; \ + fi; + ${_v}${TOUCH} ${WRKDIR}/.packages_done + +packages-mini: packages ${WRKDIR}/.packages_mini_done +${WRKDIR}/.packages_mini_done: + @echo "Installing additional mini packages ..." + ${_v}if [ -f "${TOOLSDIR}/packages-mini" ]; then \ + _PKGS="${TOOLSDIR}/packages-mini"; \ + elif [ -f "${TOOLSDIR}/packages-mini.sample" ]; then \ + _PKGS="${TOOLSDIR}/packages-mini.sample"; \ + fi; \ + if [ -n "$${_PKGS}" ]; then \ + env ASSUME_ALWAYS_YES=yes \ + PKG_ABI="${PKG_ABI}" \ + PKG_CACHEDIR=${WRKDIR}/pkgcache \ + ${PKG} -r ${_DESTDIR} install `${CAT} $${_PKGS}`; \ + fi; + ${_v}${TOUCH} ${WRKDIR}/.packages_mini_done + +config: install ${WRKDIR}/.config_done +${WRKDIR}/.config_done: + @echo -n "Installing configuration scripts and files ..." +.for FILE in boot.config loader.conf rc.conf rc.local resolv.conf interfaces.conf ttys +. if !exists(${CFGDIR}/${FILE}) && !exists(${CFGDIR}/${FILE}.sample) + @echo "Missing ${CFGDIR}/${FILE}.sample" && exit 1 +. endif +.endfor +.if defined(SE) + ${_v}${INSTALL} -m 0644 ${TOOLSDIR}/motd.se ${_DESTDIR}/etc/motd + ${_v}${INSTALL} -d -m 0755 ${_DESTDIR}/cdrom +.else + ${_v}${INSTALL} -m 0644 ${TOOLSDIR}/motd ${_DESTDIR}/etc/motd +.endif + ${_v}${MKDIR} ${_DESTDIR}/stand ${_DESTDIR}/etc/rc.conf.d + ${_v}if [ -f "${CFGDIR}/boot.config" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/boot.config ${_DESTDIR}/boot.config; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/boot.config.sample ${_DESTDIR}/boot.config; \ + fi + ${_v}if [ -f "${CFGDIR}/loader.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf ${_BOOTDIR}/loader.conf; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf.sample ${_BOOTDIR}/loader.conf; \ + fi + ${_v}if [ -f "${CFGDIR}/rc.local" ]; then \ + ${INSTALL} -m 0744 ${CFGDIR}/rc.local ${_DESTDIR}/etc/rc.local; \ + else \ + ${INSTALL} -m 0744 ${CFGDIR}/rc.local.sample ${_DESTDIR}/etc/rc.local; \ + fi +.for FILE in rc.conf ttys + ${_v}if [ -f "${CFGDIR}/${FILE}" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE} ${_DESTDIR}/etc/${FILE}; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE}.sample ${_DESTDIR}/etc/${FILE}; \ + fi +.endfor +.if !defined(NO_ROOTHACK) + @echo 'root_rw_mount="NO"' >> ${_DESTDIR}/etc/rc.conf +.endif + ${_v}if [ -f "${CFGDIR}/resolv.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/resolv.conf ${_DESTDIR}/etc/resolv.conf; \ + fi + ${_v}if [ -f "${CFGDIR}/interfaces.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/interfaces.conf ${_DESTDIR}/etc/rc.conf.d/interfaces; \ + fi + ${_v}if [ -f "${CFGDIR}/authorized_keys" ]; then \ + ${INSTALL} -d -m 0700 ${_DESTDIR}/root/.ssh; \ + ${INSTALL} ${CFGDIR}/authorized_keys ${_DESTDIR}/root/.ssh/; \ + fi + ${_v}${MKDIR} ${_DESTDIR}/root/bin + ${_v}${INSTALL} ${TOOLSDIR}/zfsinstall ${_DESTDIR}/root/bin + ${_v}${INSTALL} ${TOOLSDIR}/destroygeom ${_DESTDIR}/root/bin + ${_v}for SCRIPT in ${SCRIPTS}; do \ + ${INSTALL} -m 0555 ${SCRIPTSDIR}/$${SCRIPT} ${_DESTDIR}/etc/rc.d/; \ + done +# ${_v}${SED} -I -E 's/\(ttyv[2-7].*\)on /\1off/g' ${_DESTDIR}/etc/ttys +.if defined(NO_ROOTHACK) + ${_v}echo "/dev/md0 / ufs rw 0 0" > ${_DESTDIR}/etc/fstab + ${_v}echo "tmpfs /tmp tmpfs rw,mode=1777 0 0" >> ${_DESTDIR}/etc/fstab +.else + ${_v}${TOUCH} ${_DESTDIR}/etc/fstab +.endif +.if defined(ROOTPW) + ${_v}echo '${ROOTPW}'| ${OPENSSL} passwd -6 -stdin | ${PW} -V ${_DESTDIR}/etc usermod root -H 0 +.elif !empty(ROOTPW_HASH) + ${_v}echo '${ROOTPW_HASH}'| ${PW} -V ${_DESTDIR}/etc usermod root -H 0 +.endif + ${_v}echo PermitRootLogin yes >> ${_DESTDIR}/etc/ssh/sshd_config +.if exists(${CFGDIR}/hosts) + ${_v}${INSTALL} -m 0644 ${CFGDIR}/hosts ${_DESTDIR}/etc/hosts +.elif exists(${CFGDIR}/hosts.sample) + ${_v}${INSTALL} -m 0644 ${CFGDIR}/hosts.sample ${_DESTDIR}/etc/hosts +.else + @echo "Missing ${CFGDIR}/hosts.sample" && exit 1 +.endif + ${_v}${TOUCH} ${WRKDIR}/.config_done + @echo " done" + +genkeys: config ${WRKDIR}/.genkeys_done +${WRKDIR}/.genkeys_done: + @echo -n "Generating SSH host keys ..." + ${_v}test -f ${_DESTDIR}/etc/ssh/ssh_host_key || ${SSHKEYGEN} -t rsa1 -b 1024 -f ${_DESTDIR}/etc/ssh/ssh_host_key -N '' > /dev/null 2> /dev/null || true + ${_v}test -f ${_DESTDIR}/etc/ssh/ssh_host_dsa_key || ${SSHKEYGEN} -t dsa -f ${_DESTDIR}/etc/ssh/ssh_host_dsa_key -N '' > /dev/null 2> /dev/null || true + ${_v}test -f ${_DESTDIR}/etc/ssh/ssh_host_rsa_key || ${SSHKEYGEN} -t rsa -f ${_DESTDIR}/etc/ssh/ssh_host_rsa_key -N '' > /dev/null + ${_v}test -f ${_DESTDIR}/etc/ssh/ssh_host_ecdsa_key || ${SSHKEYGEN} -t ecdsa -f ${_DESTDIR}/etc/ssh/ssh_host_ecdsa_key -N '' > /dev/null + ${_v}test -f ${_DESTDIR}/etc/ssh/ssh_host_ed25519_key || ${SSHKEYGEN} -t ed25519 -f ${_DESTDIR}/etc/ssh/ssh_host_ed25519_key -N '' > /dev/null + ${_v}${TOUCH} ${WRKDIR}/.genkeys_done + @echo " done" + +customfiles: config ${WRKDIR}/.customfiles_done +${WRKDIR}/.customfiles_done: +.if exists(${CUSTOMFILESDIR}) + @echo "Copying user files ..." + ${_v}${CP} -afv ${CUSTOMFILESDIR}/ ${_DESTDIR}/ + ${_v}${TOUCH} ${WRKDIR}/.customfiles_done + @echo " done" +.endif + +customscripts: config ${WRKDIR}/.customscripts_done +${WRKDIR}/.customscripts_done: +.if exists(${CUSTOMSCRIPTSDIR}) + @echo -n "Running user scripts ..." + @for SCRIPT in `find ${CUSTOMSCRIPTSDIR} -type f`; do \ + chmod +x $$SCRIPT; \ + ${CUSTOMSCRIPTENV} $$SCRIPT; \ + done + ${_v}${TOUCH} ${WRKDIR}/.customscripts_done + @echo " done" +.endif + +compress-usr: install prune cdboot config genkeys customfiles customscripts boot efiboot packages ${WRKDIR}/.compress-usr_done +${WRKDIR}/.compress-usr_done: +.if defined(NO_ROOTHACK) + @echo -n "Compressing usr ..." + ${_v}${TAR} -c -J -C ${_DESTDIR} -f ${_DESTDIR}/.usr.tar.xz usr + ${_v}${RM} -rf ${_DESTDIR}/usr && ${MKDIR} ${_DESTDIR}/usr +.else + @echo -n "Compressing root ..." + ${_v}${TAR} -c -C ${_ROOTDIR} -f - rw | \ + ${XZ} ${XZ_FLAGS} -v -c > ${_ROOTDIR}/root.txz + ${_v}${RM} -rf ${_DESTDIR} && ${MKDIR} ${_DESTDIR} +.endif + ${_v}${TOUCH} ${WRKDIR}/.compress-usr_done + @echo " done" + +roothack: ${WRKDIR}/roothack/roothack +${WRKDIR}/roothack/roothack: +.if !defined(ROOTHACK_PREBUILT) + ${_v}${MKDIR} -p ${WRKDIR}/roothack + ${_v}cd ${TOOLSDIR}/roothack && env MAKEOBJDIR=${WRKDIR}/roothack make +.endif + +install-roothack: compress-usr roothack ${WRKDIR}/.install-roothack_done +${WRKDIR}/.install-roothack_done: + @echo -n "Installing roothack ..." + ${_v}${MKDIR} -p ${_ROOTDIR}/dev ${_ROOTDIR}/sbin + ${_v}${INSTALL} -m 555 ${ROOTHACK_FILE} ${_ROOTDIR}/sbin/init + ${_v}${TOUCH} ${WRKDIR}/.install-roothack_done + @echo " done" + +boot: install prune cdboot ${WRKDIR}/.boot_done +${WRKDIR}/.boot_done: + @echo -n "Configuring boot environment ..." + ${_v}${MKDIR} -p ${WRKDIR}/disk/boot/kernel + ${_v}${CHOWN} root:wheel ${WRKDIR}/disk + ${_v}${TAR} -c -X ${KERN_EXCLUDE} -C ${_BOOTDIR}/${KERNDIR} -f - . | ${TAR} -xv -C ${WRKDIR}/disk/boot/kernel -f - + ${_v}${CP} -rp ${_DESTDIR}/boot.config ${WRKDIR}/disk +.for FILE in ${BOOTFILES} + ${_v}${CP} -rp ${_DESTDIR}/boot/${FILE} ${WRKDIR}/disk/boot +.endfor +.if defined(LOADER_4TH) + ${_v}${MV} -f ${WRKDIR}/disk/boot/loader_4th ${WRKDIR}/disk/boot/loader +.else + ${_v}${MV} -f ${WRKDIR}/disk/boot/loader_lua ${WRKDIR}/disk/boot/loader +.endif + ${_v}${RM} -rf ${WRKDIR}/disk/boot/kernel/*.ko ${WRKDIR}/disk/boot/kernel/*.symbols +.if defined(DEBUG) + ${_v}-${INSTALL} -m 0555 ${_BOOTDIR}/${KERNDIR}/kernel.symbols ${WRKDIR}/disk/boot/kernel +.endif + # Install modules need to boot into the kernel directory + ${_v}${FIND} ${_BOOTDIR}/${KERNDIR} -name 'acpi*.ko' -exec ${INSTALL} -m 0555 {} ${WRKDIR}/disk/boot/kernel \; +.for FILE in ${BOOTMODULES} + ${_v}[ ! -f ${_BOOTDIR}/${KERNDIR}/${FILE}.ko ] || \ + ${INSTALL} -m 0555 ${_BOOTDIR}/${KERNDIR}/${FILE}.ko ${WRKDIR}/disk/boot/kernel +. if defined(DEBUG) + ${_v}[ ! -f ${_BOOTDIR}/${KERNDIR}/${FILE}.ko.symbols ] || \ + ${INSTALL} -m 0555 ${_BOOTDIR}/${KERNDIR}/${FILE}.ko.symbols ${WRKDIR}/disk/boot/kernel +. endif +.endfor + ${_v}${MKDIR} -p ${_DESTDIR}/boot/modules +.for FILE in ${MFSMODULES} + ${_v}[ ! -f ${_BOOTDIR}/${KERNDIR}/${FILE}.ko ] || \ + ${INSTALL} -m 0555 ${_BOOTDIR}/${KERNDIR}/${FILE}.ko ${_DESTDIR}/boot/modules +. if defined(DEBUG) + ${_v}[ ! -f ${_BOOTDIR}/${KERNDIR}/${FILE}.ko.symbols ] || \ + ${INSTALL} -m 0555 ${_BOOTDIR}/${KERNDIR}/${FILE}.ko.symbols ${_DESTDIR}/boot/modules +. endif +.endfor +.if !defined(NO_ROOTHACK) + ${_v}${MKDIR} -p ${_ROOTDIR}/boot/modules + ${_v}${INSTALL} -m 0666 ${_BOOTDIR}/${KERNDIR}/tmpfs.ko ${_ROOTDIR}/boot/modules +.endif + ${_v}${RM} -rf ${_BOOTDIR}/${KERNDIR} ${_BOOTDIR}/*.symbols + ${_v}${MKDIR} -p ${WRKDIR}/boot + ${_v}${CP} -p ${_DESTDIR}/boot/pmbr ${_DESTDIR}/boot/gptboot ${WRKDIR}/boot + ${_v}${TOUCH} ${WRKDIR}/.boot_done + @echo " done" + +efiboot: install prune cdboot config genkeys customfiles customscripts boot ${WRKDIR}/.efiboot_done +${WRKDIR}/.efiboot_done: +.if !defined(NO_EFIBOOT) + @echo -n "Creating EFI boot image ..." + ${_v}${MKDIR} -p ${WRKDIR}/efiroot/EFI/BOOT + ${_v}${CP} ${WRKDIR}/cdboot/${EFILOADER} ${WRKDIR}/efiroot/EFI/BOOT/BOOTX64.efi + ${_v}${MAKEFS} -t msdos -s 2048k -o fat_type=12,sectors_per_cluster=1 ${WRKDIR}/cdboot/efiboot.img ${WRKDIR}/efiroot + ${_v}${TOUCH} ${WRKDIR}/.efiboot_done + @echo " done" +.endif + +.if !defined(NO_ROOTHACK) +mfsroot: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr packages install-roothack ${WRKDIR}/.mfsroot_done +.else +mfsroot: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr packages ${WRKDIR}/.mfsroot_done +.endif +${WRKDIR}/.mfsroot_done: + @echo -n "Creating and compressing mfsroot ..." + ${_v}${MKDIR} ${WRKDIR}/mnt + ${_v}${MAKEFS} -t ffs -m ${MFSROOT_MAXSIZE} -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} ${WRKDIR}/disk/mfsroot ${_ROOTDIR} > /dev/null + ${_v}${RM} -rf ${WRKDIR}/mnt + ${_v}${GZIP} -9 -f ${WRKDIR}/disk/mfsroot + ${_v}${GZIP} -9 -f ${WRKDIR}/disk/boot/kernel/kernel + ${_v}if [ -f "${CFGDIR}/loader.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf ${WRKDIR}/disk/boot/loader.conf; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf.sample ${WRKDIR}/disk/boot/loader.conf; \ + fi + ${_v}${TOUCH} ${WRKDIR}/.mfsroot_done + @echo " done" + +fbsddist: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr packages mfsroot ${WRKDIR}/.fbsddist_done +${WRKDIR}/.fbsddist_done: +.if defined(SE) + @echo -n "Copying FreeBSD installation image ..." + ${_v}${CP} -rf ${_DISTDIR} ${WRKDIR}/disk/ + @echo " done" +.endif + ${_v}${TOUCH} ${WRKDIR}/.fbsddist_done + +image: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr mfsroot fbsddist ${IMAGE} +${IMAGE}: + @echo -n "Creating image file ..." +.if defined(BSDPART) + ${_v}${MKDIR} ${WRKDIR}/mnt ${WRKDIR}/trees/base/boot + ${_v}${INSTALL} -m 0444 ${WRKDIR}/disk/boot/boot ${WRKDIR}/trees/base/boot/ + ${_v}${DOFS} ${BSDLABEL} "" ${WRKDIR}/disk.img ${WRKDIR} ${WRKDIR}/mnt 0 ${WRKDIR}/disk 80000 auto > /dev/null 2> /dev/null + ${_v}${RM} -rf ${WRKDIR}/mnt ${WRKDIR}/trees + ${_v}${MV} ${WRKDIR}/disk.img ${.TARGET} +.else + ${_v}${TOOLSDIR}/do_gpt.sh ${.TARGET} ${WRKDIR}/disk 0 ${WRKDIR}/boot ${WRKDIR}/cdboot/efiboot.img ${VERB} +.endif + @echo " done" + ${_v}${LS} -l ${.TARGET} + +gce: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr mfsroot fbsddist ${IMAGE} ${GCEFILE} +${GCEFILE}: + @echo -n "Creating GCE-compatible tarball..." +.if !exists(${GTAR}) + ${_v}echo "${GTAR} is missing, please install archivers/gtar first"; exit 1 +.else + ${_v}${GTAR} -C ${.CURDIR} -Szcf ${GCEFILE} --transform='s/${IMAGE}/disk.raw/' ${IMAGE} + @echo " GCE tarball built" + ${_v}${LS} -l ${GCEFILE} +.endif + +iso: install prune cdboot config genkeys customfiles customscripts boot efiboot compress-usr mfsroot fbsddist ${ISOIMAGE} +${ISOIMAGE}: + @echo -n "Creating ISO image ..." +.if !defined(NO_EFIBOOT) + ${_v}${MAKEFS} -t cd9660 -o rockridge,label=mfsBSD \ + -o bootimage=i386\;${WRKDIR}/cdboot/cdboot,no-emul-boot \ + -o bootimage=i386\;${WRKDIR}/cdboot/efiboot.img,no-emul-boot,platformid=efi \ + ${ISOIMAGE} ${WRKDIR}/disk +.else + ${_v}${MAKEFS} -t cd9660 -o rockridge,label=mfsBSD \ + -o bootimage=i386\;${WRKDIR}/cdboot/cdboot,no-emul-boot \ + ${ISOIMAGE} ${WRKDIR}/disk +.endif + @echo " done" + ${_v}${LS} -l ${ISOIMAGE} + +tar: install prune cdboot config customfiles customscripts boot efiboot compress-usr mfsroot fbsddist ${TARFILE} +${TARFILE}: + @echo -n "Creating tar file ..." + ${_v}cd ${WRKDIR}/disk && ${FIND} . -depth 1 \ + -exec ${TAR} -r -f ${.CURDIR}/${TARFILE} {} \; + @echo " done" + ${_v}${LS} -l ${TARFILE} + +prepare-mini: packages-mini config boot cdboot + +clean-roothack: + ${_v}${RM} -rf ${WRKDIR}/roothack + +clean-pkgcache: + ${_v}${RM} -rf ${WRKDIR}/pkgcache + +clean: + ${_v}if [ -d ${WRKDIR} ]; then \ + ${CHFLAGS} -R noschg ${WRKDIR} && \ + cd ${WRKDIR} && \ + ${RM} -rf boot mfs mnt disk dist trees cdboot efiroot .*_done; \ + fi + +clean-all: clean clean-roothack clean-pkgcache diff --git a/contrib/mfsbsd/README.md b/contrib/mfsbsd/README.md new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/README.md @@ -0,0 +1,31 @@ +# mfsBSD + +Copyright (c) 2019 Martin Matuska + +Version 2.4 + +## Description + +This is a set of scripts that generates a bootable image, ISO file or boot +files only, that create a working minimal installation of FreeBSD. This +minimal installation gets completely loaded into memory. + +The image may be written directly using dd(1) onto any bootable block device, +e.g. a hard disk or a USB stick e.g. /dev/da0, or a bootable slice only, +e.g. /dev/ada0s1 + +## Build-time requirements + - FreeBSD 11 or higher installed, tested on i386 or amd64 + - base.txz and kernel.txz from a FreeBSD 11 or higher distribution + +## Runtime requirements + - a minimum of 512MB system memory + +## Other information + +See [BUILD](./BUILD.md) and [INSTALL](./INSTALL.md) for building and installation instructions. + +Project homepage: http://mfsbsd.vx.sk + +This project is based on the ideas of the depenguinator project: +http://www.daemonology.net/depenguinator/ diff --git a/contrib/mfsbsd/ci/ci.sh b/contrib/mfsbsd/ci/ci.sh new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/ci/ci.sh @@ -0,0 +1,46 @@ +#!/bin/sh +set -e +BASE=/tmp/freebsd-dist +RELEASE=${RELEASE:-13.0-RELEASE} +DOWNLOAD_URL=http://ftp.freebsd.org/pub/FreeBSD/releases/amd64/${RELEASE} +while getopts b:r: opt +do + case $opt in + b) ACTION="${OPTARG}";; + r) RELEASE="${OPTARG}";; + esac +done +if [ "${ACTION}" = "prepare" ] +then + mkdir -p ${BASE} + fetch -m -o ${BASE}/base.txz ${DOWNLOAD_URL}/base.txz + fetch -m -o ${BASE}/kernel.txz ${DOWNLOAD_URL}/kernel.txz + if [ -x tools/roothack/roothack ] + then + cd tools/roothack && make depend && make + fi +elif [ "${ACTION}" = "build-std" ] +then + make clean V=1 + make iso V=1 RELEASE=${RELEASE} BASE=${BASE} ROOTHACK=1 + make V=1 RELEASE=${RELEASE} BASE=${BASE} ROOTHACK=1 +elif [ "${ACTION}" = "build-se" ] +then + make clean V=1 + make iso V=1 RELEASE=${RELEASE} BASE=${BASE} ROOTHCK=1 SE=1 + make V=1 RELEASE=${RELEASE} BASE=${BASE} ROOTHACK=1 SE=1 +elif [ "${ACTION}" = "build-mini" ] +then + make clean V=1 + make prepare-mini V=1 RELEASE=${RELEASE} ROOTHACK=1 BASE=${BASE} + cd mini + make clean V=1 + make iso V=1 RELEASE=${RELEASE} ROOTHACK=1 BASE=${BASE} + make clean V=1 + cd .. + make clean V=1 + mv mini/*.iso . +else + echo "Unknown build step" + false +fi diff --git a/contrib/mfsbsd/conf/authorized_keys.sample b/contrib/mfsbsd/conf/authorized_keys.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/authorized_keys.sample @@ -0,0 +1,2 @@ +# $Id$ +# Public SSH key(s) for root authorization diff --git a/contrib/mfsbsd/conf/boot.config.sample b/contrib/mfsbsd/conf/boot.config.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/boot.config.sample @@ -0,0 +1 @@ +-D diff --git a/contrib/mfsbsd/conf/hosts.sample b/contrib/mfsbsd/conf/hosts.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/hosts.sample @@ -0,0 +1,6 @@ +# $Id$ +# +# The file will be the /etc/hosts file in your image +# +::1 localhost localhost.my.domain +127.0.0.1 localhost localhost.my.domain diff --git a/contrib/mfsbsd/conf/interfaces.conf.sample b/contrib/mfsbsd/conf/interfaces.conf.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/interfaces.conf.sample @@ -0,0 +1,16 @@ +# $Id$ +# +# If you don't know the exact interface names and/or order in which they +# appear, you can configure interfaces depending on their MAC addresses here. + +# mac_interfaces should be a user-defined list of virtual interface names. +#mac_interfaces="ext1 ext2" + +# ifconfig_FOO_mac should be the MAC address of interface FOO +#ifconfig_ext1_mac="00:00:00:00:00:00" +#ifconfig_ext2_mac="ff:ff:ff:ff:ff:ff" + +# ifconfig_FOO should be configured like the real interface behind FOO +# for more information, see ifconfig(8) +#ifconfig_ext1="inet 192.168.0.1/24" +#ifconfig_ext2="inet 192.168.1.1/24" diff --git a/contrib/mfsbsd/conf/loader.conf.sample b/contrib/mfsbsd/conf/loader.conf.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/loader.conf.sample @@ -0,0 +1,54 @@ +# $Id$ +# +# This is the /boot/loader.conf of your image +# +# Custom mfsbsd variables +# +# Set all auto-detected interfaces to DHCP +#mfsbsd.autodhcp="YES" +# +# Define a new root password +#mfsbsd.rootpw="foobar" +# +# Alternatively define a root password hash like in master.passwd +# NOTICE: replace '$' characters with '%' +#mfsbsd.rootpwhash="" +# +# Add additional nameservers here +#mfsbsd.nameservers="192.168.1.1 192.168.1.2" +# +# Change system hostname +#mfsbsd.hostname="mfsbsd" +# +# List of interfaces to be set +#mfsbsd.interfaces="em0 em1" +# +# Individual configuration of each interface +#mfsbsd.ifconfig_em0="DHCP" +#mfsbsd.ifconfig_em1="DHCP" +# +# List of special interfaces to be created +#mfsbsd.cloned_interfaces="" +# +# List of mac_interfaces (see interfaces.conf.sample) +#mfsbsd.mac_interfaces="eth0" +#mfsbsd.ifconfig_eth0_mac="xx:xx:xx:xx:xx:xx" +#mfsbsd.ifconfig_eth0="inet 192.168.1.10/24" +# +# Default router +#mfsbsd.defaultrouter="192.168.1.1" +# +# List of static routes and their definitions +#mfsbsd.static_routes="r1 r2" +#mfsbsd.route_r1="-net 192.168.2 192.168.1.1" +#mfsbsd.route_r2="-net 192.168.3 192.168.1.1" + +# +# Do not change anything here until you know what you are doing +# +mfs_load="YES" +mfs_type="mfs_root" +mfs_name="/mfsroot" +ahci_load="YES" +vfs.root.mountfrom="ufs:/dev/md0" +mfsbsd.autodhcp="YES" diff --git a/contrib/mfsbsd/conf/rc.conf.sample b/contrib/mfsbsd/conf/rc.conf.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/rc.conf.sample @@ -0,0 +1,24 @@ +# $Id$ +# +# This will be the rc.conf file in your image. +# +# You may set anything you want here, including network interfaces. +# If you are not sure about network interface names and/or their order, +# see the interfaces.conf file in this directory. +# +# Set this to any desired hostname +hostname="mfsbsd" +# +# You need a gateway defined for a working network setup +#defaultrouter="192.168.0.254" +# +# You may configure a network interface here, you may use "DHCP" as well +#ifconfig_em0="inet 192.168.0.1 netmask 255.255.255.0" +#ifconfig_rl0="DHCP" +# +# Change the values below only if you know what you are doing! +# +sshd_enable="YES" +sendmail_enable="NONE" +cron_enable="NO" +local_enable="YES" diff --git a/contrib/mfsbsd/conf/rc.local.sample b/contrib/mfsbsd/conf/rc.local.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/rc.local.sample @@ -0,0 +1,2 @@ +# sample rc.local +# add your code below \ No newline at end of file diff --git a/contrib/mfsbsd/conf/resolv.conf.sample b/contrib/mfsbsd/conf/resolv.conf.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/resolv.conf.sample @@ -0,0 +1,6 @@ +# $Id$ +# +# The file will be the /etc/resolv.conf file in your image +# +#domain com +#nameserver 192.168.0.254 diff --git a/contrib/mfsbsd/conf/ttys.sample b/contrib/mfsbsd/conf/ttys.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/conf/ttys.sample @@ -0,0 +1,22 @@ +# $FreeBSD$ +# +console none unknown off secure +# +ttyv0 "/usr/libexec/getty Pc" xterm on secure +# Virtual terminals +ttyv1 "/usr/libexec/getty Pc" xterm off secure +ttyv2 "/usr/libexec/getty Pc" xterm off secure +ttyv3 "/usr/libexec/getty Pc" xterm off secure +ttyv4 "/usr/libexec/getty Pc" xterm off secure +ttyv5 "/usr/libexec/getty Pc" xterm off secure +ttyv6 "/usr/libexec/getty Pc" xterm off secure +ttyv7 "/usr/libexec/getty Pc" xterm off secure +ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure +# Serial terminals +# The 'dialup' keyword identifies dialin lines to login, fingerd etc. +ttyu0 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu1 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu2 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu3 "/usr/libexec/getty 3wire" vt100 onifconsole secure +# Dumb console +dcons "/usr/libexec/getty std.9600" vt100 off secure diff --git a/contrib/mfsbsd/mini/Makefile b/contrib/mfsbsd/mini/Makefile new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/Makefile @@ -0,0 +1,333 @@ +# $Id$ +# +# mfsBSD-mini +# Copyright (c) 2018 Martin Matuska +# +# Version 0.2 +# + +# +# User-defined variables +# +BASEDIR?=${CURDIR}/../work/mfs/rw +BOOTBASE?=${CURDIR}/../work/disk/boot +CDBOOTBASE?=${CURDIR}/../work/cdboot +CFGDIR?=${CURDIR}/conf +MFSROOT_FREE_INODES?=5000 +MFSROOT_FREE_BLOCKS?=10% +MFSROOT_MINSIZE?=64m +MFSROOT_MAXSIZE?=64m +ROOTPW_HASH?=$$6$$051DdQA7fTvLymkY$$Z5f6snVFQJKugWmGi8y0motBNaKn9em0y2K0ZsJMku3v9gkiYh8M.OTIIie3RvHpzT6udumtZUtc0kXwJcCMR1 +LOCALBASEDIR?=${BASEDIR} + +.if defined(LOADER_4TH) +BOOTFILES?= defaults device.hints loader *.rc *.4th +EFILOADER?= loader_4th.efi +.else +BOOTFILES?= defaults device.hints loader lua +EFILOADER?= loader_lua.efi +.endif + +# +# Program defaults +# +CAT=/bin/cat +CHFLAGS=/bin/chflags +CHOWN=/usr/sbin/chown +CP=/bin/cp +DIRNAME=/usr/bin/dirname +FIND=/usr/bin/find +GTAR=/usr/local/bin/gtar +GZIP=/usr/bin/gzip +INSTALL=/usr/bin/install +LN=/bin/ln +LS=/bin/ls +MAKEFS=/usr/sbin/makefs +MKDIR=/bin/mkdir -p +MTREE=/usr/sbin/mtree +MV=/bin/mv +PW=/usr/sbin/pw +PWD=/bin/pwd +RM=/bin/rm +RMDIR=/bin/rmdir +SYSCTL=/sbin/sysctl +TAR=/usr/bin/tar +TOUCH=/usr/bin/touch +UNAME=/usr/bin/uname +# +BSDLABEL=bsdlabel + +# +CURDIR!=${PWD} +WRKDIR?=${CURDIR}/tmp +FILESDIR=${CURDIR}/files +TOOLSDIR=${CURDIR}/../tools +# +# +DOFS=${TOOLSDIR}/doFS.sh +BOOTMODULES=acpi ahci +MFSMODULES=geom_mirror geom_nop opensolaris zfs ext2fs smbus ipmi ntfs nullfs tmpfs \ + aesni crypto cryptodev geom_eli +# +.if defined(V) +_v= +VERB=1 +.else +_v=@ +VERB= +.endif + +.if !defined(ARCH) +TARGET!= ${SYSCTL} -n hw.machine_arch +.else +TARGET= ${ARCH} +.endif + +.if !defined(RELEASE) +RELEASE!=${UNAME} -r +.endif + +IMAGE_PREFIX=mfsbsd-mini + +IMAGE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.img +ISOIMAGE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.iso +TARFILE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.tar +GCEFILE?= ${IMAGE_PREFIX}-${RELEASE}-${TARGET}.tar.gz +_DISTDIR= ${WRKDIR}/dist/${RELEASE}-${TARGET} + +.if !defined(DEBUG) +EXCLUDE=--exclude *.symbols +.else +EXCLUDE= +.endif + +_ROOTDIR= ${WRKDIR}/mfs +_BOOTDIR= ${_ROOTDIR}/boot +_MODULESDIR= ${BASEDIR}/boot/modules + +all: image + +destdir: ${_ROOTDIR} ${_BOOTDIR} +${_ROOTDIR}: + ${_v}${MKDIR} ${_ROOTDIR} && ${CHOWN} root:wheel ${_ROOTDIR} + +${_BOOTDIR}: + ${_v}${MKDIR} ${_BOOTDIR}/kernel ${_BOOTDIR}/modules && ${CHOWN} -R root:wheel ${_BOOTDIR} + +hierarchy: destdir ${WRKDIR}/.hierarchy_done +${WRKDIR}/.hierarchy_done: + ${_v}echo -n "Creating directory hierarchy ..." + ${_v}${MTREE} -deU -f ${BASEDIR}/etc/mtree/BSD.root.dist -p ${_ROOTDIR} > /dev/null + ${_v}${MTREE} -deU -f ${BASEDIR}/etc/mtree/BSD.usr.dist -p ${_ROOTDIR}/usr > /dev/null + ${_v}${TOUCH} ${WRKDIR}/.hierarchy_done + ${_v}echo " done" + +installkernel: ${_BOOTDIR} ${WRKDIR}/.installkernel_done +${WRKDIR}/.installkernel_done: + ${_v}echo -n "Installing kernel ..." + ${_v}${CP} -a ${BOOTBASE}/ ${_BOOTDIR} + ${_v}${TOUCH} ${WRKDIR}/.installkernel_done + ${_v}echo " done" + +rescuelinks: hierarchy ${WRKDIR}/.rescuelinks_done +${WRKDIR}/.rescuelinks_done: + ${_v}echo -n "Installing rescue with linking script ..." + ${_v}${INSTALL} -m 0555 ${BASEDIR}/rescue/rescue ${_ROOTDIR}/rescue/rescue + ${_v}for FILE in `cat ${FILESDIR}/rescuelinks`; do \ + ${LN} ${_ROOTDIR}/rescue/rescue ${_ROOTDIR}/$${FILE}; \ + done + ${_v}${TOUCH} ${WRKDIR}/.rescuelinks_done + ${_v}echo " done" + +installbase: hierarchy rescuelinks ${WRKDIR}/.installbase_done +${WRKDIR}/.installbase_done: + ${_v}echo -n "Installing base files ..." + ${_v}cd ${_ROOTDIR} && for FILE in `cat ${FILESDIR}/instfiles`; do \ + ${CP} -pP ${BASEDIR}/$${FILE} ${_ROOTDIR}/$${FILE}; \ + done + ${_v}cd ${_ROOTDIR} && for DIR in `cat ${FILESDIR}/instdirs`; do \ + ${CP} -a ${BASEDIR}/$${DIR}/ ${_ROOTDIR}/$${DIR}; \ + done + ${_v}${TOUCH} ${WRKDIR}/.installbase_done + ${_v}echo " done" + +basetar: hierarchy rescuelinks ${WRKDIR}/.basetar_done +${WRKDIR}/.basetar_done: + ${_v}echo -n "Creating tar of base libraries and binaries ..." + ${_v}cd ${BASEDIR} && ${TAR} -cJf ${_ROOTDIR}/.mfs_base.txz \ + `cat ${FILESDIR}/basedirs` `cat ${FILESDIR}/basefiles` + ${_v}${TOUCH} ${WRKDIR}/.basetar_done + ${_v}echo " done" + +localtar: hierarchy ${WRKDIR}/.localtar_done +${WRKDIR}/.localtar_done: +.if exists(${FILESDIR}/localfiles) + ${_v}echo -n "Creating local files tar ..." + ${_v}cd ${LOCALBASEDIR}/usr/local && ${TAR} -cJf ${_ROOTDIR}/.mfs_local.txz \ + `cat ${FILESDIR}/localfiles` + ${_v}${TOUCH} ${WRKDIR}/.localtar_done + ${_v}echo " done" +.endif + +install: installbase basetar localtar + +config: install ${WRKDIR}/.config_done +${WRKDIR}/.config_done: + ${_v}echo -n "Installing configuration scripts and files ..." + ${_v}if [ -f "${CFGDIR}/loader.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf ${_BOOTDIR}/loader.conf; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf.sample ${_BOOTDIR}/loader.conf; \ + fi +.for FILE in rc hosts ttys resolv.conf rc.local + ${_v}if [ -f "${CFGDIR}/${FILE}" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE} ${_ROOTDIR}/etc/${FILE}; \ + elif [ -f "${CFGDIR}/${FILE}.sample" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE}.sample ${_ROOTDIR}/etc/${FILE}; \ + fi +.endfor + ${_v}${MKDIR} ${_ROOTDIR}/root/bin +.for FILE in .cshrc .profile + ${_v}if [ -f "${CFGDIR}/${FILE}" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE} ${_ROOTDIR}/root/${FILE}; \ + elif [ -f "${CFGDIR}/${FILE}.sample" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/${FILE}.sample ${_ROOTDIR}/root/${FILE}; \ + fi +.endfor + ${_v}${INSTALL} ${TOOLSDIR}/zfsinstall ${_ROOTDIR}/root/bin + ${_v}${INSTALL} ${TOOLSDIR}/destroygeom ${_ROOTDIR}/root/bin + ${_v}echo "/dev/md0 / ufs rw 0 0" > ${_ROOTDIR}/etc/fstab + ${_v}echo "tmpfs /tmp tmpfs rw,mode=1777 0 0" >> ${_ROOTDIR}/etc/fstab +.if defined(ROOTPW) + ${_v}echo '${ROOTPW}'| ${OPENSSL} passwd -6 -stdin | ${PW} -V ${_ROOTDIR}/etc usermod root -H 0 +.elif !empty(ROOTPW_HASH) + ${_v}echo '${ROOTPW_HASH}'| ${PW} -V ${_ROOTDIR}/etc usermod root -H 0 +.endif + ${_v}${TOUCH} ${WRKDIR}/.config_done + ${_v}echo " done" + +boot: installkernel install ${WRKDIR}/.boot_done +${WRKDIR}/.boot_done: + ${_v}echo -n "Configuring boot environment ..." + ${_v}${MKDIR} ${WRKDIR}/disk/boot && ${CHOWN} root:wheel ${WRKDIR}/disk + ${_v}${RM} -f ${_BOOTDIR}/kernel/kernel.debug + ${_v}${CP} -rp ${_BOOTDIR}/kernel ${WRKDIR}/disk/boot +.for FILE in ${BOOTFILES} + ${_v}${CP} -rp ${_ROOTDIR}/boot/${FILE} ${WRKDIR}/disk/boot +.endfor + ${_v}${RM} -rf ${WRKDIR}/disk/boot/kernel/*.ko ${WRKDIR}/disk/boot/kernel/*.symbols +.if defined(DEBUG) + ${_v}test -f ${_BOOTDIR}/kernel/kernel.symbols \ + && ${INSTALL} -m 0555 ${_BOOTDIR}/kernel/kernel.symbols ${WRKDIR}/disk/boot/kernel >/dev/null 2>/dev/null || exit 0 +.endif +.for FILE in ${BOOTMODULES} + ${_v}test -f ${_BOOTDIR}/kernel/${FILE}.ko \ + && ${INSTALL} -m 0555 ${_BOOTDIR}/kernel/${FILE}.ko ${WRKDIR}/disk/boot/kernel >/dev/null 2>/dev/null || exit 0 +. if defined(DEBUG) + ${_v}test -f ${_BOOTDIR}/kernel/${FILE}.ko \ + && ${INSTALL} -m 0555 ${_BOOTDIR}/kernel/${FILE}.ko.symbols ${WRKDIR}/disk/boot/kernel >/dev/null 2>/dev/null || exit 0 +. endif +.endfor + ${_v}${MKDIR} ${_ROOTDIR}/boot/modules +.for FILE in ${MFSMODULES} + ${_v}test -f ${_MODULESDIR}/${FILE}.ko \ + && ${INSTALL} -m 0555 ${_MODULESDIR}/${FILE}.ko ${_ROOTDIR}/boot/modules >/dev/null 2>/dev/null || exit 0 +. if defined(DEBUG) + ${_v}test -f ${_MODULESDIR}/${FILE}.ko.symbols \ + && ${INSTALL} -m 0555 ${_MODULESDIR}/${FILE}.ko.symbols ${_ROOTDIR}/boot/modules >/dev/null 2>/dev/null || exit 0 +. endif +.endfor + ${_v}${RM} -rf ${_BOOTDIR}/kernel ${_BOOTDIR}/*.symbols + ${_v}${TOUCH} ${WRKDIR}/.boot_done + ${_v}echo " done" + +efiboot: boot ${WRKDIR}/.efiboot_done +${WRKDIR}/.efiboot_done: +.if !defined(NO_EFIBOOT) + @echo -n "Creating EFI boot image ..." + ${_v}${MKDIR} -p ${WRKDIR}/efiroot/EFI/BOOT ${WRKDIR}/cdboot + ${_v}${CP} ${CDBOOTBASE}/${EFILOADER} ${WRKDIR}/efiroot/EFI/BOOT/BOOTX64.efi + ${_v}${MAKEFS} -t msdos -s 2048k -o fat_type=12,sectors_per_cluster=1 ${WRKDIR}/cdboot/efiboot.img ${WRKDIR}/efiroot + ${_v}${TOUCH} ${WRKDIR}/.efiboot_done + @echo " done" +.endif + +boottar: boot ${WRKDIR}/.boottar_done +${WRKDIR}/.boottar_done: + ${_v}echo -n "Compressing mfsroot boot ..." + ${_v}${TAR} -c -J -C ${_ROOTDIR} -f ${_ROOTDIR}/.mfs_boot.txz boot + ${_v}cd ${_ROOTDIR} && ${RM} -rf boot + ${_v}${TOUCH} ${WRKDIR}/.boottar_done + ${_v}echo " done" + +mfsroot: boottar ${WRKDIR}/.mfsroot_done +${WRKDIR}/.mfsroot_done: + ${_v}echo -n "Creating and compressing mfsroot ..." + ${_v}${MKDIR} ${WRKDIR}/mnt + ${_v}${MAKEFS} -t ffs -M ${MFSROOT_MINSIZE} -m ${MFSROOT_MAXSIZE} -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} ${WRKDIR}/disk/mfsroot ${_ROOTDIR} > /dev/null + ${_v}${RM} -rf ${WRKDIR}/mnt + ${_v}${GZIP} -9 -f ${WRKDIR}/disk/mfsroot + ${_v}${GZIP} -9 -f ${WRKDIR}/disk/boot/kernel/kernel + ${_v}if [ -f "${CFGDIR}/loader.conf" ]; then \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf ${WRKDIR}/disk/boot/loader.conf; \ + else \ + ${INSTALL} -m 0644 ${CFGDIR}/loader.conf.sample ${WRKDIR}/disk/boot/loader.conf; \ + fi + ${_v}${TOUCH} ${WRKDIR}/.mfsroot_done + ${_v}echo " done" + +image: install config boot mfsroot ${IMAGE} +${IMAGE}: + @echo -n "Creating image file ..." +.if defined(BSDPART) + ${_v}${MKDIR} ${WRKDIR}/mnt ${WRKDIR}/trees/base/boot + ${_v}${INSTALL} -m 0444 ${WRKDIR}/disk/boot/boot ${WRKDIR}/trees/base/boot/ + ${_v}${DOFS} ${BSDLABEL} "" ${WRKDIR}/disk.img ${WRKDIR} ${WRKDIR}/mnt 0 ${WRKDIR}/disk 80000 auto > /dev/null 2> /dev/null + ${_v}${RM} -rf ${WRKDIR}/mnt ${WRKDIR}/trees + ${_v}${MV} ${WRKDIR}/disk.img ${.TARGET} +.else + ${_v}${TOOLSDIR}/do_gpt.sh ${.TARGET} ${WRKDIR}/disk 0 ${BASEDIR}/boot ${WRKDIR}/cdboot/efiboot.img ${VERB} +.endif + @echo " done" + ${_v}${LS} -l ${.TARGET} + +gce: install config boot mfsroot ${IMAGE} ${GCEFILE} +${GCEFILE}: + ${_v}echo -n "Creating GCE-compatible tarball..." +.if !exists(${GTAR}) + ${_v}echo "${GTAR} is missing, please install archivers/gtar first"; exit 1 +.else + ${_v}${GTAR} -C ${CURDIR} -Szcf ${GCEFILE} --transform='s/${IMAGE}/disk.raw/' ${IMAGE} + ${_v}echo " GCE tarball built" + ${_v}${LS} -l ${GCEFILE} +.endif + +iso: install config boot efiboot mfsroot ${ISOIMAGE} +${ISOIMAGE}: + ${_v}echo -n "Creating ISO image ..." +.if !defined(NO_EFIBOOT) + ${_v}${MAKEFS} -t cd9660 -o rockridge,label=mfsBSD \ + -o bootimage=i386\;${CDBOOTBASE}/cdboot,no-emul-boot \ + -o bootimage=i386\;${WRKDIR}/cdboot/efiboot.img,no-emul-boot,platformid=efi \ + ${ISOIMAGE} ${WRKDIR}/disk +.else + ${_v}${MAKEFS} -t cd9660 -o rockridge,label=mfsBSD \ + -o bootimage=i386\;${CDBOOTBASE}/cdboot,no-emul-boot \ + ${ISOIMAGE} ${WRKDIR}/disk +.endif + ${_v}echo " done" + ${_v}${LS} -l ${ISOIMAGE} + +tar: install config boot mfsroot ${TARFILE} +${TARFILE}: + ${_v}echo -n "Creating tar file ..." + ${_v}cd ${WRKDIR}/disk && ${FIND} . -depth 1 \ + -exec ${TAR} -r -f ${CURDIR}/${TARFILE} {} \; + ${_v}echo " done" + ${_v}${LS} -l ${TARFILE} + +clean: + ${_v}if [ -d ${WRKDIR} ]; then \ + ${CHFLAGS} -R noschg ${WRKDIR} && \ + cd ${WRKDIR} && ${RM} -rf mfs mnt disk dist trees efiroot cdboot .*_done; \ + fi diff --git a/contrib/mfsbsd/mini/README.md b/contrib/mfsbsd/mini/README.md new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/README.md @@ -0,0 +1,19 @@ +# mfsBSD-mini + +Copyright (c) 2019 Martin Matuska + +## Description + +This is a set of scripts that generates a small bootable image, ISO file or +tar archive from a installed FreeBSD system. The image gets completely loaded +into memory. + +The image may be written directly using dd(1) onto any bootable block device, +e.g. a hard disk or a USB stick e.g. /dev/da0, or a bootable partition only, +e.g. /dev/ada0p2 + +## Building + +You need to do "make prepare-mini" in the main mfsBSD directory + +Project homepage: http://mfsbsd.vx.sk diff --git a/contrib/mfsbsd/mini/conf/.cshrc.sample b/contrib/mfsbsd/mini/conf/.cshrc.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/.cshrc.sample @@ -0,0 +1,43 @@ +# $FreeBSD: releng/10.1/etc/root/dot.cshrc 243893 2012-12-05 13:56:39Z eadler $ +# +# .cshrc - csh resource script, read at beginning of execution by each shell +# +# see also csh(1), environ(7). +# more examples available at /usr/share/examples/csh/ +# + +alias h history 25 +alias j jobs -l +alias la ls -aF +alias lf ls -FA +alias ll ls -lAF + +# A righteous umask +umask 22 + +set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin) + +setenv EDITOR vi +setenv PAGER more +setenv BLOCKSIZE K + +if ($?prompt) then + # An interactive shell -- set some stuff up + set prompt = "%N@%m:%~ %# " + set promptchars = "%#" + + set filec + set history = 1000 + set savehist = (1000 merge) + set autolist = ambiguous + # Use history to aid expansion + set autoexpand + set autorehash + set mail = (/var/mail/$USER) + if ( $?tcsh ) then + bindkey "^W" backward-delete-word + bindkey -k up history-search-backward + bindkey -k down history-search-forward + endif + +endif diff --git a/contrib/mfsbsd/mini/conf/.profile.sample b/contrib/mfsbsd/mini/conf/.profile.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/.profile.sample @@ -0,0 +1,10 @@ +# $FreeBSD: releng/10.1/etc/root/dot.profile 199243 2009-11-13 05:54:55Z ed $ +# +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:~/bin +export PATH +HOME=/root +export HOME +TERM=${TERM:-xterm} +export TERM +PAGER=more +export PAGER diff --git a/contrib/mfsbsd/mini/conf/hosts.sample b/contrib/mfsbsd/mini/conf/hosts.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/hosts.sample @@ -0,0 +1,6 @@ +# $Id$ +# +# The file will be the /etc/hosts file in your image +# +::1 localhost localhost.my.domain +127.0.0.1 localhost localhost.my.domain diff --git a/contrib/mfsbsd/mini/conf/loader.conf.sample b/contrib/mfsbsd/mini/conf/loader.conf.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/loader.conf.sample @@ -0,0 +1,4 @@ +mfs_load="YES" +mfs_type="mfs_root" +mfs_name="/mfsroot" +vfs.root.mountfrom="ufs:/dev/md0" diff --git a/contrib/mfsbsd/mini/conf/rc.local b/contrib/mfsbsd/mini/conf/rc.local new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/rc.local @@ -0,0 +1,6 @@ +#!/bin/sh +ldconfig /usr/local/lib +ln -s /usr/local/bin/dbclient /usr/bin/dbclient +ln -s /usr/local/bin/dbclient /usr/local/bin/ssh +mkdir -p /usr/local/etc/dropbear +/usr/local/sbin/dropbear -R diff --git a/contrib/mfsbsd/mini/conf/rc.sample b/contrib/mfsbsd/mini/conf/rc.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/rc.sample @@ -0,0 +1,40 @@ +#!/bin/sh +HOME=/ +PATH=/sbin:/bin/:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +export HOME PATH + +# REMOUT ROOT +mount -uw / + +# EXTRACT BOOT +tar -x -J -C / -f /.mfs_boot.txz + +# MOUNT TMPFS FILESYSTEMS +mount -t tmpfs tmpfs /tmp +mount -t tmpfs tmpfs /var +mount -t tmpfs tmpfs /usr/local + +# EXTRACT BASE and LOCAL +tar -x -J -C / -f /.mfs_base.txz +[ -f /.mfs_local.txz ] && tar -x -J -C /usr/local -f /.mfs_local.txz + +# VAR +mtree -deU -f /etc/mtree/BSD.var.dist -p /var > /dev/null +touch /var/log/utx.lastlogin /var/log/utx.log +cap_mkdb -f /tmp/termcap /etc/termcap.small + +# NETWORKING +ifconfig lo0 inet 127.0.0.1/8 +for i in `ifconfig -l`; do + if [ "$i" != "lo0" ]; then + dhclient $i + fi +done +hostname mfsbsd + +# SERVERS +newsyslog -C +syslogd -s + +# LOCAL +[ -f /etc/rc.local ] && . /etc/rc.local diff --git a/contrib/mfsbsd/mini/conf/ttys.sample b/contrib/mfsbsd/mini/conf/ttys.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/conf/ttys.sample @@ -0,0 +1,22 @@ +# $FreeBSD$ +# +console none unknown off secure +# +ttyv0 "/usr/libexec/getty Pc" xterm on secure +# Virtual terminals +ttyv1 "/usr/libexec/getty Pc" xterm off secure +ttyv2 "/usr/libexec/getty Pc" xterm off secure +ttyv3 "/usr/libexec/getty Pc" xterm off secure +ttyv4 "/usr/libexec/getty Pc" xterm off secure +ttyv5 "/usr/libexec/getty Pc" xterm off secure +ttyv6 "/usr/libexec/getty Pc" xterm off secure +ttyv7 "/usr/libexec/getty Pc" xterm off secure +ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure +# Serial terminals +# The 'dialup' keyword identifies dialin lines to login, fingerd etc. +ttyu0 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu1 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu2 "/usr/libexec/getty 3wire" vt100 onifconsole secure +ttyu3 "/usr/libexec/getty 3wire" vt100 onifconsole secure +# Dumb console +dcons "/usr/libexec/getty std.9600" vt100 off secure diff --git a/contrib/mfsbsd/mini/files/basedirs b/contrib/mfsbsd/mini/files/basedirs new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/basedirs @@ -0,0 +1,9 @@ +lib/geom +libexec +usr/libexec/bsdconfig +usr/libexec/bsdinstall +usr/share/bsdconfig +usr/share/locale/C.UTF-8 +usr/share/locale/en_US.UTF-8 +usr/share/syscons +usr/share/zoneinfo diff --git a/contrib/mfsbsd/mini/files/basefiles b/contrib/mfsbsd/mini/files/basefiles new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/basefiles @@ -0,0 +1,154 @@ +bin/domainname +bin/sleep +sbin/dhclient-script +sbin/geli +sbin/gnop +sbin/poweroff +sbin/resolvconf +sbin/rmd160 +sbin/sha1 +sbin/sha256 +sbin/sha512 +sbin/shutdown +lib/casper/libcap_dns.so* +lib/casper/libcap_fileargs.so* +lib/libalias* +lib/libbegemot.so* +lib/libbsdxml.so* +lib/libc.so* +lib/libcam.so* +lib/libcasper.so* +lib/libcrypt.so* +lib/libcrypto.so* +lib/libctf.so* +lib/libcxxrt.so* +lib/libdevstat.so* +lib/libedit.so* +lib/libelf.so* +lib/libgcc_s.so* +lib/libgeom.so* +lib/libibverbs.so* +lib/libipsec.so* +lib/libjail.so* +lib/libkiconv.so* +lib/libkvm.so* +lib/libm.so* +lib/libmd.so* +lib/libmlx5.so* +lib/libncursesw.so* +lib/libnv.so* +lib/libpcap.so* +lib/libsbuf.so* +lib/libssp.so* +lib/libthr.so* +lib/libufs.so* +lib/libulog.so* +lib/libutil.so* +lib/libxo.so* +lib/libz.so* +usr/bin/awk +usr/bin/basename +usr/bin/bc +usr/bin/cap_mkdb +usr/bin/cut +usr/bin/dc +usr/bin/b64decode +usr/bin/b64encode +usr/bin/dialog +usr/bin/dirname +usr/bin/du +usr/bin/false +usr/bin/fetch +usr/bin/file +usr/bin/find +usr/bin/grep +usr/bin/last +usr/bin/ldd +usr/bin/login +usr/bin/openssl +usr/bin/passwd +usr/bin/sort +usr/bin/top +usr/bin/touch +usr/bin/true +usr/bin/uname +usr/bin/uniq +usr/bin/uptime +usr/bin/uudecode +usr/bin/uuencode +usr/bin/w +usr/bin/wall +usr/bin/wc +usr/bin/which +usr/bin/who +usr/bin/xargs +usr/lib/libarchive.so* +usr/lib/libbsm.so* +usr/lib/libbz2.so* +usr/lib/libc++.so* +usr/lib/libcap_dns.so* +usr/lib/libcap_fileargs.so* +usr/lib/libdialog.so* +usr/lib/libdevctl.so* +usr/lib/libdevinfo.so* +usr/lib/libfetch.so* +usr/lib/liblzma.so* +usr/lib/libmagic.so* +usr/lib/libopie.so* +usr/lib/libpam.so* +usr/lib/libregex.so* +usr/lib/librt.so* +usr/lib/libssl.so* +usr/lib/libusb.so* +usr/lib/libypclnt.so* +usr/lib/pam_deny.so* +usr/lib/pam_group.so* +usr/lib/pam_lastlog.so* +usr/lib/pam_login_access.so* +usr/lib/pam_nologin.so* +usr/lib/pam_opie.so* +usr/lib/pam_opieaccess.so* +usr/lib/pam_permit.so* +usr/lib/pam_rootok.so* +usr/lib/pam_securetty.so* +usr/lib/pam_self.so* +usr/lib/pam_unix.so* +usr/libexec/getty +usr/sbin/acpidump +usr/sbin/arp +usr/sbin/bsdconfig +usr/sbin/bsdinstall +usr/sbin/boot0cfg +usr/sbin/cpucontrol +usr/sbin/cron +usr/sbin/daemon +usr/sbin/devctl +usr/sbin/devinfo +usr/sbin/diskinfo +usr/sbin/getextattr +usr/sbin/gstat +usr/sbin/jail +usr/sbin/jexec +usr/sbin/jls +usr/sbin/lsextattr +usr/sbin/mtree +usr/sbin/newsyslog +usr/sbin/ntpdate +usr/sbin/pciconf +usr/sbin/pw +usr/sbin/pwd_mkdb +usr/sbin/rmextattr +usr/sbin/sade +usr/sbin/setextattr +usr/sbin/syslogd +usr/sbin/tcpdump +usr/sbin/traceroute +usr/sbin/traceroute6 +usr/sbin/trim +usr/sbin/tzsetup +usr/sbin/usbconfig +usr/sbin/usbdump +usr/share/misc/iso3166 +usr/share/misc/termcap +usr/share/misc/magic +usr/share/misc/magic.mgc diff --git a/contrib/mfsbsd/mini/files/instdirs b/contrib/mfsbsd/mini/files/instdirs new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/instdirs @@ -0,0 +1,2 @@ +etc/pam.d +etc/security diff --git a/contrib/mfsbsd/mini/files/instfiles b/contrib/mfsbsd/mini/files/instfiles new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/instfiles @@ -0,0 +1,16 @@ +etc/crontab +etc/gettytab +etc/group +etc/hosts +etc/login.conf +etc/master.passwd +etc/mtree/BSD.var.dist +etc/newsyslog.conf +etc/nsswitch.conf +etc/passwd +etc/pwd.db +etc/services +etc/spwd.db +etc/syslog.conf +etc/termcap.small +etc/ttys diff --git a/contrib/mfsbsd/mini/files/localfiles b/contrib/mfsbsd/mini/files/localfiles new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/localfiles @@ -0,0 +1,20 @@ +bin/cpdup +bin/dbclient +bin/dbscp +bin/dropbearconvert +bin/dropbearkey +bin/ipmitool +bin/rsync +bin/nano +bin/tmux +lib/libevent-2.1.so* +lib/libiconv.so.* +lib/libintl.so.* +lib/liblz4.so.* +lib/libreadline.so.* +lib/libutf8proc.so.* +lib/libxxhash.so.* +lib/libzstd.so.* +sbin/dropbear +sbin/dmidecode +sbin/smartctl diff --git a/contrib/mfsbsd/mini/files/rescuelinks b/contrib/mfsbsd/mini/files/rescuelinks new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/mini/files/rescuelinks @@ -0,0 +1,140 @@ +rescue/sh +bin/ln +bin/sh +bin/[ +bin/cat +bin/chflags +bin/chio +bin/chmod +bin/cp +bin/csh +bin/date +bin/dd +bin/df +bin/echo +bin/ed +bin/expr +bin/getfacl +bin/hostname +bin/kenv +bin/kill +bin/link +bin/ls +bin/mkdir +bin/mv +bin/pgrep +bin/pkill +bin/ps +bin/pwd +bin/rcp +bin/realpath +bin/red +bin/rm +bin/rmdir +bin/setfacl +bin/stty +bin/sync +bin/tcsh +bin/test +bin/unlink +sbin/atmconfig +sbin/badsect +sbin/bsdlabel +sbin/camcontrol +sbin/ccdconfig +sbin/clri +sbin/devfs +sbin/dhclient +sbin/disklabel +sbin/dmesg +sbin/dump +sbin/dumpfs +sbin/dumpon +sbin/fastboot +sbin/fasthalt +sbin/fdisk +sbin/fsck +sbin/fsck_4.2bsd +sbin/fsck_ffs +sbin/fsck_msdosfs +sbin/fsck_ufs +sbin/fsdb +sbin/fsirand +sbin/gbde +sbin/geom +sbin/glabel +sbin/gpart +sbin/halt +sbin/ifconfig +sbin/init +sbin/ipf +sbin/kldconfig +sbin/kldload +sbin/kldstat +sbin/kldunload +sbin/ldconfig +sbin/md5 +sbin/mdconfig +sbin/mdmfs +sbin/mknod +sbin/mount +sbin/mount_cd9660 +sbin/mount_msdosfs +sbin/mount_nfs +sbin/mount_nullfs +sbin/mount_udf +sbin/mount_unionfs +sbin/newfs +sbin/newfs_msdos +sbin/nextboot +sbin/nos-tun +sbin/ping +sbin/ping6 +sbin/rcorder +sbin/rdump +sbin/reboot +sbin/restore +sbin/route +sbin/routed +sbin/rrestore +sbin/rtquery +sbin/rtsol +sbin/savecore +sbin/spppcontrol +sbin/swapon +sbin/sysctl +sbin/tunefs +sbin/umount +sbin/zfs +sbin/zpool +usr/bin/bunzip2 +usr/bin/bzcat +usr/bin/bzip2 +usr/bin/chgrp +usr/bin/ex +usr/bin/groups +usr/bin/gunzip +usr/bin/gzcat +usr/bin/gzip +usr/bin/head +usr/bin/id +usr/bin/less +usr/bin/lzcat +usr/bin/lzma +usr/bin/more +usr/bin/mt +usr/bin/nc +usr/bin/sed +usr/bin/tail +usr/bin/tar +usr/bin/tee +usr/bin/unlzma +usr/bin/unxz +usr/bin/vi +usr/bin/whoami +usr/bin/xz +usr/bin/xzcat +usr/bin/zcat +usr/sbin/chown +usr/sbin/chroot +usr/sbin/zdb diff --git a/contrib/mfsbsd/scripts/interfaces b/contrib/mfsbsd/scripts/interfaces new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/scripts/interfaces @@ -0,0 +1,38 @@ +#!/bin/sh +# $Id$ + +# PROVIDE: interfaces +# BEFORE: NETWORKING netif +# REQUIRE: mdinit mfsbsd +# KEYWORD: FreeBSD + +. /etc/rc.subr + +name="interfaces" +start_cmd="interfaces_start" +stop_cmd=":" + +interfaces_start() +{ + if [ -z "${mac_interfaces}" ]; then + exit 0 + fi + for if in ${mac_interfaces}; do + _cmac=`eval echo "\\$ifconfig_${if}_mac"` + if [ -n "$_cmac" ]; then + _dif=`/sbin/ifconfig -l | /usr/bin/sed -E 's/lo[0-9]+//g'` + for i in $_dif; do + _mac=`/sbin/ifconfig $i | /usr/bin/grep ether | /usr/bin/awk '{ print $2 }'` + if [ "$_mac" = "$_cmac" ]; then + _cif=`eval echo "\\$ifconfig_${if}"` + if [ -n "$_cif" ]; then + echo "ifconfig_$i=\"${_cif}\"" >> /etc/rc.conf.d/network + fi + fi + done + fi + done +} + +load_rc_config $name +run_rc_command "$1" diff --git a/contrib/mfsbsd/scripts/mdinit b/contrib/mfsbsd/scripts/mdinit new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/scripts/mdinit @@ -0,0 +1,36 @@ +#!/bin/sh +# $Id$ + +# PROVIDE: mdinit +# BEFORE: FILESYSTEMS +# REQUIRE: mountcritlocal +# KEYWORD: FreeBSD + +. /etc/rc.subr + +name="mdinit" +start_cmd="mdinit_start" +stop_cmd=":" + +mdinit_start() +{ + if [ -f /.usr.tar.xz ]; then + /sbin/mount -t tmpfs tmpfs /usr + /rescue/xz -d -c /.usr.tar.xz | /rescue/tar -x -C / -f - + elif [ -f /.usr.tar.bz2 ]; then + /sbin/mount -t tmpfs tmpfs /usr + /rescue/bzip2 -d -c /.usr.tar.bz2 | /rescue/tar -x -C / -f - + elif [ -f /.usr.tar.gz ]; then + /sbin/mount -t tmpfs tmpfs /usr + /rescue/gzip -d -c /.usr.tar.gz | /rescue/tar -x -C / -f - + fi + # Check if we are using roothack + if ! /sbin/mount -t tmpfs | /usr/bin/grep -q " /rw "; then + /sbin/mount -t tmpfs tmpfs /var/db/pkg + mkdir -p /var/cache/pkg + /sbin/mount -t tmpfs tmpfs /var/cache/pkg + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/contrib/mfsbsd/scripts/mfsbsd b/contrib/mfsbsd/scripts/mfsbsd new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/scripts/mfsbsd @@ -0,0 +1,87 @@ +#!/bin/sh +# $Id$ + +# PROVIDE: mfsbsd +# BEFORE: NETWORKING netif routing hostname +# REQUIRE: mountcritlocal mdinit +# KEYWORD: FreeBSD + +. /etc/rc.subr + +name="mfsbsd" +start_cmd="mfsbsd_start" +stop_cmd=":" + +mfsbsd_start() +{ + _hn=`/bin/kenv -q mfsbsd.hostname` + _clif=`/bin/kenv -q mfsbsd.cloned_interfaces` + _mif=`/bin/kenv -q mfsbsd.mac_interfaces` + _dhcp=`/bin/kenv -q mfsbsd.autodhcp` + _if=`/bin/kenv -q mfsbsd.interfaces` + _dr=`/bin/kenv -q mfsbsd.defaultrouter` + _sr=`/bin/kenv -q mfsbsd.static_routes` + _ns=`/bin/kenv -q mfsbsd.nameservers` + _rootpw=`/bin/kenv -q mfsbsd.rootpw` + _rootpwhash=`/bin/kenv -q mfsbsd.rootpwhash` + if [ -n "$_hn" ]; then + echo "hostname=\"$_hn\"" >> /etc/rc.conf.d/hostname + fi + if [ -n "$_clif" ]; then + echo "cloned_interfaces=\"$_clif\"" >> /etc/rc.conf.d/network + fi + if [ -n "$_mif" ]; then + echo "mac_interfaces=\"$_mif\"" >> /etc/rc.conf.d/interfaces + for i in $_mif; do + _mac=`/bin/kenv mfsbsd.ifconfig_${i}_mac` + if [ -n "$_mac" ]; then + echo "ifconfig_${i}_mac=\"$_mac\"" >> /etc/rc.conf.d/interfaces + fi + _config=`/bin/kenv mfsbsd.ifconfig_$i` + if [ -n "$_config" ]; then + echo "ifconfig_$i=\"$_config\"" >> /etc/rc.conf.d/interfaces + fi + done + fi + if [ -n "$_dhcp" ]; then + if `checkyesno _dhcp`; then + _dif=`/sbin/ifconfig -l | /usr/bin/sed -E 's/lo[0-9]+//g'` + for i in $_dif; do + echo "ifconfig_$i=\"DHCP\"" >> /etc/rc.conf.d/network + done + fi + fi + for i in $_if $_mif $_clif; do + _config=`/bin/kenv mfsbsd.ifconfig_$i` + if [ -n "$_config" ]; then + echo "ifconfig_$i=\"$_config\"" >> /etc/rc.conf.d/network + fi + done + if [ -n "$_dr" ]; then + echo "defaultrouter=\"$_dr\"" >> /etc/rc.conf.d/routing + fi + if [ -n "$_sr" ]; then + echo "static_routes=\"$_sr\"" >> /etc/rc.conf.d/routing + for i in $_sr; do + _config=`/bin/kenv mfsbsd.route_$i` + if [ -n "$_config" ]; then + echo "route_$i=\"$_config\"" >> /etc/rc.conf.d/routing + fi + done + fi + if [ -n "$_rootpw" ]; then + echo $_rootpw | /usr/sbin/pw usermod root -h 0 + /bin/kenv -u mfsbsd.rootpw + elif [ -n "$_rootpwhash" ]; then + echo $_rootpwhash | /usr/bin/sed -e 's,%,$,g' | /usr/sbin/pw usermod root -H 0 + /bin/kenv -u mfsbsd.rootpwhash + fi + if [ -n "$_ns" ]; then + for n in $_ns; do + echo "nameserver $n" >> /etc/resolv.conf + done + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/contrib/mfsbsd/scripts/packages b/contrib/mfsbsd/scripts/packages new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/scripts/packages @@ -0,0 +1,27 @@ +#!/bin/sh +# $Id$ + +# PROVIDE: packages +# BEFORE: LOGIN +# REQUIRE: mdinit tmp var +# KEYWORD: FreeBSD + +. /etc/rc.subr + +name="packages" +start_cmd="packages_start" +stop_cmd=":" + +packages_start() +{ + PACKAGES=`/bin/ls -1 /packages/*.t?z 2>/dev/null` + if /bin/test -n "$PACKAGES"; then + MD=`/sbin/mdconfig -a -t swap -s 64m` + /sbin/newfs -U /dev/$MD + /sbin/mount /dev/$MD /usr/local + cd /packages && /usr/sbin/pkg_add *.t?z > /dev/null 2> /dev/null + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/contrib/mfsbsd/tools/destroygeom b/contrib/mfsbsd/tools/destroygeom new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/tools/destroygeom @@ -0,0 +1,81 @@ +#!/bin/sh +# $Id$ +# +# mfsBSD ZFS pool and geom partition deleting +# +# Copyright (c) 2010-2011 Georges Discry +# Copyright (c) 2018 Martin Matuska + +usage () { + echo "Usage: $0 [-h] -d geom [-d geom ...] [-p zpool ...]" +} + +help () { + echo; echo "Destroy all partitions on geom provider(s)" + echo; echo "Required flags:" + echo "-d geom : geom provider(s) to clear" + echo;echo "Optional flags:" + echo "-p zpool : zpool(s) installed on the geom providers to clear" + echo;echo "Examples:" + echo "Destroy all partitions on ad4 and ad6:" + echo "$0 -d ad4 -d ad6" + echo "Destroy ZFS pool tank and all partitions on ada0:" + echo "$0 -p tank -d ada0" +} + +while getopts d:p:h o; do + case "$o" in + d) DEVS="$DEVS ${OPTARG##/dev/}" ;; + p) POOLS="$POOLS ${OPTARG}" ;; + h) help; exit 1;; + [?]) usage; exit 1;; + esac +done + +if [ -z "$DEVS" ]; then + usage + exit 1 +fi + + +for DEV in ${DEVS}; do + if ! [ -c "/dev/${DEV}" ]; then + echo "error: /dev/${DEV} is not a block device" + exit 1 + fi +done + +for POOL in ${POOLS}; do + if ! /sbin/zpool list -H ${POOL} > /dev/null 2> /dev/null; then + echo "warning: pool does not exist" + continue + fi + + echo -n "Destroying ZFS pool ${POOL} ..." + if ! /sbin/zpool destroy -f ${POOL} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + echo " done" +done + + +for DEV in ${DEVS}; do + GEOMS=`/sbin/gpart show | /usr/bin/tail -r | /usr/bin/grep '=>' | /usr/bin/awk '{print $4}' | /usr/bin/grep "^${DEV}" | /usr/bin/uniq` + for GEOM in ${GEOMS}; do + echo "Destroying geom ${GEOM}:" + PARTS=`/sbin/gpart show ${GEOM} | /usr/bin/grep -v '=>\|- free -' | /usr/bin/awk '{if ($3 ~ /[0-9]+/) print $3}' | /usr/bin/sort -n | /usr/bin/uniq` + for PART in ${PARTS}; do + echo -n " Deleting partition ${PART} ..." + if ! /sbin/gpart delete -i${PART} ${GEOM} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + echo " done" + done + if ! /sbin/gpart destroy ${GEOM} > /dev/null 2> /dev/null; then + echo "error: could not destroy geom ${GEOM}" + exit 1 + fi + done +done diff --git a/contrib/mfsbsd/tools/doFS.sh b/contrib/mfsbsd/tools/doFS.sh new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/tools/doFS.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# $FreeBSD: src/release/scripts/doFS.sh,v 1.60 2004/08/25 01:39:52 kensmith Exp $ +# + +set -ex + +export BLOCKSIZE=512 + +DISKLABEL=$1; shift +MACHINE=${1:+"-m $1"}; shift +FSIMG=$1; shift +RD=$1 ; shift +MNT=$1 ; shift +FSSIZE=$1 ; shift +FSPROTO=$1 ; shift +FSINODE=$1 ; shift +FSLABEL=$1 ; shift + +# +# If we've been told to, compute the required file system size +# and average inode size automatically. +# +if [ ${FSSIZE} -eq 0 -a ${FSLABEL} = "auto" ]; then + roundup() echo $((($1+$2-1)-($1+$2-1)%$2)) + nf=$(find ${FSPROTO} |wc -l) + sk=$(du -skA ${FSPROTO} |cut -f1) + FSINODE=$(roundup $(($sk*1024/$nf)) ${FSINODE}) + FSSIZE=$(roundup $(($sk*12/10)) 1024) +fi + +dofs_vn () { + if [ "x$VNDEVICE" = "x" ] ; then + VNDEVICE=vn0 + fi + u=`expr $VNDEVICE : 'vn\([0-9]*\)' || true` + VNDEVICE=vnn$u + + rm -f /dev/*vnn* + mknod /dev/rvnn${u} c 43 `expr 65538 + $u '*' 8` + mknod /dev/rvnn${u}a c 43 `expr 2 + $u '*' 8` + mknod /dev/vnn${u} b 15 `expr 65538 + $u '*' 8` + mknod /dev/vnn${u}a b 15 `expr 2 + $u '*' 8` + + umount /dev/${VNDEVICE} 2>/dev/null || true + umount ${MNT} 2>/dev/null || true + vnconfig -u /dev/r${VNDEVICE} 2>/dev/null || true + + vnconfig -s labels -c /dev/r${VNDEVICE} ${FSIMG} + + trap "umount ${MNT}; vnconfig -u /dev/r${VNDEVICE}; rm -f /dev/*vnn*" EXIT + + disklabel -w ${BOOT} ${VNDEVICE} ${FSLABEL} + newfs -i ${FSINODE} -o space -m 0 /dev/r${VNDEVICE}a + + mount -o async /dev/${VNDEVICE}a ${MNT} +} + +dofs_md () { + if [ "x${MDDEVICE}" != "x" ] ; then + umount /dev/${MDDEVICE} 2>/dev/null || true + umount ${MNT} 2>/dev/null || true + mdconfig -d -u ${MDDEVICE} 2>/dev/null || true + fi + + MDDEVICE=`mdconfig -a -t vnode -f ${FSIMG}` + if [ ! -c /dev/${MDDEVICE} ] ; then + echo "No /dev/$MDDEVICE" 1>&2 + exit 1 + fi + + trap "umount ${MNT}; mdconfig -d -u ${MDDEVICE}" EXIT + + if [ "x${DISKLABEL}" != "x" ] ; then + ${DISKLABEL} ${MACHINE} -w ${BOOT} ${MDDEVICE} ${FSLABEL} + newfs -O2 -i ${FSINODE} -o space -m 0 /dev/${MDDEVICE}a + mount -o async /dev/${MDDEVICE}a ${MNT} + else + newfs -O2 -i ${FSINODE} -o space -m 0 /dev/${MDDEVICE} + mount -o async /dev/${MDDEVICE} ${MNT} + fi +} + +rm -f ${FSIMG} +dd of=${FSIMG} if=/dev/zero count=${FSSIZE} bs=1k 2>/dev/null + +# +# We don't have any bootblocks on ia64. Note that -B implies -r, +# so we have to specifically specify -r when we don't have -B. +# bsdlabel fails otherwise. +# +case `uname -r` in +4.*) + if [ -f "${RD}/trees/base/boot/boot1" ]; then + BOOT="-B -b ${RD}/trees/base/boot/boot1" + if [ -f "${RD}/trees/base/boot/boot2" ]; then + BOOT="${BOOT} -s ${RD}/trees/base/boot/boot2" + fi + else + BOOT="-r" + fi + dofs_vn + ;; +*) + if [ -f "${RD}/trees/base/boot/boot" ]; then + BOOT="-B -b ${RD}/trees/base/boot/boot" + else + BOOT="-r" + fi + dofs_md + ;; +esac + +if [ -d ${FSPROTO} ]; then + ABS=`cd ${MNT} && pwd` + (set -e && cd ${FSPROTO} && find . -print | cpio -dump ${ABS}) +else + cp -p ${FSPROTO} ${MNT} +fi + +df -ki ${MNT} + +set `df -ki ${MNT} | tail -1` + +echo "*** File system is ${FSSIZE} K, $4 left" +echo "*** ${FSINODE} bytes/inode, $7 left" diff --git a/contrib/mfsbsd/tools/do_gpt.sh b/contrib/mfsbsd/tools/do_gpt.sh new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/tools/do_gpt.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# +set -e + +FSIMG=$1 +FSPROTO=$2 +FSSIZE=$3 +BOOTDIR=$4 +EFIIMG=$5 +VERBOSE=$6 + +FSLABEL="auto" + + +exit_with() { + local status="$1" + shift + + if [ -n "$@" ]; then + echo + echo "$@" + fi + + mdconfig -d -u ${unit} + rm -f ${TMPIMG} + + exit ${status} +} + +#Trap the killer signals so that we can exit with a good message. +trap "exit_with 1 'Received signal SIGHUP'" SIGHUP +trap "exit_with 1 'Received signal SIGINT'" SIGINT +trap "exit_with 1 'Received signal SIGTERM'" SIGTERM + +if [ ${FSSIZE} -eq 0 -a ${FSLABEL} = "auto" ]; then + roundup() echo $((($1+$2-1)-($1+$2-1)%$2)) + nf=$(find ${FSPROTO} |wc -l) + sk=$(du -skA ${FSPROTO} |cut -f1) + FSSIZE=$(roundup $(($sk*12/10)) 1024) + IMG_SIZE=$((${FSSIZE}+32)) +fi + +if [ -n "$VERBOSE" ]; then + echo "FSIMG ${FSIMG} FSPROTO ${FSPROTO} FSSIZE ${FSSIZE}" +fi + +TMPIMG=`env TMPDIR=. mktemp -t ${FSIMG}` + +dd of=${FSIMG} if=/dev/zero count=${IMG_SIZE} bs=1k +dd of=${TMPIMG} if=/dev/zero count=${FSSIZE} bs=1k + +export unit=`mdconfig -a -t vnode -f ${FSIMG}` +if [ $? -ne 0 ]; then + echo "mdconfig failed" + exit 1 +fi + +if [ -n "$VERBOSE" ]; then + TIME=time + set -x +else + TIME= +fi + +gpart create -s gpt ${unit} +gpart add -t freebsd-boot -b 40 -l boot -s 472 ${unit} +gpart bootcode -b ${BOOTDIR}/pmbr -p ${BOOTDIR}/gptboot -i 1 ${unit} +if [ -n "${EFIIMG}" -a -f "${EFIIMG}" ]; then + gpart add -t efi -s 2m ${unit} + ${TIME} dd if=${EFIIMG} of=/dev/${unit}p2 bs=128k +fi +gpart add -t freebsd-ufs -l rootfs ${unit} +${TIME} makefs -B little ${TMPIMG} ${FSPROTO} +if [ -f ${EFIIMG} ]; then + ${TIME} dd if=${TMPIMG} of=/dev/${unit}p3 bs=128k +else + ${TIME} dd if=${TMPIMG} of=/dev/${unit}p2 bs=128k +fi + +if [ -n "$VERBOSE" ]; then + set +x +fi +if [ $? -ne 0 ]; then + echo "makefs failed" + exit_with 1 +fi + +exit_with 0 + diff --git a/contrib/mfsbsd/tools/kern_exclude b/contrib/mfsbsd/tools/kern_exclude new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/kern_exclude @@ -0,0 +1,3 @@ +kernel.debug +*.symbols +*.ko diff --git a/contrib/mfsbsd/tools/motd b/contrib/mfsbsd/tools/motd new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/motd @@ -0,0 +1,10 @@ +Welcome to mfsBSD, the memory based FreeBSD distribution. + +This is a stripped-down version of FreeBSD without: +- manual pages, info pages, examples +- include files, static library files, development tools +- bind binaries (host, dig, named, etc.) + +Feel free to email me with any bug reports or feature suggestions. +Martin Matuska +http://mfsbsd.vx.sk/ diff --git a/contrib/mfsbsd/tools/motd.se b/contrib/mfsbsd/tools/motd.se new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/motd.se @@ -0,0 +1,16 @@ +Welcome to mfsBSD SE, the memory based FreeBSD distribution. +This is a special version intended for full-ZFS install of FreeBSD + +To make a full-ZFS FreeBSD install from this ISO: + +1. Mount the CD device +( e.g. mount_cd9660 /dev/cd0 /cdrom ) +2. Run "zfsinstall" with path to release directory and your drive +( e.g. zfsinstall -d ada0 -u /cdrom/9.2-RELEASE-amd64 ) + +Run zfsinstall with the -h flag for help or without flags for options. +I recommend creating a GPT swap partition (e.g. -s 2G for a 2GB swap). + +Feel free to email me with any bug reports or feature suggestions. +Martin Matuska +http://mfsbsd.vx.sk/ diff --git a/contrib/mfsbsd/tools/packages-mini.sample b/contrib/mfsbsd/tools/packages-mini.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/packages-mini.sample @@ -0,0 +1 @@ +dropbear diff --git a/contrib/mfsbsd/tools/packages.sample b/contrib/mfsbsd/tools/packages.sample new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/packages.sample @@ -0,0 +1,12 @@ +cpdup +dmidecode +indexinfo +ipmitool +libevent +libiconv +nano +readline +rsync +smartmontools +tmux +utf8proc diff --git a/contrib/mfsbsd/tools/prunelist b/contrib/mfsbsd/tools/prunelist new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/prunelist @@ -0,0 +1,81 @@ +usr/bin/c++ +usr/bin/c++filt +usr/bin/g++ +usr/bin/c89 +usr/bin/c99 +usr/bin/CC +usr/bin/cc +usr/bin/clang +usr/bin/clang++ +usr/bin/clang-cpp +usr/bin/clang-tblgen +usr/bin/cpp +usr/bin/gcc +usr/bin/yacc +usr/bin/f77 +usr/bin/byacc +usr/bin/addr2line +usr/bin/ar +usr/bin/gnu-ar +usr/bin/gnu-ranlib +usr/bin/as +usr/bin/gasp +usr/bin/gcov +usr/bin/gdb +usr/bin/gdbreplay +usr/bin/kyua +usr/bin/ld +usr/bin/ld.bfd +usr/bin/ld.lld +usr/bin/lldb +usr/bin/lldb-tblgen +usr/bin/llvm-addr2line +usr/bin/llvm-ar +usr/bin/llvm-cov +usr/bin/llvm-cxxfilt +usr/bin/llvm-nm +usr/bin/llvm-objdump +usr/bin/llvm-profdata +usr/bin/llvm-ranlib +usr/bin/llvm-symbolizer +usr/bin/llvm-tblgen +usr/bin/nm +usr/bin/objcopy +usr/bin/objdump +usr/bin/ranlib +usr/bin/readelf +usr/bin/size +usr/bin/strip +usr/bin/svnlite +usr/bin/svnliteadmin +usr/bin/svnlitebench +usr/bin/svnlitedumpfilter +usr/bin/svnlitefsfs +usr/bin/svnlitelook +usr/bin/svnlitemucc +usr/bin/svnliterdump +usr/bin/svnliteserve +usr/bin/svnlitesync +usr/bin/svnliteversion +usr/bin/gdbtui +usr/bin/kgdb +usr/games +usr/include +usr/lib32 +usr/lib/*.a +usr/lib/clang +usr/lib/private/*.a +usr/lib/private/libunbound* +usr/libexec/cc1 +usr/libexec/cc1obj +usr/libexec/cc1plus +usr/libexec/f771 +usr/sbin/unbound* +usr/share/dict +usr/share/doc +usr/share/examples +usr/share/info +usr/share/games +usr/share/man +usr/share/openssl +usr/share/nls diff --git a/contrib/mfsbsd/tools/prunelist.9 b/contrib/mfsbsd/tools/prunelist.9 new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/prunelist.9 @@ -0,0 +1,67 @@ +usr/bin/c++ +usr/bin/c++filt +usr/bin/g++ +usr/bin/c89 +usr/bin/c99 +usr/bin/CC +usr/bin/cc +usr/bin/clang +usr/bin/clang++ +usr/bin/clang-cpp +usr/bin/clang-tblgen +usr/bin/cpp +usr/bin/gcc +usr/bin/yacc +usr/bin/f77 +usr/bin/byacc +usr/bin/addr2line +usr/bin/ar +usr/bin/gnu-ar +usr/bin/gnu-ranlib +usr/bin/as +usr/bin/gasp +usr/bin/gdb +usr/bin/gdbreplay +usr/bin/ld +usr/bin/nm +usr/bin/objcopy +usr/bin/objdump +usr/bin/ranlib +usr/bin/readelf +usr/bin/size +usr/bin/strip +usr/bin/gdbtui +usr/bin/kgdb +usr/include +usr/games +usr/lib32 +usr/lib/*.a +usr/lib/private/*.a +usr/libexec/cc1 +usr/libexec/cc1obj +usr/libexec/cc1plus +usr/libexec/f771 +usr/share/dict +usr/share/doc +usr/share/examples +usr/share/info +usr/share/games +usr/share/man +usr/share/openssl +usr/share/nls +usr/bin/dig +usr/bin/host +usr/bin/nslookup +usr/bin/nsupdate +usr/sbin/dnssec-dsfromkey +usr/sbin/dnssec-signzone +usr/sbin/lwresd +usr/sbin/named +usr/sbin/named-checkconf +usr/sbin/named-checkzone +usr/sbin/named-compilezone +usr/sbin/dnssec-keygen +usr/sbin/dnssec-keyfromlabel +usr/sbin/rndc-confgen +usr/sbin/named-reconfig +usr/sbin/named-reload diff --git a/contrib/mfsbsd/tools/roothack/Makefile b/contrib/mfsbsd/tools/roothack/Makefile new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/roothack/Makefile @@ -0,0 +1,10 @@ +PROG= roothack +MAN= + +LDADD= -larchive -lbz2 -lz -llzma -lcrypto -lbsdxml -lmd -lprivatezstd + +NO_SHARED= + +WARNS= 6 + +.include diff --git a/contrib/mfsbsd/tools/roothack/roothack.c b/contrib/mfsbsd/tools/roothack/roothack.c new file mode 100644 --- /dev/null +++ b/contrib/mfsbsd/tools/roothack/roothack.c @@ -0,0 +1,176 @@ +/*- + * Copyright (c) 2010-2012 Ed Schouten + * 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 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 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static void +die(const char *msg) +{ + int fd, serrno; + + serrno = errno; + fd = open("/dev/console", O_RDWR); + if (fd != -1 && fd != STDERR_FILENO) + dup2(fd, STDERR_FILENO); + errno = serrno; + perror(msg); + sleep(10); + exit(1); +} + +static void +domount(const char * const list[], unsigned int elems) +{ + struct iovec iov[elems]; + unsigned int i; + + for (i = 0; i < elems; i++) { + iov[i].iov_base = __DECONST(char *, list[i]); + iov[i].iov_len = strlen(list[i]) + 1; + } + + if (nmount(iov, elems, 0) != 0) + die(list[1]); +} + +static int +copy_data(struct archive *ar, struct archive *aw) +{ + int r; + const void *buff; + size_t size; + off_t offset; + + for (;;) { + r = archive_read_data_block(ar, &buff, &size, &offset); + if (r == ARCHIVE_EOF) + return (ARCHIVE_OK); + if (r != ARCHIVE_OK) + return (r); + r = archive_write_data_block(aw, buff, size, offset); + if (r != ARCHIVE_OK) { + die(archive_error_string(aw)); + return (r); + } + } +} + +static void +extract(const char *filename) +{ + struct archive *a; + struct archive *ext; + struct archive_entry *entry; + int flags; + int r; + + flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM; + + a = archive_read_new(); + archive_read_support_format_all(a); +#if ARCHIVE_VERSION_NUMBER < 3000000 + archive_read_support_compression_all(a); +#else + archive_read_support_filter_all(a); +#endif + ext = archive_write_disk_new(); + archive_write_disk_set_options(ext, flags); + archive_write_disk_set_standard_lookup(ext); +#if ARCHIVE_VERSION_NUMBER < 3000000 + if ((r = archive_read_open_file(a, filename, 10240))) + die("archive_read_open_file"); +#else + if ((r = archive_read_open_filename(a, filename, 10240))) + die("archive_read_open_filename"); +#endif + for (;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_EOF) + break; + if (r < ARCHIVE_WARN) + die(archive_error_string(a)); + r = archive_write_header(ext, entry); + if (r == ARCHIVE_OK && archive_entry_size(entry) > 0) { + r = copy_data(a, ext); + if (r < ARCHIVE_WARN) + die(archive_error_string(a)); + } + r = archive_write_finish_entry(ext); + if (r < ARCHIVE_WARN) + die(archive_error_string(ext)); + } + archive_read_close(a); + archive_read_free(a); + archive_write_close(ext); + archive_write_free(ext); +} + +static char const * const tmpfs[] = { + "fstype", "tmpfs", "fspath", "/rw" +}; +static char const * const devfs[] = { + "fstype", "devfs", "fspath", "/rw/dev" +}; + +int +main(int argc __unused, char *argv[]) +{ + + /* Prevent foot shooting. */ + if (getpid() != 1) + return (1); + + if (modfind("tmpfs") == -1 && kldload("tmpfs") == -1) + die("error loading tmpfs"); + + /* Extract FreeBSD installation in a tmpfs. */ + domount(tmpfs, sizeof(tmpfs) / sizeof(char *)); + extract("/root.txz"); + domount(devfs, sizeof(devfs) / sizeof(char *)); + + /* chroot() into system and continue boot process. */ + if (chroot("/rw") != 0) + die("chroot"); + chdir("/"); + + /* Execute the real /sbin/init. */ + execv(argv[0], argv); + die("execv"); + return (1); +} diff --git a/contrib/mfsbsd/tools/zfsinstall b/contrib/mfsbsd/tools/zfsinstall new file mode 100755 --- /dev/null +++ b/contrib/mfsbsd/tools/zfsinstall @@ -0,0 +1,501 @@ +#!/bin/sh +# $Id$ +# +# mfsBSD ZFS install script +# Copyright (c) 2018 Martin Matuska +# +FREEBSD_MIRROR="${FREEBSD_MIRROR:-ftp://ftp.freebsd.org/pub/FreeBSD}" +FS_LIST="var tmp" +RAID_TYPES="mirror raidz raidz1 raidz2 raidz3" + +usage() { + echo "Usage: $0 [-h] -d geom_provider [-d geom_provider ...] [ -u dist_url ] [-r mirror|raidz[1|2|3]] [-m mount_point] [-p zfs_pool_name] [-s swap_partition_size] [-z zfs_partition_size] [-c] [-C] [-l] [-4] [-A]" +} + +osarch() { + /sbin/sysctl -n hw.machine_arch +} + +osrelease() { + /sbin/sysctl -n kern.osrelease | /usr/bin/sed -E -e 's,-p[0-9]+$,,g' +} + +check_raid() { + RAID_TYPE="$1" + test -n "$RAID_TYPE" || return 1 + + for raid_type in $RAID_TYPES; do + if [ "$raid_type" = $RAID_TYPE ]; then + return 0 + fi + done + + return 1 +} + +help() { + echo; echo "Install FreeBSD using ZFS from a compressed archive" + echo; echo "Required flags:" + echo "-d geom_provider : geom provider(s) to install to (e.g. da0)" + echo; echo "Optional flags:" + echo "-r raidz[1|2|3]|mirror : select raid mode if more than one -d provider given" + echo " (must begin after -d)" + echo "-u dist_url : URL or directory with base.txz and kernel.txz" + echo " (defaults to FreeBSD FTP mirror)" + echo "-s swap_part_size : create a swap partition with given size (default: no swap)" + echo "-z zfs_part_size : create zfs parition of this size (default: all space left)" + echo "-p pool_name : specify a name for the ZFS pool (default: tank)" + echo "-C : compatibility mode with limited feature flags" + echo " (enable only async_destroy, empty_bpobj and lz4_compress)" + echo "-m mount_point : use this mount point for operations (default: /mnt)" + echo "-c : enable compression for all datasets" + echo "-l : use legacy mounts (via fstab) instead of ZFS mounts" + echo "-4 : use fletcher4 as default checksum algorithm" + echo "-A : align partitions to 4K blocks" + echo; echo "Examples:" + echo "Install on a single drive with 2GB swap:" + echo "$0 -u /path/to/release -d da0 -s 2G" + echo "Install on four-disk stripe:" + echo "$0 -u /path/to/release -d da0 -d da1 -d da2 -d da3" + echo "Install on an stripped mirror:" + echo "$0 -u /path/to/release -d da0 -d da1 -r mirror -d da2 -d da3 -r mirror" + echo "Install on a raidz2:" + echo "$0 -u /path/to/release -d da0 -d da1 -d da2 -d da3 -r raidz2" + echo "Install on a mirror without swap, pool name rpool:" + echo "$0 -u /path/to/release -d da0 -d da1 -r mirror -p rpool" + echo; echo "Notes:" + echo "When using swap and raidz/mirror, the swap partition is created on all drives." + echo "The /etc/fstab entry will contatin only the first drive's swap partition." + echo "You can enable all swap partitions and/or make a gmirror-ed swap later." +} + +while getopts d:u:t:r:p:s:z:m:V:Chcl4A o; do + case "$o" in + d) DEVS="$DEVS ${OPTARG##/dev/}"; ZDEVS="$ZDEVS ${OPTARG##/dev/}" ;; + u) URL="${OPTARG}" ;; + t) ARCHIVE="${OPTARG}" ;; + p) POOL="${OPTARG}" ;; + s) SWAP="${OPTARG}" ;; + m) MNT="${OPTARG}" ;; + r) + if [ -z "${ZDEVS}" ]; then + echo "Error: geom providers must be defined before using \ + this option" + usage + exit 1 + fi + + if [ -n "${RAID}" -a "${RAID}" != "${OPTARG}" ]; then + echo "Error: array types do not match" + exit 1 + else + RAID="${OPTARG}" + fi + + if ! check_raid "$RAID"; then + echo "Error: please choose raid mode with the -r switch (mirror or raidz[1|2|3])" + exit 1 + fi + + COUNT=`echo ${ZDEVS} | /usr/bin/wc -w | /usr/bin/awk '{ print $1 }'` + if [ "$COUNT" -lt "3" ] && [ "$RAID" = "raidz" -o "$RAID" = "raidz1" ]; then + echo "Error: raidz needs at least three devices (-d switch)" + exit 1 + elif [ "$COUNT" -lt "4" -a "$RAID" = "raidz2" ]; then + echo "Error: raidz2 needs at least four devices (-d switch)" + exit 1 + elif [ "$COUNT" -lt "5" -a "$RAID" = "raidz3" ]; then + echo "Error: raidz3 needs at least five devices (-d switch)" + exit 1 + elif [ "$COUNT" = "1" -a "$RAID" = "mirror" ]; then + echo "Error: mirror needs at least two devices (-d switch)" + exit 1 + fi + + ZARRAY="${ZARRAY} ${RAID} ${ZDEVS}" + + unset ZDEVS + ;; + z) ZPART="${OPTARG}" ;; + V) VERSION="${OPTARG}" ;; + C) COMPAT=1 ;; + c) COMPRESS=1 ;; + l) LEGACY=1 ;; + 4) FLETCHER=1 ;; + A) ALIGN=1 ;; + h) help; exit 1;; + [?]) usage; exit 1;; +esac +done + +if ! `/sbin/kldstat -m zfs >/dev/null 2>/dev/null`; then + /sbin/kldload zfs >/dev/null 2>/dev/null +fi + +ZFS_VERSION=`/sbin/sysctl -n vfs.zfs.version.spa 2>/dev/null` + +if [ -z "$ZFS_VERSION" ]; then + echo "Error: failed to load ZFS module" + exit 1 +elif [ "$ZFS_VERSION" -lt "13" ]; then + echo "Error: ZFS module too old, version 13 or higher required" + exit 1 +fi + +if [ -z "$DEVS" ]; then + usage + exit 1 +fi + +if [ -z "$POOL" ]; then + POOL=tank +fi + +if [ -z "$VERSION" ]; then + VERSION=${ZFS_VERSION} +elif [ "$VERSION" -gt "$ZFS_VERSION" ]; then + echo "Error: invalid ZFS pool version (maximum: $ZFS_VERSION)" + exit 1 +fi + +if [ "$VERSION" = "5000" ]; then + VERSION= +else + VERSION="-o version=${VERSION}" +fi + +if [ "$COMPAT" = "1" ]; then + if [ "$ZFS_VERSION" != 5000 ]; then + echo "Error: compatibility mode requires ZFS version 5000" + exit 1 + fi + COMPATFLAGS="-d -o feature@async_destroy=enabled -o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled" +fi + +if [ "$ALIGN" = "1" ]; then + ALIGNMENT="-a 4096" +fi + +if /sbin/zpool list $POOL > /dev/null 2> /dev/null; then + echo Error: ZFS pool \"$POOL\" already exists + echo Please choose another pool name or rename/destroy the existing pool. + exit 1 +fi + +EXPOOLS=`/sbin/zpool import 2> /dev/null | /usr/bin/grep pool: | /usr/bin/awk '{ print $2 }'` + +if [ -n "${EXPOOLS}" ]; then + for P in ${EXPOOLS}; do + if [ "$P" = "$POOL" ]; then + echo Error: An exported ZFS pool \"$POOL\" already exists + echo Please choose another pool name or rename/destroy the exported pool. + exit 1 + fi + done +fi + +if [ -z "${ZARRAY}" ]; then + echo Notice: no raid type has been chosen, it will be \`stripe\` + ZARRAY="${DEVS}" +fi + +for DEV in ${DEVS}; do + if ! [ -c "/dev/${DEV}" ]; then + echo "Error: /dev/${DEV} is not a block device" + exit 1 + fi + if /sbin/gpart show $DEV > /dev/null 2> /dev/null; then + echo "Error: /dev/${DEV} already contains a partition table." + echo "" + /sbin/gpart show $DEV + echo "You may erase the partition table manually with the destroygeom command" + exit 1 + fi +done + +EXTRACT_FILES="/tmp/base.txz /tmp/kernel.txz" + +if [ -z "${URL}" ]; then + if [ -z "${ARCHIVE}" ]; then + URL="${FREEBSD_MIRROR}/releases/$(osarch)/$(osrelease)" + elif ! [ -f "${ARCHIVE}" ]; then + echo "Error: file $ARCHIVE does not exist" + exit 1 + else + EXTRACT_FILES=${ARCHIVE} + fi +else + if [ -d "${URL}" ]; then + for file in base.txz kernel.txz; do + if ! [ -f "${URL}/${file}" ]; then + echo "File not found: ${URL}/${file}" + exit 1 + fi + done + EXTRACT_FILES="${URL}/base.txz ${URL}/kernel.txz" + fi +fi + +if [ -z "$MNT" ]; then + MNT=/mnt +fi + +if ! [ -d "${MNT}" ]; then + echo "Error: $MNT is not a directory" + exit 1 +fi + +if [ -n "${ZPART}" ]; then + SZPART="-s ${ZPART}" +fi + +if [ "${LEGACY}" = "1" ]; then + ALTROOT= + ROOTMNT=legacy +else + ALTROOT="-o altroot=${MNT} -o cachefile=/boot/zfs/zpool.cache" + ROOTMNT=/ +fi + +# Fetch base.txz and kernel.txz + +if [ -n "${URL}" -a ! -d "${URL}" ]; then + echo "Fetching base files from: $URL" + if ! /usr/bin/fetch -o /tmp/base.txz "${URL}/base.txz"; then + echo "Error fetching ${URL}/base.txz" + exit 1 + elif ! /usr/bin/fetch -o /tmp/kernel.txz "${URL}/kernel.txz"; then + echo "Error fetching ${URL}/kernel.txz" + exit 1 + fi +fi + +# Create GPT + +for DEV in ${DEVS}; do + echo -n "Creating GUID partitions on ${DEV} ..." + if ! /sbin/gpart create -s GPT /dev/${DEV} > /dev/null; then + echo " error" + exit 1 + fi + /bin/sleep 1 + if ! echo "a 1" | /sbin/fdisk -f - ${DEV} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + if ! /sbin/gpart add -t freebsd-boot -b 40 -s 472 ${DEV} > /dev/null; then + echo " error" + exit 1 + fi + if [ -n "${SWAP}" ]; then + if ! /sbin/gpart add -t freebsd-swap ${ALIGNMENT} -s "${SWAP}" ${DEV} > /dev/null; then + echo " error" + exit 1 + fi + SWAPPART=`/sbin/glabel status ${DEV}p2 | /usr/bin/grep gptid | /usr/bin/awk '{ print $1 }'` + if [ -z "$SWAPPART" ]; then + echo " error determining swap partition" + fi + if [ -z "$FSWAP" ]; then + FSWAP=${SWAPPART} + fi + fi + if ! /sbin/gpart add -t freebsd-zfs ${ALIGNMENT} ${SZPART} ${DEV} > /dev/null; then + echo " error" + exit 1 + fi + /bin/dd if=/dev/zero of=/dev/${DEV}p2 bs=512 count=560 > /dev/null 2> /dev/null + if [ -n "${SWAP}" ]; then + /bin/dd if=/dev/zero of=/dev/${DEV}p3 bs=512 count=560 > /dev/null 2> /dev/null + fi + echo " done" + + echo -n "Configuring ZFS bootcode on ${DEV} ..." + if ! /sbin/gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${DEV} > /dev/null; then + echo " error" + exit 1 + fi + echo " done" + /sbin/gpart show ${DEV} +done + +# Create zpool and zfs + +for DEV in ${ZARRAY}; do + if check_raid "${DEV}"; then + if [ -n "${_PARTS}" ]; then + ZPARTS="${ZPARTS} ${RAID} ${_PARTS}" + + unset _PARTS + fi + continue + fi + + PART=`/sbin/gpart show ${DEV} | /usr/bin/grep freebsd-zfs | /usr/bin/awk '{ print $3 }'` + + if [ -z "${PART}" ]; then + echo Error: freebsd-zfs partition not found on /dev/$DEV + exit 1 + fi + + GPART=`/sbin/glabel list ${DEV}p${PART} | /usr/bin/grep gptid | /usr/bin/awk -F"gptid/" '{ print "gptid/" $2 }'` + + GPARTS="${GPARTS} ${GPART}" + PARTS="${PARTS} ${DEV}p${PART}" + _PARTS="${_PARTS} ${DEV}p${PART}" +done +ZPARTS="${ZPARTS} ${RAID} ${_PARTS}" + +echo -n "Creating ZFS pool ${POOL} on ${PARTS} ..." +if ! /sbin/zpool create -f -m none ${ALTROOT} ${COMPATFLAGS} ${VERSION} ${POOL} ${ZPARTS} > /dev/null 2> /dev/null; then + echo " error" + exit 1 +fi +echo " done" + +if [ "${FLETCHER}" = "1" ]; then + echo -n "Setting default checksum to fletcher4 for ${POOL} ..." + if ! /sbin/zfs set checksum=fletcher4 ${POOL} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + echo " done" +fi + +if [ "${COMPRESS}" = "1" ]; then + echo -n "Enabling default compression on ${POOL} ..." + if ! /sbin/zfs set compression=on ${POOL} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + echo " done" +fi + +echo -n "Creating ${POOL} root partition:" +if ! /sbin/zfs create -o mountpoint=${ROOTMNT} ${POOL}/root > /dev/null 2> /dev/null; then + echo " error" + exit 1 +fi +echo " ... done" +echo -n "Creating ${POOL} partitions:" +for FS in ${FS_LIST}; do + if [ "${LEGACY}" = 1 ]; then + MNTPT="-o mountpoint=legacy" + else + MNTPT= + fi + if ! /sbin/zfs create ${MNTPT} ${POOL}/root/${FS} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi + echo -n " ${FS}" +done +echo " ... done" +echo -n "Setting bootfs for ${POOL} to ${POOL}/root ..." +if ! /sbin/zpool set bootfs=${POOL}/root ${POOL} > /dev/null 2> /dev/null; then + echo " error" + exit 1 +fi +echo " done" +/sbin/zfs list -r ${POOL} + +# Mount and populate zfs (if legacy) +if [ "${LEGACY}" = "1" ]; then + echo -n "Mounting ${POOL} on ${MNT} ..." + /bin/mkdir -p ${MNT} + if ! /sbin/mount -t zfs ${POOL}/root ${MNT} > /dev/null 2> /dev/null; then + echo " error mounting pool/root" + exit 1 + fi + for FS in ${FS_LIST}; do + /bin/mkdir -p ${MNT}/${FS} + if ! /sbin/mount -t zfs ${POOL}/root/${FS} ${MNT}/${FS} > /dev/null 2> /dev/null; then + echo " error mounting ${POOL}/root/${FS}" + exit 1 + fi + done +echo " done" +fi + +echo -n "Extracting FreeBSD distribution ..." +for file in ${EXTRACT_FILES}; do + if ! /usr/bin/tar -C ${MNT} -x -f ${file} > /dev/null 2> /dev/null; then + echo " error" + exit 1 + fi +done +echo " done" + +# Adjust configuration files + +echo -n "Writing /boot/loader.conf..." +echo "zfs_load=\"YES\"" > ${MNT}/boot/loader.conf +echo "vfs.root.mountfrom=\"zfs:${POOL}/root\"" >> ${MNT}/boot/loader.conf +echo " done" + +# Write fstab if swap or legacy +echo -n "Writing /etc/fstab..." +rm -f ${MNT}/etc/fstab +touch ${MNT}/etc/fstab +if [ -n "${FSWAP}" -o "${LEGACY}" = "1" ]; then + if [ -n "${FSWAP}" ]; then + echo "/dev/${FSWAP} none swap sw 0 0" > ${MNT}/etc/fstab + fi + if [ "${LEGACY}" = "1" ]; then + for FS in ${FS_LIST}; do + echo ${POOL}/root/${FS} /${FS} zfs rw 0 0 >> ${MNT}/etc/fstab + done + fi +fi +if [ "${LEGACY}" != "1" ]; then + echo -n "Writing /etc/rc.conf..." + echo 'zfs_enable="YES"' >> ${MNT}/etc/rc.conf +fi +echo " done" + +echo -n "Copying /boot/zfs/zpool.cache ..." +if [ -n "${LEGACY}" ]; then + for FS in ${FS_LIST}; do + /sbin/umount ${MNT}/${FS} > /dev/null 2> /dev/null + done + /sbin/umount ${MNT} > /dev/null 2> /dev/null +fi +if ! /sbin/zpool export ${POOL} > /dev/null 2> /dev/null; then + echo " error exporting pool" + exit 1 +fi +if ! /sbin/zpool import ${ALTROOT} ${POOL} > /dev/null 2> /dev/null; then + echo " error importing pool" + exit 1 +fi +if [ -n "${LEGACY}" ]; then + if ! /sbin/mount -t zfs ${POOL}/root ${MNT} > /dev/null 2> /dev/null; then + echo " error mounting ${POOL}/root" + exit 1 + fi +fi +if ! /bin/cp /boot/zfs/zpool.cache ${MNT}/boot/zfs/ > /dev/null 2> /dev/null; then + echo " error copying zpool.cache" + exit 1 +fi +if [ -n "${LEGACY}" ]; then + for FS in ${FS_LIST}; do + if ! /sbin/mount -t zfs ${POOL}/${FS} ${MNT}/${FS} > /dev/null 2> /dev/null; then + echo " error mounting ${POOL}/${FS}" + exit 1 + fi + done +fi +echo " done" + +echo "" +echo "Installation complete." +echo "The system will boot from ZFS with clean install on next reboot" +echo "" +echo "You may make adjustments to the installed system using chroot:" +echo "chroot ${MNT}" +echo "" +echo "Some adjustments may require a mounted devfs:" +echo "mount -t devfs devfs ${MNT}/dev" +echo "" +echo "WARNING - Don't export ZFS pool \"${POOL}\"!"