NetBSD Problem Report #60383

From www@netbsd.org  Mon Jun 29 02:26:53 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.netbsd.org", Issuer "R13" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id DB3BE1A923A
	for <gnats-bugs@gnats.NetBSD.org>; Mon, 29 Jun 2026 02:26:52 +0000 (UTC)
Message-Id: <20260629022651.D75CB1A923B@mollari.NetBSD.org>
Date: Mon, 29 Jun 2026 02:26:51 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: fssconfig(8): distinguish between taking and loading a snapshot
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>

>Number:         60383
>Category:       bin
>Synopsis:       fssconfig(8): distinguish between taking and loading a snapshot
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 29 02:30:00 +0000 2026
>Last-Modified:  Sat Jul 25 19:30:02 +0000 2026
>Originator:     Taylor R Campbell
>Release:        current, 11, 10, 9, ...
>Organization:
The NetFSS Foundasnapshot, Inc.
>Environment:
>Description:

	The way to create a new snapshot /fs/.snap/20260628 archiving
	the current state of a file system /fs, and configure fss0 to
	point at it, is:

		fssconfig fss0 /fs /fs/.snap/20260628

	The way to load an existing snapshot /fs/.snap/20260628
	recovering a past state of the file system /fs is:

		fssconfig fss0 /fs /fs/.snap/20260628

	Yes, those are the same command.

	This is confusing and error-prone: what operation we are
	_trying_ to do should not depend on what files exist on disk.

	When _creating_ a snapshot, fssconfig(8) should be able to
	report an error if the file already exists.

	When _loading_ a snapshot, fssconfig(8) should be able to
	report an error if the file does not actually exist.

>How-To-Repeat:

	try to use ffs fss snapshots (say that five times fast!)

>Fix:

	Yes, please!

	Perhaps we should have separate options like -C and -L for
	`create' and `load'.

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60383 CVS commit: src/share/man/man4
Date: Mon, 6 Jul 2026 13:37:08 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Mon Jul  6 13:37:08 UTC 2026

 Modified Files:
 	src/share/man/man4: fss.4

 Log Message:
 fss(4): Clarify FSSIOCSET operation for persistent snapshots.

 Prompted by the persistent confusion on my part that led to:

 PR bin/60383: fssconfig(8): distinguish between taking and loading a
 snapshot


 To generate a diff of this commit:
 cvs rdiff -u -r1.15 -r1.16 src/share/man/man4/fss.4

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60383 CVS commit: src/usr.sbin/fssconfig
Date: Mon, 6 Jul 2026 16:52:32 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Mon Jul  6 16:52:32 UTC 2026

 Modified Files:
 	src/usr.sbin/fssconfig: fssconfig.8

 Log Message:
 fssconfig(8) Rework man page and give more practical examples.

 Prompted by the persistent confusion on my part that led to:

 PR bin/60383: fssconfig(8): distinguish between taking and loading a
 snapshot


 To generate a diff of this commit:
 cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/fssconfig/fssconfig.8

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60383 CVS commit: src/usr.sbin/fssconfig
Date: Mon, 6 Jul 2026 16:53:56 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Mon Jul  6 16:53:56 UTC 2026

 Modified Files:
 	src/usr.sbin/fssconfig: fssconfig.8

 Log Message:
 fssconfig(8): Fix punctuation-o noticed milliseconds after commit.

 Prompted by the persistent confusion on my part that led to:

 PR bin/60383: fssconfig(8): distinguish between taking and loading a
 snapshot


 To generate a diff of this commit:
 cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/fssconfig/fssconfig.8

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Cc: 
Subject: Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
Date: Sat, 18 Jul 2026 20:30:28 +0000

 Would also be nice if creating and mounting a snapshot didn't require
 specifying an fssN device, just like dumping a snapshot with dump(8)
 doesn't require that.

 For example, perhaps the interface could look something like:

 - Take a snapshot without mounting it:

 	# snapfs /home /home/.snap/20260718

 - Mount a snapshot:

 	# mount -t snapshot /home/.snap/20260718 /mnt

 Under the hood, it might be nice if /dev/fss were a cloning device so
 programs could just open("/dev/fss") without having to allocate an
 fssN unit themselves.

From: Robert Elz <kre@munnari.OZ.AU>
To: Taylor R Campbell <riastradh@NetBSD.org>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
Date: Sun, 19 Jul 2026 19:08:33 +0700

 This is a multipart MIME message.

 --==_Exmh_1784462650_178700
 Content-Type: text/plain; charset=us-ascii

     Date:        Sat, 18 Jul 2026 20:30:28 +0000
     From:        Taylor R Campbell <riastradh@NetBSD.org>
     Message-ID:  <20260718203030.422B284DA5@mail.netbsd.org>

   | - Mount a snapshot:
   | 	# mount -t snapshot /home/.snap/20260718 /mnt

 If you're meaning to mount an existing snapshot that way, then fine,
 just needs a mount_snapshot command to make it work I expect.  But
 if you expect that to create the snapshot, and mount it, the same way
 that dump -x creates the snapshot and dumps it, it would need more or
 perhaps just different, information than that - in what you give there
 there's no information about what filesystem to snapshot.

 You can't assume it is /home as there is no requirement the snapshot
 backing file is on the same filesystem as is being snapshot (snapshotted?)

 What could be done, and would be more akin to what dump does is

 	mount -t snapshot /home /mnt

 which would make a snapshot of /home in some unnamed file on its
 filesystem, and mount that on /mnt - destroying the snapshot when
 /mnt is umounted, just as dump destroys its when the backup has
 completed.

 I kind of agree on making fss into a cloner - the only issue is that
 this one (like cgd and raid etc) is one where the user (or script)
 needs to know what it is getting, because it needs to be able to use
 the same one again later, most users of cloning devices don't care
 which minor dev is assigned to them, whatever it is just gets used,
 and closed.

 I have a script (which I will attach below) that I find useful when
 dealing with all these pseudo-disk type devices (vnd, cgd, ...) which
 finds the first free one, and prints its name - it isn't race proof,
 two instances of it run at once will return the same name, but for most
 normal uses it works just fine.  Usage is just something like "next_avail ffs"
 and it will output fss0 (or fss3 or whatever is the first free).

 kre

 ps: I don't expect the attachment will survive into gnats, and perhaps
 not even to netbsd-bugs, if anyone, if anyone else wants a copy, let me
 know, I will either e-mail them, or make it available on munnari.oz.au
 for anon ftp (no http servers there).

 --==_Exmh_1784462650_178700
 Content-Type: application/octet-stream ; name="next_avail"
 Content-Description: next_avail
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="next_avail"

 #! /bin/sh

 # Usage: next_avail cloner-type-disk
 #	eg: next_avail vnd
 #			(or cgd or raid ...)

 usage()
 {
 	printf >&2 'Usage: %s xxx ...\n' "${0##*/}"
 	if [ -n "$1" ]
 	then
 		printf >&2 "$@"
 	else
 		printf >&2 '       where xxx is a disk-type driver name\n'
 	fi
 	exit 2
 }

 case "$#" in
 0)	usage;;
 esac
 E=3D
 for A
 do
 	case "${A}" in
 	(*[0-9]) E=3D"${E} ${A}";;
 	esac
 done
 if [ -n "${E}" ]
 then
 	usage '       Do not include unit numbers:%s\n' "${E}"
 fi

 # Note that while this script works for any disk type device
 # it is only useful for those that can be created on demand by
 # some config command ... "next_avail wd" might reveal that wd3
 # is the next, indicating that wd0 wd1 and wd2 are all in use,
 # but there is nothing much that can be done about that, should
 # a new wd arrive (hot plugged) the kernel will simply assign the
 # id at that time, there is nothing another script (or a human)
 # using this script can do to influence that.


 # Any specific units of devices that are never to be made available
 # via this script, should be listed here.   These are typically ones
 # known in fstab, or some other config file, and so should not be
 # simply usurped for casual use (there is no requirement that they
 # actually be in use at any particular time).
 RESERVED=3D'cgd0 ccd0'

 # The script (temporarily, just while executing) appends assigned
 # units to the RESERVED list, so if request asks for 'raid raid' (etc)
 # 2 different (currently free) raid unit numbers will be returned.

 next_avail ()
 {
 	local dev=3D"$1"
 	local N=3D$(( ${#dev} + 1 ))
 	local unit units

 	sysctl -n kern.drivers	|
 	    tr , '\012'		|
 	    tr -d ']['		|	=

 	    grep " ${dev}\$" >/dev/null 2>&1 || {
 		printf >&2 'No %s driver in booted kernel\n' "${dev}"
 		printf \\n
 		return 1
 	}

 	# Discover which units are currently known to the kernel
 	# (ie: in use already).   To those we add any reserved
 	# units that we are to assume are (or might be) in use,
 	# whether they actually are or not (ie: never asign).
 	units=3D$(
 		{
 			sysctl -n hw.disknames
 			printf '%s\n' "${RESERVED}"
 		}						|
 			tr ' ' '\012'				|
 			grep '^'"${dev}"'[0-9]'			|
 			sort -u -n -k "1.$N"			)

 	test -z "${units}" && {

 		# Currently, ${dev} is not in hw.disknames, so
 		# no units are in use.  That means that as long
 		# as the entry for ${dev}0 is in /dev, that one
 		# is free, and obviously is the first, nothing
 		# more to do, we found it.

 		test -e "/dev/${dev}0" ||
 		test -e "/dev/${dev}0a" || {
 			printf >&2 "No %s's available!\\n" "${dev}"
 			printf \\n
 			return 1
 		}
 		RESERVED=3D"${RESERVED} ${dev}0"
 		printf '%s\n' "${dev}0"
 		return
 	}

 	# Now fine the lowest free unit number.

 	# Note we just need to scan the list once.  units is sorted,
 	# and contains those which are in use, 0 1 2 4 5 7
 	# N runs 0 1 2 3 4 ...  as long as the two match, the unit
 	# is in use, onto the next, when N and the unit are different,
 	# then dev$N is not currently in use, which is all we need.
 	N=3D0
 	for unit in ${units}
 	do
 		if [ "${unit}" !=3D "${dev}${N}" ]
 		then
 			break
 		fi
 		N=3D$(( N + 1 ))
 	done

 	# If the first one not in use we found has no /dev
 	# entry, then we failed, no available ${dev} is free.
 	test -e "/dev/${dev}${N}" ||
 	test -e /dev/"${dev}${N}a" || {
 		printf >&2 "All %s's in use\\n" "${dev}"
 		printf \\n
 		return 1
 	}

 	# Success!
 	RESERVED=3D"${RESERVED} ${dev}${N}"
 	printf '%s\n' "${dev}${N}"
 }


 X=3D0
 for A
 do
 	next_avail "${A}"
 	: $(( X |=3D $? ))
 done
 exit $X
 --==_Exmh_1784462650_178700--


From: Taylor R Campbell <riastradh@NetBSD.org>
To: Robert Elz <kre@munnari.OZ.AU>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
Date: Sun, 19 Jul 2026 12:25:09 +0000

 > Date: Sun, 19 Jul 2026 19:08:33 +0700
 > From: Robert Elz <kre@munnari.OZ.AU>
 > 
 >     Date:        Sat, 18 Jul 2026 20:30:28 +0000
 >     From:        Taylor R Campbell <riastradh@NetBSD.org>
 >     Message-ID:  <20260718203030.422B284DA5@mail.netbsd.org>
 > 
 >   | - Mount a snapshot:
 >   | 	# mount -t snapshot /home/.snap/20260718 /mnt
 > 
 > If you're meaning to mount an existing snapshot that way, then fine,
 > just needs a mount_snapshot command to make it work I expect.

 Yes, that is exactly what I meant, which would make sense in the
 context of the first part I suggested:

 	- Take a snapshot without mounting it:

 		# snapfs /home /home/.snap/20260718

 > What could be done, and would be more akin to what dump does is
 > 
 > 	mount -t snapshot /home /mnt
 > 
 > which would make a snapshot of /home in some unnamed file on its
 > filesystem, and mount that on /mnt - destroying the snapshot when
 > /mnt is umounted, just as dump destroys its when the backup has
 > completed.

 Yes, that would also be nice.  If /home is not ffs, it would need a
 temporary place for the storage to go, something like:

 	mount -t snapshot -o snapstore=/var/tmp /home /mnt

From: Robert Elz <kre@munnari.OZ.AU>
To: Taylor R Campbell <riastradh@NetBSD.org>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
Date: Wed, 22 Jul 2026 14:16:06 +0700

     Date:        Sun, 19 Jul 2026 12:25:09 +0000
     From:        Taylor R Campbell <riastradh@NetBSD.org>
     Message-ID:  <20260719122511.54CC984D41@mail.netbsd.org>

   | Yes, that is exactly what I meant, which would make sense in the
   | context of the first part I suggested:
   |
   | 	- Take a snapshot without mounting it:
   |
   | 		# snapfs /home /home/.snap/20260718

 Except it didn't, there wasn't enough explanation, it might just
 have meant first "this is how one simply makes a snapshot" (that one
 was clear enough) and second, "this is what you do if you want to make
 a snapshot and have it mounted".

 If "Mount a snapshot" had been "Mount an existing snapshot" or words
 to that effect, it would have been clearer.   That's why I asked which
 meaning you intended.

 kre

From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Cc: Robert Elz <kre@munnari.OZ.AU>
Subject: Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
Date: Sat, 25 Jul 2026 19:28:30 +0000

 Another thing that would be nice: mount a snapshot -- or any file
 system, really -- just for the duration of a command, so that you
 could, e.g., easily write a cron job that rsyncs a snapshot without
 having to teach rsync(1) (or tar(1) or tarsnap(1) or borg(1) or
 whatever) how to create snapshots on NetBSD:

 	withsnapmount /fs /fs/.snap/snapname /mnt \
 	rsync -aH /mnt/. backuphost:/backups/$(hostname)/.

 (How to distinguish taking a new snapshot from loading an existing
 snapshot in this operation is left as an exercise for the reader's
 imagination.)



 Also, for comparison, here's the interface on FreeBSD:

 1. Create a snapshot /fs/.snap/snapname of the file system /fs
    (assuming that is, in fact, the mount point) using the
    mksnap_ffs(8) command:

 	# mksnap_ffs /fs/.snap/snapname

 2. Create a snapshot /fs/.snap/snapname of the file system /fs, using
    the mount(8) command -- but this doesn't actually mount it,
    apparently:

 	# mount -u -o snapshot /fs/.snap/snapname /fs

 3. Given a snapshot that was previously created, mount it at /mnt:

 	# mdconfig -a -t vnode -o readonly -f /fs/.snap/snapname -u 4
 	# mount -r /dev/md4 /mnt

 Except for mksnap_ffs(8), this strikes me as very confusing!  I'm not
 sure we want to copy it.

 https://web.archive.org/web/20260722195637/https://docs.freebsd.org/en/book=
 s/handbook/disks/#snapshots
 https://web.archive.org/web/20251118192326/https://man.freebsd.org/cgi/man.=
 cgi?query=3Dmksnap_ffs&sektion=3D8&format=3Dhtml
 https://web.archive.org/web/20260220073336/https://man.freebsd.org/cgi/man.=
 cgi?format=3Dhtml&query=3Dmount&sektion=3D8

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.