The branch main has been updated by jlduran:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ecc039be7fdd7bbae6419a311af9398ca595b2f6

commit ecc039be7fdd7bbae6419a311af9398ca595b2f6
Author:     Jose Luis Duran <[email protected]>
AuthorDate: 2026-01-17 18:10:48 +0000
Commit:     Jose Luis Duran <[email protected]>
CommitDate: 2026-01-17 18:10:48 +0000

    nanobsd: Add a NO_ROOT build option
    
    Add a -U option to build NanoBSD images without root privileges.  It
    relies on makefs/mkimg and metalog (mtree) files, similar to what
    release engineering uses to build images.
    
    Keep the current way to build NanoBSD images untouched.  Once this
    method gets battle tested, it may be used to build images as root as
    well.
    
    Reviewed by:    imp, emaste
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D48793
---
 tools/tools/nanobsd/defaults.sh |  40 +++++++++++++---
 tools/tools/nanobsd/legacy.sh   | 100 ++++++++++++++++++++++++++++++++++++++++
 tools/tools/nanobsd/nanobsd.sh  |  20 ++++++--
 3 files changed, 151 insertions(+), 9 deletions(-)

diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
index bb22ab9a0aa4..850a82d4362f 100755
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -192,9 +192,11 @@ NANO_CPUTYPE=""
 
 # Directory to populate /cfg from
 NANO_CFGDIR=""
+NANO_METALOG_CFG=""
 
 # Directory to populate /data from
 NANO_DATADIR=""
+NANO_METALOG_DATA=""
 
 # We don't need SRCCONF or SRC_ENV_CONF. NanoBSD puts everything we
 # need for the build in files included with __MAKE_CONF. Override in your
@@ -356,6 +358,10 @@ make_conf_build() {
        nano_global_make_env
        echo "${CONF_WORLD}"
        echo "${CONF_BUILD}"
+       if [ -n "${NANO_NOPRIV_BUILD}" ]; then
+               echo NO_ROOT=true
+               echo METALOG="${NANO_METALOG}"
+       fi
        ) > ${NANO_MAKE_CONF_BUILD}
 }
 
@@ -595,15 +601,28 @@ setup_nanobsd() {
                # link /$d under /conf
                # we use hard links so we have them both places.
                # the files in /$d will be hidden by the mount.
-               mkdir -p conf/base/$d conf/default/$d
+               tgt_dir conf/base/$d conf/default/$d
                find $d -print | cpio ${CPIO_SYMLINK} -dumpl conf/base/
+               if [ -n "$NANO_METALOG" ]; then
+                       grep "^.\/${d}\/" "${NANO_METALOG}" |
+                           sed -e "s=^./${d}=./conf/base/${d}=g" |
+                           sort | uniq >> "${NANO_METALOG}.conf"
+               fi
        done
 
+       if [ -n "$NANO_METALOG" ]; then
+               cat "${NANO_METALOG}.conf" >> "${NANO_METALOG}"
+               rm -f "${NANO_METALOG}.conf"
+       fi
+
        echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size
        echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size
+       tgt_touch conf/base/etc/md_size
+       tgt_touch conf/base/var/md_size
 
        # pick up config files from the special partition
        echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > 
conf/default/etc/remount
+       tgt_touch conf/default/etc/remount
 
        # Put /tmp on the /var ramdisk (could be symlink already)
        tgt_dir2symlink tmp var/tmp 1777
@@ -660,13 +679,15 @@ EOF
 
        # save config file for scripts
        echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+       tgt_touch etc/nanobsd.conf
 
        echo "/dev/${NANO_DRIVE}${NANO_ROOT} / ufs ro 1 1" > etc/fstab
        echo "/dev/${NANO_DRIVE}${NANO_SLICE_CFG} /cfg ufs rw,noauto 2 2" >> 
etc/fstab
-       mkdir -p cfg
+       tgt_touch etc/fstab
+       tgt_dir cfg
 
        # Create directory for eventual /usr/local/etc contents
-       mkdir -p etc/local
+       tgt_dir etc/local
        )
 }
 
@@ -883,6 +904,8 @@ cust_install_files() (
        if [ -n "${NANO_CUST_FILES_MTREE}" -a -f ${NANO_CUST_FILES_MTREE} ]; 
then
                CR "mtree -eiU -p /" <${NANO_CUST_FILES_MTREE}
        fi
+
+       tgt_touch $(find * -type f)
 )
 
 #######################################################################
@@ -995,7 +1018,7 @@ pprint() {
 
 usage() {
        (
-       echo "Usage: $0 [-BbfhIiKknpqvWwX] [-c config_file]"
+       echo "Usage: $0 [-BbfhIiKknpqUvWwX] [-c config_file]"
        echo "  -B      suppress installs (both kernel and world)"
        echo "  -b      suppress builds (both kernel and world)"
        echo "  -c      specify config file"
@@ -1008,6 +1031,7 @@ usage() {
        echo "  -n      add -DNO_CLEAN to buildworld, buildkernel, etc"
        echo "  -p      suppress preparing the image"
        echo "  -q      make output more quiet"
+       echo "  -U      add -DNO_ROOT to build without root privileges"
        echo "  -v      make output more verbose"
        echo "  -W      suppress installworld"
        echo "  -w      suppress buildworld"
@@ -1039,6 +1063,9 @@ set_defaults_and_export() {
        if ! $do_clean; then
                NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN"
        fi
+       if ! $do_root; then
+               NANO_PMAKE="${NANO_PMAKE} -DNO_ROOT"
+       fi
        NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
        NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
 
@@ -1049,8 +1076,9 @@ set_defaults_and_export() {
        [ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \
                NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" || true
 
-       [ -n "${NANO_NOPRIV_BUILD}" ] && [ -z "${NANO_METALOG}" ] && \
-               NANO_METALOG=${NANO_OBJ}/_.metalog || true
+       if [ -n "${NANO_NOPRIV_BUILD}" ] && [ -z "${NANO_METALOG}" ]; then
+               NANO_METALOG=${NANO_OBJ}/_.metalog
+       fi
 
        NANO_STARTTIME=`date +%s`
        : ${NANO_TIMESTAMP:=${NANO_STARTTIME}}
diff --git a/tools/tools/nanobsd/legacy.sh b/tools/tools/nanobsd/legacy.sh
index ff951f4b762b..efb9c68254c9 100644
--- a/tools/tools/nanobsd/legacy.sh
+++ b/tools/tools/nanobsd/legacy.sh
@@ -155,6 +155,33 @@ create_code_slice() {
        ) > ${NANO_OBJ}/_.cs 2>&1
 }
 
+_create_code_slice ( ) (
+       pprint 2 "build code slice"
+       pprint 3 "log: ${NANO_OBJ}/_.cs"
+
+       (
+       IMG=${NANO_DISKIMGDIR}/_.disk.image
+       CODE_SIZE=$(head -n 1 "${NANO_LOG}/_.partitioning" | awk '{ print $2 }')
+       CODE_SIZE=$(_xxx_adjust_code_size "$CODE_SIZE")
+
+       echo "Writing code image..."
+       if [ -f "${NANO_WORLDDIR}/boot/boot" ]; then
+               echo "Making bootable partition"
+               bootcode="-b ${NANO_WORLDDIR}/boot/boot"
+       else
+               echo "Partition will not be bootable"
+       fi
+       nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
+           "${NANO_METALOG}" "${CODE_SIZE}" "${NANO_OBJ}/_.disk.part" \
+           "${NANO_WORLDDIR}"
+       mkimg -s bsd \
+           ${bootcode} \
+           -p freebsd-ufs:="${NANO_OBJ}/_.disk.part" \
+           -o "${NANO_DISKIMGDIR}/_.disk.image"
+       rm -f "${NANO_OBJ}/_.disk.part"
+
+       ) > ${NANO_OBJ}/_.cs 2>&1
+)
 
 create_diskimage() {
        pprint 2 "build diskimage"
@@ -255,3 +282,76 @@ create_diskimage() {
 
        ) > ${NANO_LOG}/_.di 2>&1
 }
+
+_create_diskimage() {
+       pprint 2 "build diskimage"
+       pprint 3 "log: ${NANO_OBJ}/_.di"
+
+       (
+       local altroot bootloader cfgimage dataimage diskimage
+
+       CODE_SIZE=$(head -n 1 "${NANO_LOG}/_.partitioning" | awk '{ print $2 }')
+       CODE_SIZE=$(_xxx_adjust_code_size "$CODE_SIZE")
+       IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
+
+       if [ -f "${NANO_WORLDDIR}/${NANO_BOOTLOADER}" ]; then
+               bootloader="-b ${NANO_WORLDDIR}/${NANO_BOOTLOADER}"
+       else
+               echo "Image will not be bootable"
+       fi
+
+       diskimage="-p freebsd:=${NANO_DISKIMGDIR}/_.disk.image"
+
+       if [ "$NANO_IMAGES" -gt 1 ] && [ "$NANO_INIT_IMG2" -gt 0 ] ; then
+               echo "Duplicating to second image..."
+               tgt_switch_root_fstab "${NANO_SLICE_ROOT}" 
"${NANO_SLICE_ALTROOT}"
+               nano_makefs "-DxZ ${NANO_MAKEFS} -o 
minfree=0,optimization=space" \
+                   "${NANO_METALOG}" "${CODE_SIZE}" 
"${NANO_OBJ}/_.altroot.part" \
+                   "${NANO_WORLDDIR}"
+               tgt_switch_root_fstab "${NANO_SLICE_ALTROOT}" 
"${NANO_SLICE_ROOT}"
+               if [ -f "${NANO_WORLDDIR}/boot/boot" ]; then
+                       bootcode="-b ${NANO_WORLDDIR}/boot/boot"
+               fi
+               mkimg -s bsd \
+                   ${bootcode} \
+                   -p freebsd-ufs:="${NANO_OBJ}/_.altroot.part" \
+                   -o "${NANO_OBJ}/_.altroot.image"
+               altroot="-p freebsd:=${NANO_OBJ}/_.altroot.image"
+               rm -f "${NANO_OBJ}/_.altroot.part"
+       else
+               altroot="-p-"
+       fi
+       if [ "${NANO_INIT_IMG2}" -eq 0 ]; then
+               altroot="-p freebsd::${CODE_SIZE}b"
+       fi
+
+       # Create Config slice
+       _populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
+           "${NANO_SLICE_CFG}" "${NANO_CONFSIZE}" "${NANO_METALOG_CFG}"
+       cfgimage="-p freebsd:=${NANO_OBJ}/_.cfg.part"
+
+       # Create Data slice, if any.
+       if [ -n "${NANO_SLICE_DATA}" ] &&
+           [ "${NANO_SLICE_CFG}" = "${NANO_SLICE_DATA}" ] &&
+           [ "${NANO_DATASIZE}" -ne 0 ]; then
+               pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
+               exit 2
+       fi
+       if [ "${NANO_DATASIZE}" -ne 0 ] && [ -n "${NANO_SLICE_DATA}" ] ; then
+               _populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" 
\
+                   "${NANO_SLICE_DATA}" "${NANO_DATASIZE}" 
"${NANO_METALOG_DATA}"
+               dataimage="-p freebsd:=${NANO_OBJ}/_.data.part"
+       fi
+
+       echo "Writing out ${NANO_IMGNAME}..."
+       mkimg -s mbr \
+           ${bootloader} \
+           ${diskimage} \
+           ${altroot} \
+           ${cfgimage} \
+           ${dataimage} \
+           -o ${IMG}
+       exit
+
+       ) > ${NANO_LOG}/_.di 2>&1
+}
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
index 208bc646122d..94e74d9ed216 100755
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -36,6 +36,7 @@ topdir=`dirname ${nanobsd_sh}`
 # Parse arguments
 
 do_clean=true
+do_root=true
 do_kernel=true
 do_installkernel=true
 do_world=true
@@ -49,7 +50,7 @@ do_prep_image=true
 . "${topdir}/legacy.sh"
 
 set +e
-args=`getopt BKXWbc:fhiIknpqvw $*`
+args=`getopt BKXWbc:fhiIknpqUvw $*`
 if [ $? -ne 0 ] ; then
        usage
        exit 2
@@ -133,6 +134,11 @@ do
                PPLEVEL=$(($PPLEVEL + 1))
                shift
                ;;
+       -U)
+               do_root=false
+               NANO_NOPRIV_BUILD=true
+               shift
+               ;;
        -w)
                do_world=false
                shift
@@ -221,9 +227,17 @@ else
 fi
 if $do_code ; then
        calculate_partitioning
-       create_code_slice
+       if [ -z "${NANO_NOPRIV_BUILD}" ]; then
+               create_code_slice
+       else
+               _create_code_slice
+       fi
        if $do_image ; then
-               create_diskimage
+               if [ -z "${NANO_NOPRIV_BUILD}" ]; then
+                       create_diskimage
+               else
+                       _create_diskimage
+               fi
        else
                pprint 2 "Skipping image build (as instructed)"
        fi

Reply via email to