From: Goffredo Baroncelli <kreijack@libero.it>
To: Chris Mason <clm@fb.com>
Cc: systemd-devel@lists.freedesktop.org,
linux-btrfs <linux-btrfs@vger.kernel.org>
Subject: Re: [systemd-devel] [HEADS-UP] Discoverable Partitions Spec
Date: Wed, 12 Mar 2014 23:18:09 +0100 [thread overview]
Message-ID: <5320DD21.1040007@libero.it> (raw)
In-Reply-To: <5320B18C.9050400@inwind.it>
On 03/12/2014 08:12 PM, Goffredo Baroncelli wrote:
[...]
> I am working to prototype something like that. A "mount.btrfs" command which
> 1) handles the rollback (i.e. the user make a snapshot which is a rollback; if something goes wrong and the machine reboot before ending the process, during the subvolume mounting phase the rollback replaces the "original" subvolume)
>
> 2) handles the automount (i.e. if a subvolume has the right xattr it is automatically mounted in the right place)
>
> My idea is that the subvolume are grouped so:
>
> @<name> simple subvolume
> @<name>.<timestamp> snapshot of subvolume <name>
> @<name>.rollback rollback subvolume
>
> If @<name>.rollback exists, then it replace @<name> (something went wrong, the machine rebooted so the rollback have to take place of the original subvolume)
>
> For each @<name> subvolume the following xattrs are considered:
> user.btrfs.automount=1|0 the subvolume has to be automounted
> user.btrfs.mountpoint=<path> subvolume mount point
>
>
> So this "mount.btrfs" command should:
>
> 1) mount the root btrfs filesystem (subvolid=5) in a temporary directory
> 2) performing the auto rollback (this behaviour can be controlled by another xattr)
> 3) mount the subvolume "@" as "root" (like the default one) in the right mount point
> 4) for each subvolume which has user.btrfs.automount=1, it should be mounted under the path stored in the "user.btrfs.mntpoint" xattr (relative to "@" or absolute)
> 5) umount the btrfs filesystem mounted at #1, or better move it to a new position in order
> to allow managing (snapshot) of the different subvolumes.
>
Below my POC.
$ sudo mount /dev/loop0 t
$ sudo getfattr -d t/{@*,.}
# file: t/@
user.btrfs.automount="1"
# file: t/@__boot__
user.btrfs.automount="1"
user.btrfs.mountpoint="/boot"
# file: t/@.broken-0
user.btrfs.automount="1"
# file: t/@.broken-1
user.btrfs.automount="1"
# file: t/@__home__
user.btrfs.automount="1"
user.btrfs.mountpoint="/home"
# file: t/@__root__.12345
user.btrfs.automount="0"
# file: t/@space space
user.btrfs.automount="0"
# file: t/@__srv__
user.btrfs.automount="0"
# file: t/.
user.btrfs.automount="1"
user.btrfs.autorollback="1"
user.btrfs.mountpoint="/var/btrfs"
$ sudo umount t
$ sudo sh mount.btrfs /dev/loop0 t
Mount /dev/loop0/@ -> t
Mount /dev/loop0/@__boot__ -> t//boot
Mount /dev/loop0/@__home__ -> t//home
Mount /dev/loop0 -> t//var/btrfs
ghigo@venice:~/btrfs/mount-btrfs$ find t
t
t/var
t/var/btrfs
t/var/btrfs/@__boot__
t/var/btrfs/@__home__
t/var/btrfs/@__srv__
t/var/btrfs/@__root__.12345
t/var/btrfs/@space space
t/var/btrfs/@.broken-0
t/var/btrfs/@.broken-0/var
t/var/btrfs/@.broken-0/var/btrfs
t/var/btrfs/@.broken-0/@__boot__
t/var/btrfs/@.broken-0/@__home__
t/var/btrfs/@.broken-0/boot
t/var/btrfs/@.broken-0/home
t/var/btrfs/@.broken-0/non-rollback-subvol
t/var/btrfs/@.broken-1
t/var/btrfs/@.broken-1/var
t/var/btrfs/@.broken-1/var/btrfs
t/var/btrfs/@.broken-1/@__boot__
t/var/btrfs/@.broken-1/@__home__
t/var/btrfs/@.broken-1/boot
t/var/btrfs/@.broken-1/home
t/var/btrfs/@.broken-1/rollback-subvol
find: File system loop detected; ‘t/var/btrfs/@’ is part of the same file system loop as ‘t’.
t/@__boot__
t/@__home__
t/boot
t/home
t/non-rollback-subvol
$cat mount.btrfs
#!/bin/sh
XAAMOUNT="user.btrfs.automount"
XAAMNTPNT="user.btrfs.mountpoint"
XAAROLLBACK="user.btrfs.autorollback"
xdebug() {
[ -z "$DEBUG" ] && return
echo "$@"
}
autorollback() {
( cd "$tmpdir"; ls -d @*.rollback 2>/dev/null) | while read drb; do
rbfullpath="$tmpdir/$drb"
[ ! -d "$rbfullpath" ] && continue
is_btrfs_subvol "$rbfullpath" || continue
f="$(get_fattr $XAAROLLBACK "$rbfullpath" )"
[ "x$f" = "x0" ] && continue
d="$(echo $drb | sed -e "s/.rollback$//")"
fullpath="$tmpdir/$d"
if [ -d "$fullpath" ]; then
f="$(get_fattr $XAAROLLBACK "$fullpath" )"
[ "x$f" = "x0" ] && continue
i=0
while true; do
newfullpath="$fullpath.broken-$i"
if [ ! -e "$newfullpath" ]; then
mv "$fullpath" "$newfullpath"
break
fi
i=$(($i+1))
done
fi
echo "Rollback $d"
mv "$rbfullpath" "$fullpath"
done
}
is_btrfs_subvol() {
[ "$(stat -c "%i" "$1")" -eq "256" ]
}
get_fattr() {
name="$1"
file="$2"
getfattr --only-values -n "$name" "$file" 2>/dev/null || echo -n ""
}
automount() {
tmpdir="$1"
srcdev="$2"
mntpnt="$3"
fullpath="$tmpdir/@"
[ ! -d "$fullpath" ] && return 1
is_btrfs_subvol "$fullpath" || return 1
b="$(get_fattr $XAAMOUNT "$fullpath" )"
[ "x$b" = "x0" ] && return 1
path="$(get_fattr $XAAMNTPNT "$fullpath" )"
if [ -n "$path" ] ; then
mntpnt="$path"
fi
xdebug mount -o "subvol=@" "$srcdev" "$mntpnt/"
echo "Mount $srcdev/@ -> $mntpnt"
mount -o "subvol=@" "$srcdev" "$mntpnt/" || return 1
( cd "$tmpdir"; ls -d @* 2>/dev/null) | grep -v "\." | while read d; do
[ "x$d" = "x./@" ] && continue
fullpath="$tmpdir/$d"
[ ! -d "$fullpath" ] && continue
is_btrfs_subvol "$fullpath" || continue
path="$(get_fattr $XAAMNTPNT "$fullpath" )"
[ -z "$path" ] && continue
b="$(get_fattr $XAAMOUNT "$fullpath" )"
[ "x$b" = "x0" ] && continue
echo "Mount $srcdev/$d -> $mntpnt/$path"
xdebug mount -o "subvol=$d" "$srcdev" "$mntpnt/$path"
mkdir -p "$mntpnt/$path"
mount -o "subvol=$d" "$srcdev" "$mntpnt/$path"
done
return 0
}
main() {
#create tempdir
tmpdir=$(mktemp --directory)
srcdev="$1"
mntpnt="$2"
xdebug mount -t btrfs "$srcdev" "$tmpdir"
mount -o subvolid=5 -t btrfs "$srcdev" "$tmpdir" || exit
# get the global value
GLOBALAMOUNT=$(get_fattr $XAAMOUNT "$tmpdir/.")
GLOBALAROLLBACK=$(get_fattr $XAAROLLBACK "$tmpdir/.")
BTRFSROOT="$(get_fattr $XAAMNTPNT "$tmpdir/." )"
xdebug "GLOBALAMOUNT=$GLOBALAMOUNT, GLOBALAROLLBACK=$GLOBALAROLLBACK"
if [ "x$GLOBALAROLLBACK" = "x1" ]; then
autorollback "$tmpdir"
fi
if [ "x$GLOBALAMOUNT" = "x1" ]; then
if ! automount "$tmpdir" "$srcdev" "$mntpnt"; then
echo 1>&2 "ERROR: unable to mount the filesystem"
exit 10
fi
umount "$tmpdir"
if [ -n "$BTRFSROOT" ]; then
mkdir -p "$mntpnt/$BTRFSROOT"
echo "Mount $srcdev -> $mntpnt/$BTRFSROOT"
mount -o subvolid=5 "$srcdev" "$mntpnt/$BTRFSROOT"
fi
else
mount --move "$tmpdir" "$mntpnt"
fi
}
#FIXME: allow options
if [ $# -ne 2 ]; then
echo "usage: $0 <srcdev> <mount-point>"
exit 1
fi
main "$@"
--
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D 17B2 0EDA 9B37 8B82 E0B5
prev parent reply other threads:[~2014-03-12 22:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20140307182603.GA22874@tango.0pointer.de>
2014-03-10 18:34 ` [systemd-devel] [HEADS-UP] Discoverable Partitions Spec Goffredo Baroncelli
2014-03-10 18:53 ` Kay Sievers
2014-03-10 18:59 ` Goffredo Baroncelli
2014-03-10 19:43 ` Chris Murphy
2014-03-10 20:02 ` Lennart Poettering
2014-03-10 20:21 ` Chris Mason
2014-03-10 20:53 ` Chris Murphy
2014-03-10 21:09 ` Lennart Poettering
2014-03-10 22:44 ` Goffredo Baroncelli
2014-03-10 22:39 ` Goffredo Baroncelli
2014-03-10 23:45 ` Lennart Poettering
2014-03-10 23:59 ` Alex Elsayed
2014-03-11 14:30 ` [systemd-devel] " Calvin Walton
2014-03-12 17:24 ` Chris Mason
2014-03-12 19:12 ` Goffredo Baroncelli
2014-03-12 19:31 ` Chris Murphy
2014-03-12 19:55 ` Goffredo Baroncelli
2014-03-12 23:22 ` Brendan Hide
2014-03-12 22:18 ` Goffredo Baroncelli [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5320DD21.1040007@libero.it \
--to=kreijack@libero.it \
--cc=clm@fb.com \
--cc=kreijack@inwind.it \
--cc=linux-btrfs@vger.kernel.org \
--cc=systemd-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.