Project

General

Profile

Feature #7584

Improve 'zpool labelclear' command

Added by Ganael Laplanche almost 3 years ago. Updated about 2 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
zfs - Zettabyte File System
Start date:
2016-11-15
Due date:
% Done:

0%

Estimated time:
Difficulty:
Bite-size
Tags:
needs-triage

Description

Following #6418 "zpool should have a label clearing command", find attached a patch that improves the 'zpool labelclear' command.

This patch has been tested on FreeBSD (only) and has been originally reported and described here :

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

The attached patch is a port of the FreeBSD patch for Illumos rev. 9185393.


Files

patch-zpool_labelclear-Illumos-9185393.txt (8.11 KB) patch-zpool_labelclear-Illumos-9185393.txt Patch for rev. 9185393 Ganael Laplanche, 2016-11-15 08:47 AM
patch-zpool_labelclear-second_take.txt (9.36 KB) patch-zpool_labelclear-second_take.txt Second version of the patch Ganael Laplanche, 2017-07-13 10:32 AM
patch-zpool_labelclear-take_three.txt (9.44 KB) patch-zpool_labelclear-take_three.txt Ganael Laplanche, 2017-07-16 12:23 PM

History

#1

Updated by Yuri Pankov almost 3 years ago

You should really describe the enhancement here, not refer to external bug tracker.

#2

Updated by Ganael Laplanche almost 3 years ago

Yes, sorry. I just wanted to avoid duplicating info. Here is what I originally posted (examples apply to FreeBSD).

----
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 :

  1. zpool create test ada1
    [... work ...]
  2. zpool export test

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

  1. newfs /dev/ada1
  2. mount /dev/ada1 /mnt
  3. touch /mnt/foo
  4. umount /mnt

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

  1. 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 :

  1. zpool import test
  2. zpool export test
  3. 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)
  1. zpool labelclear -m -f /dev/ada1
  2. zpool import
    <nothing!>
  3. mount /dev/ada1 /mnt
  4. 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 :

  1. zpool create test ada1
  2. zpool export test
  3. newfs_msdos /dev/ada1
  4. mount -t msdosfs -o large /dev/ada1 /mnt
  5. touch /mnt/foo
  6. umount /mnt
  7. 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 :

  1. 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 :

  1. zpool labelclear -e -m -f /dev/ada1
  2. zpool import
    <nothing!>
  3. mount -t msdosfs -o large /dev/ada1 /mnt
  4. 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 :

  1. zpool create test ada1
  2. zpool export test
  3. zpool labelclear -c -f /dev/ada1
  4. 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.
----

#3

Updated by Ganael Laplanche about 2 years ago

Hi everyone,

Finally, here is an improved version of the patch that builds
successfully on Illumos (that was apparently not the case with previous version as the patch had only been tested on FreeBSD).

It has now been tested and validated on OpenIndiana 5.11 (illumos-48d8443e35).

Best regards,

Ganael.

#4

Updated by Ganael Laplanche about 2 years ago

FYI, a pull request is available here :

https://github.com/openzfs/openzfs/pull/424

with ongoing discussions + updated patches.

#5

Updated by Ganael Laplanche about 2 years ago

Here is the latest patch available so far.

Also available in: Atom PDF