Quantcast
Channel: Active questions tagged openzfs - Server Fault
Viewing all articles
Browse latest Browse all 29

ZFS silently overwrites the later mirrored devs, without any logs?

$
0
0

Given two mirrored drives:

  • /dev/loop1 of zfs1.img
  • /dev/loop2 of zfs2.img

If the drives contain different data, even if the copies in zfs2.img are newer, or zfs2.img contains extra files, ZFS always silently uses state of zfs1.img, and overwrites all files in zfs2.img.

In these situations, the most favourable behaviour would be to list out all the conflicting copies and let the user (or administrator) decide.

ZFS is designed to be a smart filesystem that perform automatic recovery with minimal user interference. However, ZFS should at least leave a log of its actions, especially when it decides to delete a file. I have searched extensively but found no mention of such a log.

Step to reproduce:

  1. Create a simple mirror.
  2. Write a common file to both drives, then export.
  3. Unmount zfs2.img; import with only zfs1.img, modify the common file, write a new file one, export.
  4. Mount zfs2.img, unmount zfs1.img; import with only zfs2.img, modify the common file, write a new file two, export.

At this stage:

  • zfs1.img contains its own version of the common file, and the new file one.
  • zfs2.img contains its own version of the common file, and the new file two. The version of the common file in zfs2.img is newer. zfs2.img also contains an extra new file two.

Continuing with the reproduction:

  1. Mount zfs1.img; import with both zfs1.img and zfs2.img mounted, note that the version and files of zfs1.img are shown in the filesystem. The version and files of zfs2.img is not available. Export.

  2. Mount zfs2.img, unmount zfs1.img; import with only zfs2.img, note that the version and the new file two in zfs2.img are silently overwritten. Export.

The issue is now reproduced. Even though the version in zfs2.img is newer and there is a newer file in zfs2.img, both are overwritten without any error messages.

I am still unable to find any logs mentioning this issue.

Additional step: If the first drive is replaced with a blank drive, ZFS does not overwrite drive two with the blank drive one, as normally expected. Instead, the blank drive one is populated with the data from drive two:

  1. Create a new blank drive, import, replace missing drive one with the newly created drive. Export.

Code to reproduce:

(1) Create a simple mirror.

print_status() {printf -- 'vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n'ls -Al /zpool_test/ ; cat /zpool_test/* ; echo ; losetup ; zpool list -v ; zpool status -vprintf -- '^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n'}printf '(1) : Create mirror\n'tmpdir=$(mktemp -d)cd "${tmpdir}"truncate -s 100M "${tmpdir}/zfs1.img"truncate -s 100M "${tmpdir}/zfs2.img"loop1=$(losetup -f --show "${tmpdir}/zfs1.img")loop2=$(losetup -f --show "${tmpdir}/zfs2.img")/sbin/modprobe zfszpool create zpool_test mirror "${loop1}" "${loop2}"

(2) Write the common file to both drives.

printf '(2) : Write common to both\n'echo 'common'> /zpool_test/file_commonprint_statuszpool export zpool_test

(3) Only in drive one: Modify the common file & Add a new file one.

printf '(3) : Modify & Add only to one\n'losetup -d "${loop2}"zpool import zpool_testecho 'append one'>> /zpool_test/file_commonecho 'new one'> /zpool_test/file_new_1print_statuszpool export zpool_test

(4) Only in drive two: Modify the common file & Add a new file two.

printf '(4) : Modify & Add only to two\n'loop2=$(losetup -f --show "${tmpdir}/zfs2.img")losetup -d "${loop1}"zpool import zpool_testecho 'append two'>> /zpool_test/file_commonecho 'new two'> /zpool_test/file_new_2print_statuszpool export zpool_test

(5) Import both. Shows only the version and files in zfs1.img.

printf '(5) : import both one and two\n'loop1=$(losetup -f --show "${tmpdir}/zfs1.img")zpool import zpool_testprint_statuszpool export zpool_test

(6) Import only two. Check zfs2.img is overwritten silently without any logs.

printf '(6) : import only two\n'losetup -d "${loop1}"zpool import zpool_testprint_statuszpool export zpool_test

(7) If drive one is replaced with blank drive, blank drive is overwritten.

printf '(7) : if one is replaced with blank\n'truncate -s 100M "${tmpdir}/zfs_new_1.img"loop4=$(losetup --show /dev/loop4 "${tmpdir}/zfs_new_1.img")zpool import zpool_testzpool replace zpool_test /dev/loop1 /dev/loop4sleep 1print_statuszpool export zpool_test

Last but not least, handy clean up script is also provided:

zpool import zpool_testzpool destroy zpool_test# losetup -d "${loop1}" "${loop2}"losetup -d "${loop2}" "${loop4}"rm -rf "${tmpdir}"

Viewing all articles
Browse latest Browse all 29

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>