Page MenuHomeFreeBSD

D58964.id184545.diff
No OneTemporary

D58964.id184545.diff

diff --git a/tools/tools/nanobsd/Files/root/change_password b/tools/tools/nanobsd/Files/root/change_password
--- a/tools/tools/nanobsd/Files/root/change_password
+++ b/tools/tools/nanobsd/Files/root/change_password
@@ -30,10 +30,8 @@
passwd root
-cfgslice=`grep '/cfg' /etc/fstab | cut -d \ -f 1`
-
-trap "umount /cfg" 1 2 15 EXIT
mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
cp /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
umount /cfg
-trap 1 2 15 EXIT
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/Files/root/update b/tools/tools/nanobsd/Files/root/update
--- a/tools/tools/nanobsd/Files/root/update
+++ b/tools/tools/nanobsd/Files/root/update
@@ -35,9 +35,10 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s1 > /dev/null ; then
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s1"; then
exec sh /root/updatep2
else
exec sh /root/updatep1
fi
-
diff --git a/tools/tools/nanobsd/Files/root/updatep1 b/tools/tools/nanobsd/Files/root/updatep1
--- a/tools/tools/nanobsd/Files/root/updatep1
+++ b/tools/tools/nanobsd/Files/root/updatep1
@@ -35,19 +35,21 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s1 > /dev/null ; then
- echo "You are running partition 1 already"
- echo "you probably want to use 'updatep2' instead"
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s1"; then
+ echo "You are running partition 1 already." >&2
+ echo "You probably want to use 'updatep2' instead." >&2
exit 1
fi
-# Blow away old system.
-dd if=/dev/zero of=/dev/${NANO_DRIVE}s1 bs=1m count=1 > /dev/null 2>&1
+# Blow away old system
+dd if=/dev/zero of="/dev/${NANO_DRIVE}s1" bs=1m count=1 > /dev/null 2>&1
# Copy in new system
-dd of=/dev/${NANO_DRIVE}s1 obs=64k
+dd of="/dev/${NANO_DRIVE}s1" obs=64k
# Check that it worked
-fsck_ffs -n /dev/${NANO_DRIVE}s1a
+fsck_ffs -n "/dev/${NANO_DRIVE}s1a"
-gpart set -a active -i 1 ${NANO_DRIVE}
+gpart set -a active -i 1 "${NANO_DRIVE}"
diff --git a/tools/tools/nanobsd/Files/root/updatep2 b/tools/tools/nanobsd/Files/root/updatep2
--- a/tools/tools/nanobsd/Files/root/updatep2
+++ b/tools/tools/nanobsd/Files/root/updatep2
@@ -35,26 +35,28 @@
. /etc/nanobsd.conf
-if mount | grep ${NANO_DRIVE}s2 > /dev/null ; then
- echo "You are running partition 2 already"
- echo "you probably want to use 'updatep1' instead"
+: "${NANO_DRIVE:?NANO_DRIVE not set in /etc/nanobsd.conf}"
+
+if mount | grep -q -F "${NANO_DRIVE}s2"; then
+ echo "You are running partition 2 already." >&2
+ echo "You probably want to use 'updatep1' instead." >&2
exit 1
fi
# Blow away old system.
-dd if=/dev/zero of=/dev/${NANO_DRIVE}s2 bs=1m count=1 > /dev/null 2>&1
+dd if=/dev/zero of="/dev/${NANO_DRIVE}s2" bs=1m count=1 > /dev/null 2>&1
# Copy in new system
-dd of=/dev/${NANO_DRIVE}s2 obs=64k
+dd of="/dev/${NANO_DRIVE}s2" obs=64k
# Check that it worked
-fsck_ffs -n /dev/${NANO_DRIVE}s2a
+fsck_ffs -n "/dev/${NANO_DRIVE}s2a"
# Update the /etc/fstab
trap "umount /mnt" 1 2 15 EXIT
-mount /dev/${NANO_DRIVE}s2a /mnt
+mount "/dev/${NANO_DRIVE}s2a" /mnt
sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/conf/base/etc/fstab
sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/" /mnt/etc/fstab
umount /mnt
trap 1 2 15 EXIT
-gpart set -a active -i 2 ${NANO_DRIVE}
+gpart set -a active -i 2 "${NANO_DRIVE}"
diff --git a/tools/tools/nanobsd/FlashDevice.sub b/tools/tools/nanobsd/FlashDevice.sub
--- a/tools/tools/nanobsd/FlashDevice.sub
+++ b/tools/tools/nanobsd/FlashDevice.sub
@@ -36,7 +36,6 @@
#
sub_FlashDevice () {
-
a1=`echo $1 | tr '[:upper:]' '[:lower:]'`
a2=`echo $2 | tr '[:upper:]' '[:lower:]'`
case $a1 in
@@ -103,7 +102,7 @@
# Version 10.9
# Document No. 20-10-00038
# April 2005
- # Table 2-7
+ # Table 2-7
# NB: notice math error in SDCFJ-4096-388 line.
#
case $a2 in
@@ -155,11 +154,11 @@
;;
siliconsystems)
case $a2 in
- 256|256mb)
- NANO_MEDIASIZE=`expr 260571136 / 512`
- NANO_HEADS=16
- NANO_SECTS=32
- ;;
+ 256|256mb)
+ NANO_MEDIASIZE=`expr 260571136 / 512`
+ NANO_HEADS=16
+ NANO_SECTS=32
+ ;;
4096|4g)
NANO_MEDIASIZE=`expr -e 4224761856 / 512`
NANO_HEADS=16
diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -51,6 +51,8 @@
# where package metadata gets placed
NANO_PKG_META_BASE=/var/db
+# Path to the files directory used by cust_install_files()
+NANO_CUST_FILESDIR="${NANO_TOOLS}/Files"
# Path to mtree file to apply to anything copied by cust_install_files().
# If you specify this, the mtree file *must* have an entry for every file and
# directory located in Files.
@@ -105,25 +107,34 @@
# Late customize commands.
NANO_LATE_CUSTOMIZE=""
-# Newfs parameters to use
-NANO_NEWFS="-b 4096 -f 512 -i 8192 -U"
-NANO_MAKEFS="-o bsize=4096,density=8192,fsize=512,softupdates=1,version=2"
+# makefs parameters to use
+NANO_MAKEFS="-o softupdates=1,version=2"
# The drive name of the media at runtime
NANO_DRIVE=ada0
+#
+# Sector size in bytes.
+# Accepts suffixes and products (4k, 1M, 4x1024)
+#
+NANO_SECTOR_SIZE=512
+
# Target media size in 512 bytes sectors
NANO_MEDIASIZE=4000000
# Number of code images on media (1 or 2)
NANO_IMAGES=2
+#
# 0 -> Leave second image all zeroes so it compresses better.
# 1 -> Initialize second image with a copy of the first
+#
NANO_INIT_IMG2=1
+#
# Size of code file system in 512 bytes sectors
# If zero, size will be as large as possible.
+#
NANO_CODESIZE=0
# Size of configuration file system in 512 bytes sectors
@@ -141,9 +152,11 @@
# Size of the /tmp+/var ramdisk in 512 bytes sectors
NANO_RAM_TMPVARSIZE=10240
-# boot0 flags/options and configuration
-NANO_BOOT0CFG="-o packet -s 1 -m 3"
-NANO_BOOTLOADER="boot/boot0sio"
+# Size of swap partition in 512 bytes sectors
+NANO_SWAP_SIZE=0
+
+# Swap partition encryption
+NANO_SWAP_ENCRYPTION=
# boot2 flags/options
# default force serial console
@@ -159,21 +172,6 @@
# Progress Print level
PPLEVEL=3
-# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label
-# in preference to /dev/${NANO_DRIVE}
-# Root partition will be ${NANO_LABEL}s{1,2}
-# /cfg partition will be ${NANO_LABEL}s3
-# /data partition will be ${NANO_LABEL}s4
-NANO_LABEL=""
-NANO_SLICE_ROOT=s1
-NANO_SLICE_ALTROOT=s2
-NANO_SLICE_CFG=s3
-NANO_SLICE_DATA=s4
-NANO_PARTITION_ROOT=a
-NANO_PARTITION_ALTROOT=a
-NANO_ROOT=s1a
-NANO_ALTROOT=s2a
-
# Default ownership for nopriv build
NANO_DEF_UNAME=root
NANO_DEF_GNAME=wheel
@@ -524,43 +522,48 @@
}
#
-# Update the path the files table of the target pkg database from
-# /usr/local/etc to /etc/local. All paths are relative to NANO_WORLDDIR
+# Swap the dir ID with the symlink ID in the pkg_directories table.
+# Remove the dir ID from the directories table
#
-tgt_pkg_update_file_path_etc_local() {
- tgt_pkg shell <<-EOF
- UPDATE files
- SET path = '/etc/local' || SUBSTR(path, 15)
- WHERE path LIKE '/usr/local/etc%';
- EOF
-}
+tgt_pkg_rm_dir2symlink() {
+ local dir dir_id realpath_target symlink symlink_id update_stmt
-#
-# Swap the /tmp ID with the /var/tmp ID in the pkg_directories table.
-# Remove the /tmp directory from the directories table.
-#
-tgt_pkg_link_tmp_var_tmp() {
- local tmp_id var_tmp_id
+ dir="$1"
+ symlink="$2"
- tmp_id=$(tgt_pkg shell "SELECT id FROM directories WHERE path = '/tmp';")
- var_tmp_id=$(tgt_pkg shell "SELECT id FROM directories WHERE path = '/var/tmp';")
+ # Resolve the symlink's target destination to query the database
+ realpath_target=$(realpath -q "${NANO_WORLDDIR}/${dir}/../${symlink}")
+ realpath_target="${realpath_target#$NANO_WORLDDIR}"
- if [ -z "$tmp_id" ] || [ -z "$var_tmp_id" ]; then
- return
+ if [ -n "$realpath_target" ]; then
+ symlink_id=$(tgt_pkg shell "SELECT id FROM directories
+ WHERE path = '${realpath_target}';")
+ fi
+ dir_id=$(tgt_pkg shell "SELECT id FROM directories
+ WHERE path = '/${dir}';")
+ if [ -z "$dir_id" ]; then
+ return 0
+ fi
+
+ # Change any package relation from the dir ID to the symlink ID (if any)
+ if [ -n "$symlink_id" ]; then
+ update_stmt="UPDATE OR IGNORE pkg_directories
+ SET directory_id = ${symlink_id}
+ WHERE directory_id = ${dir_id};"
+ else
+ update_stmt="-- Skip UPDATE: symlink_id is empty"
fi
tgt_pkg shell <<-EOF
BEGIN TRANSACTION;
- -- Change any package relation from the /tmp ID to the /var/tmp ID
- UPDATE OR IGNORE pkg_directories
- SET directory_id = ${var_tmp_id} WHERE directory_id = ${tmp_id};
+ ${update_stmt}
- -- Remove residual /tmp remnants left behind by "OR IGNORE"
- DELETE FROM pkg_directories WHERE directory_id = ${tmp_id};
+ -- Remove residual dir ID remnants left behind by "OR IGNORE"
+ DELETE FROM pkg_directories WHERE directory_id = ${dir_id};
- -- Remove /tmp from the directories table
- DELETE FROM directories WHERE id = ${tmp_id};
+ -- Remove dir ID from the directories table
+ DELETE FROM directories WHERE id = ${dir_id};
COMMIT;
EOF
@@ -569,7 +572,7 @@
# Timestamp all files with NANO_TIMESTAMP in the pkg database
tgt_pkg_time_timestamp() {
if [ -z "$NANO_TIMESTAMP" ]; then
- return
+ return 0
fi
tgt_pkg shell "UPDATE files SET mtime = ${NANO_TIMESTAMP};"
@@ -584,6 +587,7 @@
-o IGNORE_OSVERSION=yes \
-o OSVERSION="$NANO_OSVERSION" \
-o PKG_CACHEDIR="$(nano_pkg_cachedir)" \
+ -o PKG_DBDIR="${NANO_WORLDDIR}/var/db/pkg" \
"$@"
}
@@ -655,7 +659,7 @@
# XXXJL FINGERPRINTS!
cat > "$(nano_pkg_repos_dir)/FreeBSD-local.conf" <<EOF
FreeBSD-local: {
- url: "file:///$(nano_pkg_cachedir)",
+ url: "file://$(nano_pkg_cachedir)",
enabled: no
}
EOF
@@ -802,25 +806,14 @@
done
)
-#
-# Update the path the files table of the target pkg database from
-# /usr/local/etc to /etc/local. All paths are relative to NANO_WORLDDIR
-#
-tgt_pkg_update_file_path_etc_local() {
- tgt_pkg shell <<-EOF
- UPDATE files
- SET path = '/etc/local' || SUBSTR(path, 15)
- WHERE path LIKE '/usr/local/etc%';
- EOF
-}
-
#
# Convert a directory into a symlink. Takes three arguments, the current
# directory, what it should become a symlink to, and optionally, the mode.
# The directory is removed and a symlink is created. If we're doing
# a nopriv build, then append this fact to the metalog
#
-tgt_dir2symlink() (
+tgt_dir2symlink() {
+ (
local dir=$1
local symlink=$2
local mode=${3:-0777}
@@ -828,25 +821,22 @@
cd "${NANO_WORLDDIR}"
rm -xrf "$dir"
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg shell <<-EOF
- DELETE FROM directories WHERE path = '$dir';
- EOF
+ if [ -n "$NANO_METALOG" ]; then
+ sed -i "" "\=^\./${dir} =d" "$NANO_METALOG"
+ fi
+ if [ -z "$NANO_NOPKGBASE" ]; then
+ tgt_pkg_rm_dir2symlink "$dir" "$symlink" || true
fi
ln -sf "$symlink" "$dir"
+ chmod "$mode" "$dir"
if [ -n "$NANO_METALOG" ]; then
printf "./%s type=link uname=%s gname=%s mode=%s link=%s\n" \
"$dir" "$NANO_DEF_UNAME" "$NANO_DEF_GNAME" "$mode" \
"$symlink" >> "$NANO_METALOG"
fi
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg shell <<-EOF
- INSERT INTO files (path, uname, gname, perm, fflags, symlink_target)
- VALUES ('$dir', '$NANO_DEF_UNAME', '$NANO_DEF_GNAME', '$mode', 0, '$symlink');
- EOF
- fi
-)
+ )
+}
#
# Generate metalog entries for each intermediate directory in a path.
@@ -902,8 +892,7 @@
# Switch the current root partition in the target file system tab.
# Input: $1 = current root partition, $2 = new root partition
#
-tgt_switch_root_fstab()
-{
+tgt_switch_root_fstab() {
local current new
current="$1"
new="$2"
@@ -1271,8 +1260,13 @@
sed -i "" "\=^\./usr/local/etc =d" "$NANO_METALOG"
sed -i "" -e "s=^\./usr/local/etc/=./etc/local/=g" "$NANO_METALOG"
fi
- if $do_precompiled && [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg_update_file_path_etc_local
+ if [ -z "$NANO_NOPKGBASE" ]; then
+ tgt_pkg shell "UPDATE directories
+ SET path = '/etc/local'
+ WHERE path = '/usr/local/etc';"
+ tgt_pkg shell "UPDATE files
+ SET path = '/etc/local' || SUBSTR(path, 15)
+ WHERE path LIKE '/usr/local/etc%';"
fi
fi
@@ -1288,6 +1282,9 @@
nano_pkg_disable_repos
fi
+ # Put /tmp on the /var ramdisk
+ tgt_dir2symlink tmp var/tmp 1777
+
if [ -n "$NANO_METALOG" ]; then
_xxx_pkg_add_var_db_files_to_metalog
fi
@@ -1320,19 +1317,11 @@
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 (it may already be symlinked)
- if [ -n "$NANO_METALOG" ]; then
- sed -i "" "\=^\./tmp =d" "$NANO_METALOG"
- fi
- tgt_dir2symlink tmp var/tmp 1777
- if [ -z "$NANO_NOPKGBASE" ]; then
- tgt_pkg_link_tmp_var_tmp
- fi
+ # Add the /conf/default/etc/remount file
+ tgt_etc_remount
+ # Make sure that firstboot scripts run so growfs works
+ tgt_touch firstboot
) > ${NANO_LOG}/_.dl 2>&1
}
@@ -1379,6 +1368,8 @@
# entropy through reboots.
entropy_dir="NO" # Disable caching entropy via cron.
dumpdev="NO" # Disable dumpdev.
+growfs_enable="YES" # Attempt to grow the root filesystem on boot.
+growfs_swap_size="${NANO_SWAP_SIZE}" # Size in bytes to specify swap size.
##############################################################
.
@@ -1394,13 +1385,7 @@
tgt_pkg_update_config_files_content etc/defaults/rc.conf
fi
- # 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
- tgt_touch etc/fstab
+ tgt_write_fstab
tgt_dir cfg
# Create directory for eventual /usr/local/etc contents
@@ -1408,6 +1393,47 @@
)
}
+# Write to the /etc/fstab file
+printf_fstab() {
+ printf "%s\t\t%s\t%s\t%s\t\t%s\t%s\n" \
+ "$1" "$2" "$3" "$4" "$5" "$6" >> ${NANO_WORLDDIR}/etc/fstab
+}
+
+get_uefi_bootname() {
+ case "$NANO_ARCH" in
+ amd64) echo BOOTX64 ;;
+ aarch64) echo BOOTAA64 ;;
+ i386) echo BOOTIA32 ;;
+ armv7) echo BOOTARM ;;
+ riscv64) echo BOOTRISCV64 ;;
+ *) err "Unsupported NANO_ARCH '${NANO_ARCH}'" ;;
+ esac
+}
+
+get_bootcode() {
+ local boot_type part_type
+ boot_type="$1"
+ part_type="$2"
+
+ case "$boot_type" in
+ [Bb][Ii][Oo][Ss])
+ case "$part_type" in
+ [Mm][Bb][Rr]) echo "boot/boot" ;;
+ [Gg][Pp][Tt]) echo "boot/gptboot" ;;
+ *) err "Unsupported BIOS partition type '${part_type}'" ;;
+ esac
+ ;;
+ [Uu][Ee][Ff][Ii])
+ case "$part_type" in
+ [Gg][Pp][Tt]) echo "boot/gptboot.efi" ;;
+ [Zz][Ff][Ss]) echo "boot/loader.efi" ;;
+ *) err "Unsupported UEFI partition type '${part_type}'" ;;
+ esac
+ ;;
+ *) err "Unsupported boot type '${boot_type}'" ;;
+ esac
+}
+
# Remove all empty directories under NANO_WORLDDIR/usr
prune_usr() {
# Remove all empty directories in /usr
@@ -1449,8 +1475,13 @@
image=$4
dir=$5
- makefs -t ffs ${options} -F "${metalog}" -N "${NANO_WORLDDIR}/etc" \
- -R "${size}b" -T "${NANO_TIMESTAMP}" "${image}" "${dir}"
+ if [ -n "$metalog" ] && [ -f "$metalog" ]; then
+ makefs -t ffs -DxZ ${options} -F "$metalog" -N "${NANO_WORLDDIR}/etc" \
+ -R "${size}b" -T "$NANO_TIMESTAMP" "$image" "$dir"
+ else
+ makefs -t ffs -Z ${options} -N "${NANO_WORLDDIR}/etc" \
+ -R "${size}b" -T "$NANO_TIMESTAMP" "$image" "$dir"
+ fi
}
#
@@ -1489,7 +1520,7 @@
# Input: $1 = type (cfg/data), $2 = output image path, $3 = source dir,
# $4 = label, $5 = size in sectors, $6 = metalog
#
-_populate_part() {
+populate_part() {
local dir fs lbl metalog size type
type=$1
fs=$2
@@ -1528,7 +1559,7 @@
)
fi
- nano_makefs "-DxZ ${NANO_MAKEFS}" "${metalog}" "${size}" "${fs}" "${dir}"
+ nano_makefs "${NANO_MAKEFS}" "${metalog}" "${size}" "${fs}" "${dir}"
fi
}
@@ -1541,13 +1572,13 @@
}
#
-# Thin wrapper around _populate_part for creating
+# Thin wrapper around populate_part for creating
# the configuration partition image file
-# Input: $1 = image path, $2 = source dir, $3 = label, $4 = size in sectors,
-# $5 = metalog
+# Input: $1 = image path, $2 = source dir, $3 = slice number,
+# $4 = size in sectors, $5 = metalog
#
-_populate_cfg_part() {
- _populate_part "cfg" "$1" "$2" "$3" "$4" "$5"
+populate_cfg_part() {
+ populate_part "cfg" "$1" "$2" "$3" "$4" "$5"
}
#
@@ -1559,11 +1590,11 @@
}
#
-# Thin wrapper around _populate_part for creating the data partition image file
+# Thin wrapper around populate_part for creating the data partition image file
# Input: $1 = image path, $2 = source dir, $3 = label, $4 = size, $5 = metalog
#
-_populate_data_part() {
- _populate_part "data" "$1" "$2" "$3" "$4" "$5"
+populate_data_part() {
+ populate_part "data" "$1" "$2" "$3" "$4" "$5"
}
#
@@ -1590,6 +1621,36 @@
exit 2
}
+#
+# Convert a human-readable size string with a suffix (b/k/m/g/t/w) into bytes.
+# Also accepts "x"-delimited products followed by a suffix (e.g., "2x1024k")
+# makefs(8)-size compatible. See NetBSD's strsuftoll(3)
+# Input: $1 = size string (e.g., "512m", "2x1024x1024k")
+# Output: byte count
+#
+strsuftoll() {
+ local num result unit
+
+ num=${1%?}
+ unit=${1#"${num}"}
+
+ case "$unit" in
+ [bB]) result="${num}x${NANO_SECTOR_SIZE}" ;;
+ [kK]) result="${num}x1024" ;;
+ [mM]) result="${num}x1024x1024" ;;
+ [gG]) result="${num}x1024x1024x1024" ;;
+ [tT]) result="${num}x1024x1024x1024x1024" ;;
+ [wW]) result="${num}x4" ;; # sizeof(int)
+ [0-9]) result="$1" ;;
+ *)
+ printf "%s\n" "'$1': illegal number"
+ exit 1
+ ;;
+ esac
+
+ printf "%s" "$(echo "scale=0; $result" | tr 'x' '*' | bc)"
+}
+
#######################################################################
# Common Flash device geometries
#
@@ -1691,17 +1752,25 @@
# Install the stuff under ./Files
# Copy all files from NANO_TOOLS/Files into NANO_WORLDDIR
-cust_install_files() (
- cd "${NANO_TOOLS}/Files"
+cust_install_files() {
+ (
+ cd "$NANO_CUST_FILESDIR"
find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)/' |
- cpio ${CPIO_SYMLINK} -Ldumpv ${NANO_WORLDDIR}
+ cpio ${CPIO_SYMLINK} -Ldumpv "$NANO_WORLDDIR"
- if [ -n "${NANO_CUST_FILES_MTREE}" -a -f ${NANO_CUST_FILES_MTREE} ]; then
- CR "mtree -eiU -p /" <${NANO_CUST_FILES_MTREE}
+ if [ -n "$NANO_CUST_FILES_MTREE" ] && [ -f "$NANO_CUST_FILES_MTREE" ]; then
+ if [ -n "$NANO_NOPRIV_BUILD" ]; then
+ # Entries in NANO_CUST_FILES_MTREE must precede NANO_METALOG
+ cat "$NANO_CUST_FILES_MTREE" "$NANO_METALOG" > "${NANO_METALOG}.tmp"
+ mv "${NANO_METALOG}.tmp" "$NANO_METALOG"
+ else
+ CR "mtree -eiU -p /" <"$NANO_CUST_FILES_MTREE"
+ fi
+ else
+ tgt_touch $(find * -type f)
fi
-
- tgt_touch $(find * -type f)
-)
+ )
+}
#######################################################################
# Install packages from ${NANO_PACKAGE_DIR}
@@ -1711,6 +1780,11 @@
# into NANO_WORLDDIR via a nullfs-mounted chroot
#
cust_pkgng() {
+ if ! $do_root && [ -n "$NANO_NOPRIV_BUILD" ]; then
+ pprint 2 'Skipping "cust_pkgng" (unprivileged builds not supported yet)'
+ return 0
+ fi
+
mkdir -p ${NANO_WORLDDIR}/usr/local/etc
local PKG_CONF="${NANO_WORLDDIR}/usr/local/etc/pkg.conf"
local PKGCMD="env BATCH=YES ASSUME_ALWAYS_YES=YES PKG_DBDIR=${NANO_PKG_META_BASE}/pkg SIGNATURE_TYPE=none /usr/sbin/pkg"
@@ -1825,11 +1899,11 @@
# Input: $1 = level, $2 = message
#
pprint() {
- if [ "$1" -le $PPLEVEL ]; then
+ if [ "$1" -le $PPLEVEL ]; then
runtime=$(( $(date +%s) - NANO_STARTTIME ))
printf "%s %.${1}s %s\n" \
"$(date -u -r $runtime +%H:%M:%S)" "#####" "$2" 1>&3
- fi
+ fi
}
# Print the nanobsd.sh command-line option summary to stderr, exit with code 2
@@ -1891,9 +1965,6 @@
NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
- # Override user's NANO_DRIVE if they specified a NANO_LABEL
- [ -n "${NANO_LABEL}" ] && NANO_DRIVE="ufs/${NANO_LABEL}" || true
-
# Set a default NANO_TOOLS to NANO_SRC/NANO_TOOLS if it exists.
[ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \
NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" || true
@@ -1911,6 +1982,7 @@
export_var NANO_CONFSIZE
export_var NANO_CUSTOMIZE
export_var NANO_DATASIZE
+ export_var NANO_DISKIMGDIR
export_var NANO_DRIVE
export_var NANO_HEADS
export_var NANO_IMAGES
@@ -1928,6 +2000,8 @@
export_var NANO_PMAKE
export_var NANO_SECTS
export_var NANO_SRC
+ export_var NANO_SWAP_ENCRYPTION
+ export_var NANO_SWAP_SIZE
export_var NANO_TIMESTAMP
export_var NANO_TOOLS
export_var NANO_WORLDDIR
diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common
--- a/tools/tools/nanobsd/embedded/common
+++ b/tools/tools/nanobsd/embedded/common
@@ -168,31 +168,6 @@
NANO_PACKAGE_ONLY=1
-# makefs(8)-size compatible
-# See NetBSD's strsuftoll(3)
-strsuftoll() {
- local num result unit
-
- num=${1%?}
- unit=${1#"${num}"}
-
- case "$unit" in
- [bB]) result="${num}x512" ;;
- [kK]) result="${num}x1024" ;;
- [mM]) result="${num}x1024x1024" ;;
- [gG]) result="${num}x1024x1024x1024" ;;
- [tT]) result="${num}x1024x1024x1024x1024" ;;
- [wW]) result="${num}x4" ;; # sizeof(int)
- [0-9]) result="$1" ;;
- *)
- printf "%s\n" "'$1': illegal number"
- exit 1
- ;;
- esac
-
- printf "%s" "$(echo "scale=0; $result" | tr 'x' '*' | bc)"
-}
-
# Creates images for all the formats that use MBR / GPT
# split later if the #ifdef soup gets too bad.
create_diskimage_gpt() {
diff --git a/tools/tools/nanobsd/gpt.sh b/tools/tools/nanobsd/gpt.sh
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt.sh
@@ -0,0 +1,474 @@
+#!/bin/sh
+#
+# Copyright (c) 2026 The FreeBSD Project.
+#
+# 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.
+#
+#
+
+set -e
+
+NANO_PLAN=gpt
+
+#
+# Space-separated list of boot types; options: BIOS, UEFI (case-insensitive).
+# Default enables both.
+#
+NANO_BOOT_TYPE="BIOS UEFI"
+
+# EFI System Partition size in 512 bytes sectors
+NANO_EFI_BOOTPART_SIZE=532480
+
+# Set NANO_LABEL to non-blank to form the basis for using /dev/gpt/code
+# in preference to /dev/${NANO_DRIVE}
+# Root partition will be /dev/gpt/${NANO_ROOT, NANO_ALTROOT}
+# /cfg partition will be /dev/gpt/cfg
+# /data partition will be /dev/gpt/data
+NANO_LABEL=code
+NANO_PARTITION_ROOT=1
+NANO_PARTITION_CFG=cfg
+NANO_PARTITION_DATA=data
+
+NANO_ROOT="${NANO_LABEL}${NANO_PARTITION_ROOT}"
+
+if [ "$NANO_IMAGES" -gt 1 ]; then
+ NANO_PARTITION_ALTROOT=2
+ NANO_ALTROOT="${NANO_LABEL}${NANO_PARTITION_ALTROOT}"
+fi
+
+# Override NANO_DRIVE with NANO_LABEL
+if [ -z "${NANO_LABEL}" ]; then
+ err "NANO_LABEL must be defined"
+fi
+
+NANO_BOOTLOADER="boot/gptboot"
+
+NANO_ALIGN="${NANO_ALIGN:-2048}"
+
+NANO_CUST_FILESDIR="${NANO_TOOLS}/gpt/Files"
+NANO_CUST_FILES_MTREE="${NANO_TOOLS}/gpt/Files.mtree"
+
+# Create the /etc/fstab file
+tgt_write_fstab() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ # Save config file for scripts
+ echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+ echo "NANO_LABEL=${NANO_LABEL}" >> etc/nanobsd.conf
+ echo "NANO_ROOT=${NANO_ROOT}" >> etc/nanobsd.conf
+ echo "NANO_ALTROOT=${NANO_ALTROOT}" >> etc/nanobsd.conf
+ tgt_touch etc/nanobsd.conf
+
+ printf_fstab "# Device" Mountpoint FStype Options Dump "Pass#"
+ if is_boot_type UEFI; then
+ printf_fstab "/dev/gpt/efiboot0" /boot/efi msdosfs rw,noauto 2 2
+ fi
+ printf_fstab "/dev/gpt/${NANO_ROOT}" / ufs ro 1 1
+ printf_fstab /dev/gpt/${NANO_PARTITION_CFG} /cfg ufs rw,noauto 2 2
+ if [ "$NANO_SWAP_SIZE" -gt 0 ]; then
+ if [ -n "$NANO_SWAP_ENCRYPTION" ]; then
+ printf_fstab "/dev/gpt/swap0.eli" none swap sw 0 0
+ else
+ printf_fstab "/dev/gpt/swap0" none swap sw 0 0
+ fi
+ fi
+
+ tgt_touch etc/fstab
+ )
+}
+
+# Pick up config files from the special partition
+tgt_etc_remount() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ echo "mount -o ro /dev/gpt/${NANO_PARTITION_CFG}" > conf/default/etc/remount
+ tgt_touch conf/default/etc/remount
+ )
+}
+
+#
+# Check whether a boot type is present in NANO_BOOT_TYPE
+# Input: $1 = boot type to check
+# Output: return 0 if found, 1 if not
+#
+is_boot_type() {
+ local boot_type boot_types
+
+ boot_type=$(echo "$1" | tr "[:upper:]" "[:lower:]")
+ boot_types=$(echo "${NANO_BOOT_TYPE}" | tr "[:upper:]" "[:lower:]")
+
+ # These architectures lack a BIOS
+ case "$NANO_ARCH" in
+ aarch64|riscv64|riscv)
+ case "${boot_type}" in
+ efi|uefi) ;;
+ *) return 1 ;;
+ esac
+ ;;
+ esac
+
+ case " ${boot_types} " in
+ *" ${boot_type} "*) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
+#
+# Create a FreeBSD Boot Partition image file of 512 KiB
+#
+make_boot_partition() {
+ local bootcode
+
+ bootcode="${NANO_WORLDDIR}/${NANO_BOOTLOADER}"
+
+ if [ ! -f "$bootcode" ]; then
+ echo "Image will not be bootable"
+ else
+ cp -p "$bootcode" "${NANO_OBJ}/_.gptboot0.image"
+ truncate -s 512k "${NANO_OBJ}/_.gptboot0.image"
+ fi
+}
+
+#
+# Create an EFI System Partition image file
+#
+make_esp_partition() {
+ local bootcode efibootname espdir esp_sects fat_size fat_type
+
+ # Since sectors_per_cluster=1, assume 1 cluster = 1 sector
+ MINCLS16=4085 # minimum FAT16 clusters (0xff5U)
+ MINCLS32=65525 # minimum FAT32 clusters (0xfff5U)
+ esp_sects=$(awk '$5 == "efiboot0" {print $4}' "${NANO_LOG}/_.partitioning")
+ fat_size=$(( esp_sects * NANO_SECTOR_SIZE ))
+ if [ "$esp_sects" -ge "$MINCLS32" ]; then
+ fat_type=32
+ elif [ "$esp_sects" -ge "$MINCLS16" ]; then
+ fat_type=16
+ else
+ fat_type=12
+ fi
+
+ espdir="${NANO_OBJ}/_.efi"
+ rm -rf "$espdir"
+ mkdir -p "${espdir}/EFI/BOOT"
+
+ efibootname=$(get_uefi_bootname)
+ bootcode="${NANO_WORLDDIR}/$(get_bootcode uefi gpt)"
+
+ if [ ! -f "$bootcode" ]; then
+ echo "Image will not be bootable"
+ fi
+
+ cp -p "$bootcode" "${espdir}/EFI/BOOT/${efibootname}.EFI"
+
+ makefs -t msdos \
+ -o fat_type="$fat_type" \
+ -o sectors_per_cluster=1 \
+ -o volume_label="efiboot0" \
+ -o OEM_string="" \
+ -s "$fat_size" \
+ -T "$NANO_TIMESTAMP" \
+ "${NANO_OBJ}/_.efiboot0.image" "$espdir"
+
+ rm -rf "$espdir"
+}
+
+#
+# Calculate partition sizes aligned at NANO_ALIGN boundaries.
+# All sizes are in sectors.
+# The output is compatible with gpart restore
+#
+calculate_partitioning() {
+ local boot_sects boot_size boot_type esp_sects
+ boot_sects=0
+ boot_type=0
+ esp_sects=0
+
+ if is_boot_type BIOS; then
+ boot_type=1
+ # Boot partition is exactly 512 KiB
+ boot_size=$(strsuftoll 512k)
+ boot_sects=$(( boot_size / NANO_SECTOR_SIZE ))
+ fi
+ is_boot_type UEFI && esp_sects="$NANO_EFI_BOOTPART_SIZE"
+
+ echo "$NANO_MEDIASIZE" "$NANO_IMAGES" "$NANO_SECTOR_SIZE" \
+ "$NANO_CODESIZE" "$NANO_CONFSIZE" "$NANO_DATASIZE" "$boot_type" \
+ "$boot_sects" "$esp_sects" "$NANO_SWAP_SIZE" "$NANO_ROOT" \
+ "$NANO_ALTROOT" "$NANO_PARTITION_CFG" "$NANO_PARTITION_DATA" \
+ "$NANO_ALIGN" |
+ awk '
+ function roundup(sects) {
+ return int((sects + align - 1) / align) * align
+ }
+ function print_line(type, sects, label, windex, wtype, wblocks) {
+ windex = 3
+ wtype = ($7 == 1 || swap_sects > 0) ? length("freebsd-swap") : length("freebsd-ufs")
+ wblocks = length($1)
+
+ printf "%-*s %*s %*s %*s %s\n",
+ windex, i,
+ wtype, type,
+ wblocks, sstart,
+ wblocks, sects,
+ label
+ sstart += sects
+ avail_sects -= sects
+ i++
+ }
+
+ {
+ # Sector size
+ ssize = $3
+
+ # Align to a NANO_ALIGN boundary in sectors
+ align = $15
+
+ # GPT backup metadata at the end of the disk in sectors
+ # (128 entries x 128 bytes + 1 header sector)
+ gpt_end_sects = int(16384 / ssize) + 1
+
+ # Boot size in sectors (already rounded up)
+ boot_sects = ($8 > 0) ? $8 : 0
+
+ # ESP size in sectors (rounded up)
+ esp_sects = ($9 > 0) ? roundup($9) : 0
+
+ # Swap size in sectors (rounded up)
+ swap_sects = ($10 > 0) ? roundup($10) : 0
+
+ # Configuration partition size in sectors (rounded up)
+ cfg_sects = roundup($5)
+
+ # Data partition size in sectors (rounded up)
+ data_sects = ($6 > 0) ? roundup($6) : $6
+
+ # Starting sector (512/4K-bytes aligned)
+ sstart = 40
+
+ # Available sectors
+ avail_sects = $1 - sstart - gpt_end_sects
+
+ # Print header (scheme and number of entries)
+ print "GPT 128"
+
+ # Partition index counter
+ i = 1
+
+ # Boot partition (if any)
+ if ($7 == 1) {
+ print_line("freebsd-boot", boot_sects, "gptboot0")
+ }
+
+ # Starting sector (NANO_ALIGN boundary in sectors)
+ avail_sects -= (align - sstart)
+ sstart = align
+
+ # ESP partition (if any)
+ if (esp_sects > 0) {
+ print_line("efi", esp_sects, "efiboot0")
+ }
+
+ if (swap_sects > 0) {
+ print_line("freebsd-swap", swap_sects, "swap0")
+ }
+
+ # Code partition size in sectors
+ code_sects = $4
+ if (code_sects == 0) {
+ # (rounded down)
+ total_code_sects = avail_sects - cfg_sects - \
+ ((data_sects > 0) ? data_sects : 0)
+ total_code_sects = int(total_code_sects / align) * align
+ code_sects = int((total_code_sects / $2) / align) * align
+ } else {
+ # (rounded up)
+ code_sects = roundup(code_sects)
+ }
+
+ # First code partition
+ print_line("freebsd-ufs", code_sects, $11)
+
+ # Second code partition (if any)
+ if ($2 > 1) {
+ print_line("freebsd-ufs", code_sects, $12)
+ }
+
+ # Configuration partition
+ print_line("freebsd-ufs", cfg_sects, $13)
+
+ # Data partition (if any)
+ if (data_sects > 0) {
+ print_line("freebsd-ufs", data_sects, $14)
+ } else if (data_sects < 0 && avail_sects > 0) {
+ print_line("freebsd-ufs", avail_sects, $14)
+ }
+
+ # Overcommit check
+ if (avail_sects < 0) {
+ print "Disk space overcommitted by", \
+ (avail_sects * -1), "sectors" > "/dev/stderr"
+ exit 2
+ }
+ }' > "${NANO_LOG}/_.partitioning"
+}
+
+# Create the code partition image
+create_code_partition() {
+ pprint 2 "build code partition"
+ pprint 3 "log: ${NANO_OBJ}/_.cp"
+
+ (
+ local IMG code_sects
+
+ IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
+ code_sects=$(awk -v label="$NANO_ROOT" '$5 == label {print $4}' "${NANO_LOG}/_.partitioning")
+
+ echo "Writing code image..."
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ "$NANO_METALOG" "$code_sects" "$IMG" "$NANO_WORLDDIR"
+ ) > "${NANO_OBJ}/_.cp" 2>&1
+}
+
+_create_diskimage() {
+ create_diskimage
+}
+
+# Assemble the final GPT disk image from pre-built partition images using mkimg
+create_diskimage() {
+ pprint 2 "build diskimage"
+ pprint 3 "log: ${NANO_OBJ}/_.di"
+
+ (
+ local IMG code_sects code_size
+ local bootcode cfg data efiboot0 gptboot0 swap0
+ local code1 "${NANO_ROOT}" code2 "${NANO_ALTROOT}" # XXXJL NANO_ALTROOT
+
+ IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
+ code_sects=$(awk -v label="$NANO_ROOT" '$5 == label {print $4}' "${NANO_LOG}/_.partitioning")
+ code_size=$(( code_sects * NANO_SECTOR_SIZE ))
+
+ # Build mkimg partition entries
+ if [ -f "${NANO_WORLDDIR}/boot/pmbr" ]; then
+ bootcode="-b ${NANO_WORLDDIR}/boot/pmbr"
+ fi
+
+ for image in gptboot0 efiboot0 swap0 \
+ ${NANO_ROOT} ${NANO_ALTROOT} cfg data; do
+ match=$(awk -v dir="$NANO_OBJ" -v img="$image" -v ssize="$NANO_SECTOR_SIZE" \
+ '$5 == img {
+ if ($5 == "swap0") {
+ print "-p", $2 "/" $5 "::" ($4 * ssize) ":" ($3 * ssize)
+ } else {
+ print "-p", $2 "/" $5 ":=" dir "/_." $5 ".image:" ($3 * ssize)
+ }
+ }' "${NANO_LOG}/_.partitioning")
+
+ if [ -n "$match" ]; then
+ eval "${image}=\"\${match}\""
+ else
+ eval "${image}=\"\""
+ fi
+ done
+
+ # Use fixed variable names when dealing with code partitions
+ eval "code1=\"\$${NANO_ROOT}\""
+ eval "code2=\"\$${NANO_ALTROOT}\""
+
+ # Rename code1 image name to match NANO_IMG1NAME
+ code1=$(echo "$code1" | sed "s|${NANO_OBJ}/_.${NANO_ROOT}.image|${NANO_DISKIMGDIR}/${NANO_IMG1NAME}|")
+
+ # Create boot partition (if any)
+ if is_boot_type BIOS; then
+ make_boot_partition "gptboot0"
+ fi
+
+ # Create ESP partition (if any)
+ if is_boot_type UEFI; then
+ make_esp_partition "efiboot0"
+ fi
+
+ # Swap partition must be greater than 100 MiB
+ if [ "$NANO_SWAP_SIZE" -gt 0 ] && [ "$NANO_SWAP_SIZE" -lt 104857600 ]; then
+ err "Swap size (${NANO_SWAP_SIZE}) too small (must be > 100 MiB)."
+ fi
+
+ # Create secondary code partition (if any)
+ if [ "$NANO_IMAGES" -gt 1 ]; then
+ if [ "$NANO_INIT_IMG2" -gt 0 ]; then
+ echo "Duplicating to second image..."
+ tgt_switch_root_fstab 1 2
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ "${NANO_METALOG}" "$code_sects" \
+ "${NANO_OBJ}/_.${NANO_ALTROOT}.image" "${NANO_WORLDDIR}"
+ tgt_switch_root_fstab 2 1
+ else
+ code2=$(echo "$code2" |
+ sed "s#=${NANO_OBJ}/_.${NANO_ALTROOT}.image#:${code_size}#")
+ fi
+ fi
+
+ # Create cfg partition
+ populate_cfg_part "${NANO_OBJ}/_.cfg.image" \
+ "$NANO_CFGDIR" "$NANO_PARTITION_CFG" "$NANO_CONFSIZE" \
+ "$NANO_METALOG_CFG"
+
+ # Create data partition (if any)
+ if [ "${NANO_DATASIZE}" -ne 0 ]; then
+ populate_data_part "${NANO_OBJ}/_.data.image" \
+ "$NANO_DATADIR" "$NANO_PARTITION_DATA" "$DATA_SIZE" \
+ "$NANO_METALOG_DATA"
+ fi
+
+ echo "Writing out ${NANO_IMGNAME}..."
+ mkimg -s gpt -S ${NANO_SECTOR_SIZE} \
+ --capacity $(( NANO_MEDIASIZE * NANO_SECTOR_SIZE )) \
+ ${bootcode} \
+ ${gptboot0} \
+ ${efiboot0} \
+ ${swap0} \
+ ${code1} \
+ ${code2} \
+ ${cfg} \
+ ${data} \
+ -o ${IMG}
+
+ # Cleanup
+ rm -f "${NANO_OBJ}/_.gptboot0.image" \
+ "${NANO_OBJ}/_.efiboot0.image" \
+ "${NANO_OBJ}/_.${NANO_ALTROOT}.image" \
+ "${NANO_OBJ}/_.cfg.image" \
+ "${NANO_OBJ}/_.data.image" \
+ ) > "${NANO_LOG}/_.di" 2>&1
+}
+
+tgt_switch_root_fstab() {
+ local current new
+ current="$1"
+ new="$2"
+
+ for f in ${NANO_WORLDDIR}/etc/fstab ${NANO_WORLDDIR}/conf/base/etc/fstab; do
+ sed -i "" "s=/dev/gpt/${NANO_LABEL}${current}=/dev/gpt/${NANO_LABEL}${new}=g" "${f}"
+ done
+}
diff --git a/tools/tools/nanobsd/gpt/Files.mtree b/tools/tools/nanobsd/gpt/Files.mtree
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files.mtree
@@ -0,0 +1,10 @@
+. type=dir uname=root gname=wheel mode=0755
+./usr type=dir uname=root gname=wheel mode=0755
+./usr/local type=dir uname=root gname=wheel mode=0755
+./usr/local/sbin type=dir uname=root gname=wheel mode=0755
+./usr/local/sbin/change_password type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/save_cfg type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/save_sshkeys type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/update type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/updatep1 type=file uname=root gname=wheel mode=0555
+./usr/local/sbin/updatep2 type=file uname=root gname=wheel mode=0555
diff --git a/tools/tools/nanobsd/Files/root/change_password b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
copy from tools/tools/nanobsd/Files/root/change_password
copy to tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
--- a/tools/tools/nanobsd/Files/root/change_password
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/change_password
@@ -30,10 +30,8 @@
passwd root
-cfgslice=`grep '/cfg' /etc/fstab | cut -d \ -f 1`
-
trap "umount /cfg" 1 2 15 EXIT
mount /cfg
-cp /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
+cp -p /etc/master.passwd /etc/passwd /etc/pwd.db /etc/spwd.db /etc/group /cfg
umount /cfg
-trap 1 2 15 EXIT
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_cfg
@@ -0,0 +1,100 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Mathieu Arnold
+# Copyright (c) 2010 Alex Bakhtin
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
+
+(
+cd /etc
+find . -type f 2>/dev/null | while read -r relative_path; do
+ filename="${relative_path#./}"
+ if [ ! -f "/cfg/${filename}" ] &&
+ [ ! -f "/cfg/.ignore/${filename}" ]; then
+ #
+ # If file doesn't exist in /cfg and file is not in the "ignore"
+ # list then check if this file is exactly the same as original
+ # file in nanobsd image
+ #
+ if ! cmp -s "/etc/${filename}" "/conf/base/etc/${filename}"; then
+ file_path="${filename%/*}"
+ if [ "$file_path" != "$filename" ]; then
+ if [ ! -d "/etc/${file_path}" ]; then
+ echo "Error: Path /etc/${file_path} is not a directory." >&2
+ exit 1;
+ fi
+ fi
+
+ #
+ # Ask user - how should we handle this file.
+ # Add to cfg (y/n/i)?
+ # y) -> save this file in /cfg
+ # n) -> do not save this file in /cfg for current
+ # script invocation ONLY
+ # i) -> add file to ignore list (/cfg/.ignore hierarchy)
+ # and never try to add this file to /cfg.
+ #
+ # touch is used to add files to /cfg to keep the script
+ # flow straight and easy
+ #
+ read -rp "New file /etc/${filename} found. Add to /cfg (y/n/i)? " key < /dev/tty
+ case "$key" in
+ [yY])
+ if [ "$file_path" != "$filename" ]; then
+ mkdir -vp "/cfg/${file_path}"
+ fi
+ touch "/cfg/${filename}" &&
+ echo "File /etc/${filename} added to /cfg."
+ ;;
+ [iI])
+ mkdir -vp /cfg/.ignore
+ if [ "$file_path" != "$filename" ]; then
+ mkdir -vp "/cfg/.ignore/${file_path}"
+ fi
+ touch "/cfg/.ignore/${filename}" &&
+ echo "File /etc/${filename} added to ignore list."
+ ;;
+ esac
+ fi
+ fi
+done || exit 1
+
+#
+# Actually check all files in /cfg and save if necessary
+#
+cd /cfg
+find . -type f 2>/dev/null | while read -r relative_path; do
+ filename="${relative_path#./}"
+
+ case "$filename" in
+ .ignore/*) continue ;;
+ esac
+
+ if [ -f "/etc/${filename}" ]; then
+ cmp -s "/etc/${filename}" "/cfg/${filename}" ||
+ cp -pfv "/etc/${filename}" "/cfg/${filename}"
+ else
+ #
+ # Give user an option to remove file from /cfg if this file is
+ # removed from /etc
+ #
+ read -rp "File /cfg/${filename} not found in /etc. Remove from /cfg (y/n)? " key < /dev/tty
+ case "$key" in
+ [yY])
+ rm "/cfg/${filename}" &&
+ echo "File /cfg/${filename} removed"
+ ;;
+ esac
+ fi
+done
+)
+
+umount /cfg
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/save_sshkeys
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (c) 2004-2005 Poul-Henning Kamp.
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+mount /cfg
+trap "umount /cfg" 1 2 15 EXIT
+
+mkdir -p /cfg/ssh
+(
+cd /etc/ssh
+for keyfile in ./ssh_host_*; do
+ if [ -f "$keyfile" ]; then
+ cp -p "$keyfile" /cfg/ssh/
+ fi
+done
+)
+
+umount /cfg
+trap - 1 2 15 EXIT
diff --git a/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update
new file mode 100644
--- /dev/null
+++ b/tools/tools/nanobsd/gpt/Files/usr/local/sbin/update
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright (c) 2026 [XXX]
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+set -e
+
+. /etc/nanobsd.conf
+
+: "${NANO_ROOT:?NANO_ROOT not set in /etc/nanobsd.conf}"
+: "${NANO_ALTROOT:?NANO_ALTROOT not set in /etc/nanobsd.conf}"
+
+current_root=$(df -n / | awk 'END {print $1}')
+
+case "$current_root" in
+"/dev/gpt/${NANO_ALTROOT}")
+ exec sh /usr/local/sbin/updatep1
+ ;;
+"/dev/gpt/${NANO_ROOT}")
+ exec sh /usr/local/sbin/updatep2
+ ;;
+*)
+ echo "Invalid root device '${current_root}'." >&2
+ exit 1
+ ;;
+esac
diff --git a/tools/tools/nanobsd/legacy.sh b/tools/tools/nanobsd/legacy.sh
--- a/tools/tools/nanobsd/legacy.sh
+++ b/tools/tools/nanobsd/legacy.sh
@@ -37,6 +37,34 @@
#
METADATA_SECTS=16
+# Newfs parameters to use
+NANO_NEWFS="-b 4096 -f 512 -i 8192 -U"
+
+# makefs parameters to use
+NANO_MAKEFS="-o bsize=4096,density=8192,fsize=512,softupdates=1,version=2"
+
+# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label
+# in preference to /dev/${NANO_DRIVE}
+# Root partition will be ${NANO_LABEL}s{1,2}
+# /cfg partition will be ${NANO_LABEL}s3
+# /data partition will be ${NANO_LABEL}s4
+NANO_LABEL=""
+NANO_SLICE_ROOT=s1
+NANO_SLICE_ALTROOT=s2
+NANO_SLICE_CFG=s3
+NANO_SLICE_DATA=s4
+NANO_PARTITION_ROOT=a
+NANO_PARTITION_ALTROOT=a
+NANO_ROOT=s1a
+NANO_ALTROOT=s2a
+
+# Override user's NANO_DRIVE if they specified a NANO_LABEL
+[ -n "${NANO_LABEL}" ] && NANO_DRIVE="ufs/${NANO_LABEL}" || true
+
+# boot0 flags/options and configuration
+NANO_BOOT0CFG="-o packet -s 1 -m 3"
+NANO_BOOTLOADER="boot/boot0sio"
+
#######################################################################
# Functions and variable definitions used by the legacy nanobsd
# image building system.
@@ -120,6 +148,8 @@
pprint 3 "log: ${NANO_OBJ}/_.cs"
(
+ local CODE_SIZE IMG MNT
+
IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
MNT=${NANO_OBJ}/_.mnt
mkdir -p ${MNT}
@@ -176,6 +206,8 @@
pprint 3 "log: ${NANO_OBJ}/_.cs"
(
+ local CODE_SIZE IMG
+
IMG=${NANO_DISKIMGDIR}/${NANO_IMG1NAME}
CODE_SIZE=$(awk '$3 == 1 {print $2}' "${NANO_LOG}/_.partitioning")
@@ -186,7 +218,7 @@
else
echo "Partition will not be bootable"
fi
- nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
+ nano_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "$(( CODE_SIZE - METADATA_SECTS ))" \
"${NANO_OBJ}/_.disk.part" "${NANO_WORLDDIR}"
mkimg -s bsd -S 512 --capacity $(( CODE_SIZE * 512 )) \
@@ -274,8 +306,7 @@
# Create Data slice, if any.
if [ -n "$NANO_SLICE_DATA" -a "$NANO_SLICE_CFG" = "$NANO_SLICE_DATA" -a \
"$NANO_DATASIZE" -ne 0 ]; then
- pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
- exit 2
+ err "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
fi
if [ $NANO_DATASIZE -ne 0 -a -n "$NANO_SLICE_DATA" ]; then
populate_data_slice /dev/${MD}${NANO_SLICE_DATA} "${NANO_DATADIR}" ${MNT} "${NANO_SLICE_DATA}"
@@ -310,6 +341,7 @@
pprint 3 "log: ${NANO_OBJ}/_.di"
(
+ local CODE_SIZE CONF_SIZE DATA_SIZE
local altroot bootloader cfgimage dataimage diskimage
CODE_SIZE=$(awk '$3 == 1 {print $2}' "${NANO_LOG}/_.partitioning")
@@ -332,7 +364,7 @@
if [ "$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_makefs "${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "$(( CODE_SIZE - METADATA_SECTS ))" \
"${NANO_OBJ}/_.altroot.part" "${NANO_WORLDDIR}"
tgt_switch_root_fstab "${NANO_SLICE_ALTROOT}" "${NANO_SLICE_ROOT}"
@@ -353,7 +385,7 @@
fi
# Create Config slice
- _populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
+ populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
"${NANO_SLICE_CFG}" "${CONF_SIZE}" "${NANO_METALOG_CFG}"
cfgimage="-p freebsd:=${NANO_OBJ}/_.cfg.part"
@@ -361,11 +393,10 @@
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
+ err "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
fi
if [ "${NANO_DATASIZE}" -ne 0 ] && [ -n "${NANO_SLICE_DATA}" ]; then
- _populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" \
+ populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" \
"${NANO_SLICE_DATA}" "${DATA_SIZE}" "${NANO_METALOG_DATA}"
dataimage="-p freebsd:=${NANO_OBJ}/_.data.part"
fi
@@ -384,3 +415,29 @@
"${NANO_OBJ}/_.data.part"
) > ${NANO_LOG}/_.di 2>&1
}
+
+# Create the /etc/fstab file
+tgt_write_fstab() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ # Save config file for scripts
+ echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+ tgt_touch etc/nanobsd.conf
+
+ printf_fstab "# Device" Mountpoint FStype Options Dump "Pass#"
+ printf_fstab "/dev/${NANO_DRIVE}${NANO_ROOT}" / ufs ro 1 1
+ printf_fstab "/dev/${NANO_DRIVE}${NANO_SLICE_CFG}" /cfg ufs rw,noauto 2 2
+ tgt_touch etc/fstab
+ )
+}
+
+# Pick up config files from the special partition
+tgt_etc_remount() {
+ (
+ cd "$NANO_WORLDDIR"
+
+ echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > conf/default/etc/remount
+ tgt_touch conf/default/etc/remount
+ )
+}
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -28,6 +28,23 @@
set -e
+legacy() {
+ # Pull in legacy stuff on demand
+ . "${topdir}/legacy.sh"
+}
+
+gpt() {
+ # Pull in gpt stuff on demand
+ . "${topdir}/gpt.sh"
+}
+
+is_defined() {
+ case $(type $1 2>/dev/null) in
+ *function) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
nanobsd_sh=$(realpath $0)
topdir=$(dirname ${nanobsd_sh})
. "${topdir}/_xxx_includes.subr"

File Metadata

Mime Type
text/plain
Expires
Sat, Aug 22, 1:51 PM (6 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37086936
Default Alt Text
D58964.id184545.diff (45 KB)

Event Timeline