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

Reply via email to