Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
Am 12.07.2013 14:33, schrieb Volodymyr Kostyrko: You can try to experiment with zpool hidden flags. Look at this command: zpool import -N -o readonly=on -f -R /pool pool It will try to import pool in readonly mode so no data would be written on it. It also doesn't mount anything on import so if any fs is damaged you have less chances triggering a coredump. Also zpool import has a hidden -T switch that gives you ability to select transaction that you want to try to restore. You'll need a list of available transaction though: zdb -ul vdev This one when given a vdev lists all uberblocks with their respective transaction ids. You can take the highest one (it's not the last one) and try to mount pool with: zpool import -N -o readonly=on -f -R /pool -F -T transaction_id pool I had good luck with ZFS recovery with the following approach: 1) Use zdb to identify a TXG for which the data structures are intact 2) Select recovery mode by loading the ZFS KLD with vfs.zfs.recover=1 set in /boot/loader.conf 3) Import the pool with the above -T option referring to a suitable TXG found with the help zdb. The zdb commands to use are: # zdb -AAA -L -t TXG -bcdmu POOL (Both -AAA and -L reduce the amount of consistency checking performed. A pool (at TXG) that needs these options to allow zdb to succeed is damaged, but may still allow recovery of most or all files. Be sure to only import that pool R/O, or your data will probably be lost!) A list of TXGs to try can be retrieved with zdb -hh POOL. You may need to add -e to the list of zdb options, since the port is exported / not currently mounted). Regards, STefan ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org
Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
11.07.2013 17:43, Reid Linnemann написав(ла): So recently I was trying to transfer a root-on-ZFS zpool from one pair of disks to a single, larger disk. As I am wont to do, I botched the transfer up and decided to destroy the ZFS filesystems on the destination and start again. Naturally I was up late working on this, being sloppy and drowsy without any coffee, and lo and behold I issued my 'zfs destroy -R' and immediately realized after pressing [ENTER[ that I had given it the source's zpool name. oops. Fortunately I was able to interrupt the procedure with only /usr being destroyed from the pool and I was able to send/receive the truly vital data in my /var partition to the new disk and re-deploy the base system to /usr on the new disk. The only thing I'm really missing at this point is all of the third-party software configuration I had in /usr/local/etc and my apache data in /usr/local/www. You can try to experiment with zpool hidden flags. Look at this command: zpool import -N -o readonly=on -f -R /pool pool It will try to import pool in readonly mode so no data would be written on it. It also doesn't mount anything on import so if any fs is damaged you have less chances triggering a coredump. Also zpool import has a hidden -T switch that gives you ability to select transaction that you want to try to restore. You'll need a list of available transaction though: zdb -ul vdev This one when given a vdev lists all uberblocks with their respective transaction ids. You can take the highest one (it's not the last one) and try to mount pool with: zpool import -N -o readonly=on -f -R /pool -F -T transaction_id pool Then check available filesystems. -- Sphinx of black quartz, judge my vow. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org
Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
Hey presto! / zfs list NAME USED AVAIL REFER MOUNTPOINT bucket 485G 1.30T 549M legacy bucket/tmp21K 1.30T21K legacy bucket/usr 29.6G 1.30T 29.6G /mnt/usr bucket/var 455G 1.30T 17.7G /mnt/var bucket/var/srv 437G 1.30T 437G /mnt/var/srv There's my old bucket! Thanks much for the hidden -T argument, Volodymyr! Now I can get back the remainder of my missing configuration. On Fri, Jul 12, 2013 at 7:33 AM, Volodymyr Kostyrko c.kw...@gmail.comwrote: 11.07.2013 17:43, Reid Linnemann написав(ла): So recently I was trying to transfer a root-on-ZFS zpool from one pair of disks to a single, larger disk. As I am wont to do, I botched the transfer up and decided to destroy the ZFS filesystems on the destination and start again. Naturally I was up late working on this, being sloppy and drowsy without any coffee, and lo and behold I issued my 'zfs destroy -R' and immediately realized after pressing [ENTER[ that I had given it the source's zpool name. oops. Fortunately I was able to interrupt the procedure with only /usr being destroyed from the pool and I was able to send/receive the truly vital data in my /var partition to the new disk and re-deploy the base system to /usr on the new disk. The only thing I'm really missing at this point is all of the third-party software configuration I had in /usr/local/etc and my apache data in /usr/local/www. You can try to experiment with zpool hidden flags. Look at this command: zpool import -N -o readonly=on -f -R /pool pool It will try to import pool in readonly mode so no data would be written on it. It also doesn't mount anything on import so if any fs is damaged you have less chances triggering a coredump. Also zpool import has a hidden -T switch that gives you ability to select transaction that you want to try to restore. You'll need a list of available transaction though: zdb -ul vdev This one when given a vdev lists all uberblocks with their respective transaction ids. You can take the highest one (it's not the last one) and try to mount pool with: zpool import -N -o readonly=on -f -R /pool -F -T transaction_id pool Then check available filesystems. -- Sphinx of black quartz, judge my vow. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org
Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
zpool export does not wipe the transaction history. It does, however, write new labels and some metadata, so there is a very slight chance that it might overwrite some of the blocks that you're trying to recover. But it's probably safe. An alternative, much more complicated, solution would be to have ZFS open the device non-exclusively. This patch will do that. Caveat programmer: I haven't tested this patch in isolation. Change 624068 by willa@willa_SpectraBSD on 2012/08/09 09:28:38 Allow multiple opens of geoms used by vdev_geom. Also ignore the pool guid for spares when checking to decide whether it's ok to attach a vdev. This enables using hotspares to replace other devices, as well as using a given hotspare in multiple pools. We need to investigate alternative solutions in order to allow opening the geoms exclusive. Affected files ... ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c#2 edit Differences ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c#2 (text) @@ -179,49 +179,23 @@ gp = g_new_geomf(zfs_vdev_class, zfs::vdev); gp-orphan = vdev_geom_orphan; gp-attrchanged = vdev_geom_attrchanged; - cp = g_new_consumer(gp); - error = g_attach(cp, pp); - if (error != 0) { - printf(%s(%d): g_attach failed: %d\n, __func__, - __LINE__, error); - g_wither_geom(gp, ENXIO); - return (NULL); - } - error = g_access(cp, 1, 0, 1); - if (error != 0) { - printf(%s(%d): g_access failed: %d\n, __func__, - __LINE__, error); - g_wither_geom(gp, ENXIO); - return (NULL); - } - ZFS_LOG(1, Created geom and consumer for %s., pp-name); - } else { - /* Check if we are already connected to this provider. */ - LIST_FOREACH(cp, gp-consumer, consumer) { - if (cp-provider == pp) { - ZFS_LOG(1, Provider %s already in use by ZFS. - Failing attach., pp-name); - return (NULL); - } - } - cp = g_new_consumer(gp); - error = g_attach(cp, pp); - if (error != 0) { - printf(%s(%d): g_attach failed: %d\n, - __func__, __LINE__, error); - g_destroy_consumer(cp); - return (NULL); - } - error = g_access(cp, 1, 0, 1); - if (error != 0) { - printf(%s(%d): g_access failed: %d\n, - __func__, __LINE__, error); - g_detach(cp); - g_destroy_consumer(cp); - return (NULL); - } - ZFS_LOG(1, Created consumer for %s., pp-name); + } + cp = g_new_consumer(gp); + error = g_attach(cp, pp); + if (error != 0) { + printf(%s(%d): g_attach failed: %d\n, __func__, + __LINE__, error); + g_wither_geom(gp, ENXIO); + return (NULL); + } + error = g_access(cp, /*r*/1, /*w*/0, /*e*/0); + if (error != 0) { + printf(%s(%d): g_access failed: %d\n, __func__, + __LINE__, error); + g_wither_geom(gp, ENXIO); + return (NULL); } + ZFS_LOG(1, Created consumer for %s., pp-name); cp-private = vd; vd-vdev_tsd = cp; @@ -251,7 +225,7 @@ cp-private = NULL; gp = cp-geom; - g_access(cp, -1, 0, -1); + g_access(cp, -1, 0, 0); /* Destroy consumer on last close. */ if (cp-acr == 0 cp-ace == 0) { ZFS_LOG(1, Destroyed consumer to %s., cp-provider-name); @@ -384,6 +358,18 @@ cp-provider-name); } +static inline boolean_t +vdev_attach_ok(vdev_t *vd, uint64_t pool_guid, uint64_t vdev_guid) +{ + boolean_t pool_ok; + boolean_t vdev_ok; + + /* Spares can be assigned to multiple pools. */ + pool_ok = vd-vdev_isspare || pool_guid == spa_guid(vd-vdev_spa); + vdev_ok = vdev_guid == vd-vdev_guid; + return (pool_ok vdev_ok); +} + static struct g_consumer * vdev_geom_attach_by_guids(vdev_t *vd) { @@ -420,8 +406,7 @@ g_topology_lock(); g_access(zcp, -1, 0, 0); g_detach(zcp); - if (pguid != spa_guid(vd-vdev_spa) || - vguid != vd-vdev_guid) +
Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
On Thu, Jul 11, 2013 at 9:04 AM, Alan Somers asom...@freebsd.org wrote: zpool export does not wipe the transaction history. It does, however, write new labels and some metadata, so there is a very slight chance that it might overwrite some of the blocks that you're trying to recover. But it's probably safe. An alternative, much more complicated, solution would be to have ZFS open the device non-exclusively. This patch will do that. Caveat programmer: I haven't tested this patch in isolation. This change is quite a bit more than necessary, and probably wouldn't apply to FreeBSD given the other changes in the code. Really, to make non-exclusive opens you just have to change the g_access() calls in vdev_geom.c so the third argument is always 0. However, see below. On Thu, Jul 11, 2013 at 8:43 AM, Reid Linnemann linnema...@gmail.com wrote: But now we are to my current problem. When attempting to roll back with this script, it tries to dd zero'd bytes to offsets into the disk device (/dev/ada1p3 in my case) where the uberblocks are located. But even with kern.geom.debugflags set to 0x10 (and I am runnign this as root) I get 'Operation not permitted' when the script tries to zero out the unwanted transactions. I'm fairly certain this is because the geom is in use by the ZFS subsystem, as it is still recognized as a part of the original pool. I'm hesitant to zfs export the pool, as I don't know if that wipes the transaction history on the pool. Does anyone have any ideas? You do not have a choice. Changing the on-disk state does not mean the in-core state will update to match, and the pool could get into a really bad state if you try to modify the transactions on disk while it's online, since it may write additional transactions (which rely on state you're about to destroy), before you export. Also, rolling back transactions in this manner assumes that the original blocks (that were COW'd) are still in their original state. If you're using TRIM or have a pretty full pool, the odds are not in your favor. It's a roll of the dice, in any case. --Will. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org
Re: Attempting to roll back zfs transactions on a disk to recover a destroyed ZFS filesystem
Will, Thanks, that makes sense. I know this is all a crap shoot, but I've really got nothing to lose at this point, so this is just a good opportunity to rummage around the internals of ZFS and learn a few things. I might even get lucky and recover some data! On Thu, Jul 11, 2013 at 10:59 AM, Will Andrews w...@firepipe.net wrote: On Thu, Jul 11, 2013 at 9:04 AM, Alan Somers asom...@freebsd.org wrote: zpool export does not wipe the transaction history. It does, however, write new labels and some metadata, so there is a very slight chance that it might overwrite some of the blocks that you're trying to recover. But it's probably safe. An alternative, much more complicated, solution would be to have ZFS open the device non-exclusively. This patch will do that. Caveat programmer: I haven't tested this patch in isolation. This change is quite a bit more than necessary, and probably wouldn't apply to FreeBSD given the other changes in the code. Really, to make non-exclusive opens you just have to change the g_access() calls in vdev_geom.c so the third argument is always 0. However, see below. On Thu, Jul 11, 2013 at 8:43 AM, Reid Linnemann linnema...@gmail.com wrote: But now we are to my current problem. When attempting to roll back with this script, it tries to dd zero'd bytes to offsets into the disk device (/dev/ada1p3 in my case) where the uberblocks are located. But even with kern.geom.debugflags set to 0x10 (and I am runnign this as root) I get 'Operation not permitted' when the script tries to zero out the unwanted transactions. I'm fairly certain this is because the geom is in use by the ZFS subsystem, as it is still recognized as a part of the original pool. I'm hesitant to zfs export the pool, as I don't know if that wipes the transaction history on the pool. Does anyone have any ideas? You do not have a choice. Changing the on-disk state does not mean the in-core state will update to match, and the pool could get into a really bad state if you try to modify the transactions on disk while it's online, since it may write additional transactions (which rely on state you're about to destroy), before you export. Also, rolling back transactions in this manner assumes that the original blocks (that were COW'd) are still in their original state. If you're using TRIM or have a pretty full pool, the odds are not in your favor. It's a roll of the dice, in any case. --Will. ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org