Re: bin/60383: fssconfig(8): distinguish between taking and loading a snapshot
"Robert Elz via gnats" <[email protected]> Sun, 19 Jul 2026 12:10:01 +0000 (UTC)
| Newsgroups | gmane.os.netbsd.bugs |
|---|---|
| Message-ID | <[email protected]> |
The following reply was made to PR bin/60383; it has been noted by GNATS. From: Robert Elz <[email protected]> To: Taylor R Campbell <[email protected]> Cc: [email protected], [email protected] 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 <[email protected]> Message-ID: <[email protected]> | - 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--