Oh, and here's the source code, for the curious: #include <devid.h> #include <dirent.h> #include <errno.h> #include <libintl.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stddef.h>
#include <sys/vdev_impl.h> /* * Write a label block with a ZBT checksum. */ static void label_write(int fd, uint64_t offset, uint64_t size, void *buf) { zio_block_tail_t *zbt, zbt_orig; zio_cksum_t zc; zbt = (zio_block_tail_t *)((char *)buf + size) - 1; zbt_orig = *zbt; ZIO_SET_CHECKSUM(&zbt->zbt_cksum, offset, 0, 0, 0); zio_checksum(ZIO_CHECKSUM_LABEL, &zc, buf, size); VERIFY(pwrite64(fd, buf, size, offset) == size); *zbt = zbt_orig; } int main(int argc, char **argv) { int fd; vdev_label_t vl; nvlist_t *config; uberblock_t *ub = (uberblock_t *)vl.vl_uberblock; uint64_t txg; char *buf; size_t buflen; VERIFY(argc == 2); VERIFY((fd = open(argv[1], O_RDWR)) != -1); VERIFY(pread64(fd, &vl, sizeof (vdev_label_t), 0) == sizeof (vdev_label_t)); VERIFY(nvlist_unpack(vl.vl_vdev_phys.vp_nvlist, sizeof (vl.vl_vdev_phys.vp_nvlist), &config, 0) == 0); VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0); VERIFY(txg == 0); VERIFY(ub->ub_txg == 0); VERIFY(ub->ub_rootbp.blk_birth != 0); txg = ub->ub_rootbp.blk_birth; ub->ub_txg = txg; VERIFY(nvlist_remove_all(config, ZPOOL_CONFIG_POOL_TXG) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg) == 0); buf = vl.vl_vdev_phys.vp_nvlist; buflen = sizeof (vl.vl_vdev_phys.vp_nvlist); VERIFY(nvlist_pack(config, &buf, &buflen, NV_ENCODE_XDR, 0) == 0); label_write(fd, offsetof(vdev_label_t, vl_uberblock), 1ULL << UBERBLOCK_SHIFT, ub); label_write(fd, offsetof(vdev_label_t, vl_vdev_phys), VDEV_PHYS_SIZE, &vl.vl_vdev_phys); fsync(fd); return (0); } Jeff On Sun, May 04, 2008 at 01:21:27AM -0700, Jeff Bonwick wrote: > OK, here you go. I've successfully recovered a pool from a detached > device using the attached binary. You can verify its integrity > against the following MD5 hash: > > # md5sum labelfix > ab4f33d99fdb48d9d20ee62b49f11e20 labelfix > > It takes just one argument -- the disk to repair: > > # ./labelfix /dev/rdsk/c0d1s4 > > If all goes according to plan, your old pool should be importable. > If you do a zpool status -v, it will complain that the old mirrors > are no longer there. You can clean that up by detaching them: > > # zpool detach mypool <guid> > > where <guid> is the long integer that zpool status -v reports > as the name of the missing device. > > Good luck, and please let us know how it goes! > > Jeff > > On Sat, May 03, 2008 at 10:48:34PM -0700, Jeff Bonwick wrote: > > Oh, you're right! Well, that will simplify things! All we have to do > > is convince a few bits of code to ignore ub_txg == 0. I'll try a > > couple of things and get back to you in a few hours... > > > > Jeff > > > > On Fri, May 02, 2008 at 03:31:52AM -0700, Benjamin Brumaire wrote: > > > Hi, > > > > > > while diving deeply in zfs in order to recover data I found that every > > > uberblock in label0 does have the same ub_rootbp and a zeroed ub_txg. > > > Does it means only ub_txg was touch while detaching? > > > > > > Hoping it is the case, I modified ub_txg from one uberblock to match the > > > tgx from the label and now I try to calculate the new SHA256 checksum > > > but I failed. Can someone explain what I did wrong? And of course how to > > > do it correctly? > > > > > > bbr > > > > > > > > > The example is from a valid uberblock which belongs an other pool. > > > > > > Dumping the active uberblock in Label 0: > > > > > > # dd if=/dev/dsk/c0d1s4 bs=1 iseek=247808 count=1024 | od -x > > > 1024+0 records in > > > 1024+0 records out > > > 0000000 b10c 00ba 0000 0000 0009 0000 0000 0000 > > > 0000020 8bf2 0000 0000 0000 8eef f6db c46f 4dcc > > > 0000040 bba8 481a 0000 0000 0001 0000 0000 0000 > > > 0000060 05e6 0003 0000 0000 0001 0000 0000 0000 > > > 0000100 05e6 005b 0000 0000 0001 0000 0000 0000 > > > 0000120 44e9 00b2 0000 0000 0001 0000 0703 800b > > > 0000140 0000 0000 0000 0000 0000 0000 0000 0000 > > > 0000160 0000 0000 0000 0000 8bf2 0000 0000 0000 > > > 0000200 0018 0000 0000 0000 a981 2f65 0008 0000 > > > 0000220 e734 adf2 037a 0000 cedc d398 c063 0000 > > > 0000240 da03 8a6e 26fc 001c 0000 0000 0000 0000 > > > 0000260 0000 0000 0000 0000 0000 0000 0000 0000 > > > * > > > 0001720 0000 0000 0000 0000 7a11 b10c da7a 0210 > > > 0001740 3836 20fb e2a7 a737 a947 feed 43c5 c045 > > > 0001760 82a8 133d 0ba7 9ce7 e5d5 64e2 2474 3b03 > > > 0002000 > > > > > > Checksum is at pos 01740 01760 > > > > > > I try to calculate it assuming only uberblock is relevant. > > > #dd if=/dev/dsk/c0d1s4 bs=1 iseek=247808 count=168 | digest -a sha256 > > > 168+0 records in > > > 168+0 records out > > > 710306650facf818e824db5621be394f3b3fe934107bdfc861bbc82cb9e1bbf3 > > > > > > Helas not matching :-( > > > > > > > > > This message posted from opensolaris.org > > > _______________________________________________ > > > zfs-discuss mailing list > > > zfs-discuss@opensolaris.org > > > http://mail.opensolaris.org/mailman/listinfo/zfs-discuss > > _______________________________________________ > > zfs-discuss mailing list > > zfs-discuss@opensolaris.org > > http://mail.opensolaris.org/mailman/listinfo/zfs-discuss _______________________________________________ zfs-discuss mailing list zfs-discuss@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/zfs-discuss