[Bug 204622] [zfs] [patch] Improve 'zpool labelclear' command

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Tue Nov 17 08:39:21 UTC 2015


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=204622

            Bug ID: 204622
           Summary: [zfs] [patch] Improve 'zpool labelclear' command
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Keywords: patch
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: ganael.laplanche at corp.ovh.com
          Keywords: patch

Created attachment 163238
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=163238&action=edit
Patch for 10.2

Hi,

Here is a proposal to improve the "zpool labelclear" command. Currently, this
command blindly overwrites both the 2 first and last labels of a disk (i.e. 2 x
256 kB at the beginning and end of a disk).

This can lead to tricky situations where labels are still seen while another
filesystem has taken place over the original zpool. In such a case, still being
able to import the zpool can lead to destroying the filesystem that has been
created over the pool.

Here is a simple example :

# zpool create test ada1
[... work ...]
# zpool export test

then, one decides to re-format the drive (without clearing the labels, damn!) :

# newfs /dev/ada1
# mount /dev/ada1 /mnt
# touch /mnt/foo
# umount /mnt

Unfortunately, ZFS labels are still there as newfs did not overwrite them :

# zpool import
   pool: test
     id: 17834878187816880903
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        test        ONLINE
          ada1      ONLINE

If we import/export the pool, labels a re-written and the UFS filesystem is
broken :

# zpool import test
# zpool export test
# mount /dev/ada1 /mnt
mount: /dev/ada1: Invalid argument

To minimize the risks of overwriting important data, I have looked for a way to
invalidate a label by writing the *minimal* amount of data. I have found a
simple way to invalidate a whole label by just modifying 1 byte: setting an
invalid encoding for its nvlist is enough to make it considered as broken and
ignored. The attached patch adds a -m (minimal) option to the 'labelclear'
command that exploits this hack. With this option, we are now able to clear
labels (to avoid a future import/export) without breaking a UFS filesystem :

(after having unmounted UFS mountpoint /mnt)
# zpool labelclear -m -f /dev/ada1
# zpool import
<nothing!>
# mount /dev/ada1 /mnt
# ls /mnt
.snap   foo

Of course, if the 4 bytes (4 * 1 byte) which are overwritten here are important
for the new filesystem, it will be broken too. Anyway, erasing 4 bytes will
always be less risky than erasing 4 * 256 kB!

There are other situations where one would like to clear beginning or ending
labels only ; the patch adds two options for that purpose : -b (beginning) and
-e (ending). It also adds the ability to invalidate a single label using the -i
(index) option. Here is an example with a msdosfs filesystem :

# zpool create test ada1
# zpool export test
# newfs_msdos /dev/ada1
# mount -t msdosfs -o large /dev/ada1  /mnt
# touch /mnt/foo
# umount /mnt
# zdb -l /dev/ada1 
--------------------------------------------
LABEL 0
--------------------------------------------
failed to unpack label 0
--------------------------------------------
LABEL 1
--------------------------------------------
failed to unpack label 1
--------------------------------------------
LABEL 2
--------------------------------------------
    version: 5000
    name: 'test'
    [...]
--------------------------------------------
LABEL 3
--------------------------------------------
    version: 5000
    name: 'test'
    [...]

Ending labels remain valid :

# zpool import
   pool: test
     id: 693883832785598877
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        test        ONLINE
          ada1      ONLINE

If we import that filesystem, we will be breaking our msdosfs. To invalidate
those two ending labels (only) without breaking our filesystem, we can safely
perform the following :

# zpool labelclear -e -m -f /dev/ada1
# zpool import
<nothing!>
# mount -t msdosfs -o large /dev/ada1 /mnt
# ls /mnt
foo

Finally, the original command did a blind invalidation, without even trying to
check that there is a valid label to erase. I have added a '-c' (check) option
that tries to validate a label before doing anything on the disk. It will exit
if no label is detected, avoiding to erase important data. This feature will
try to unpack the pool configuration (nvlist) to see if it is valid or not ;
this should be enough in most cases :

# zpool create test ada1
# zpool export test
# zpool labelclear -c -f /dev/ada1
# zpool labelclear -c -f /dev/ada1
Label clear failed on vdev /dev/ada1

Here, the second call did nothing as the label has already been invalidated.

Find attached two patches: one for 10.2 and another one for -CURRENT (r290928).
It keeps full compatibility with the zpool command interface, as well as libzfs
and libnvpair ABIs.

I am submitting this patch here as it's been developped and tested on FreeBSD,
please tell me if it would be better posted on Illumos Gate.

Best regards,
Ganael.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list