devzero: when you have an exported pool with no log disk and you want to mount the pool. Here is the changes to make it compile on dev-129: --- logfix.c.2009-04-26 2009-12-18 11:39:40.917435361 -0800 +++ logfix.c 2009-12-18 12:19:27.507337246 -0800 @@ -20,6 +20,7 @@ #include <stddef.h> #include <sys/vdev_impl.h> +#include <sys/zio_checksum.h> /* * * Write a label block with a ZBT checksum. @@ -58,16 +59,19 @@ uint64_t guid; // ZPOOL_CONFIG_GUID uint64_t is_log; // ZPOOL_CONFIG_IS_LOG + uint64_t id; // ZPOOL_CONFIG_ID nvlist_t *vdev_tree; // ZPOOL_CONFIG_VDEV_TREE char *buf; size_t buflen; - VERIFY(argc == 4); + VERIFY(argc == 5); VERIFY((fd_pool = open(argv[1], O_RDWR)) != -1); VERIFY((fd_log = open(argv[2], O_RDWR)) != -1); VERIFY(sscanf(argv[3], "%" SCNu64 , &guid) == 1); //guid = 9851295902337437618ULL; + VERIFY(sscanf(argv[4], "%" SCNu64 , &id) == 1); + //id = 10; VERIFY(pread64(fd_pool, &vl_pool, sizeof (vdev_label_t), 0) = sizeof (vdev_label_t)); @@ -86,6 +90,10 @@ VERIFY(nvlist_remove_all(vdev_tree, ZPOOL_CONFIG_GUID) == 0); VERIFY(nvlist_add_uint64(vdev_tree, ZPOOL_CONFIG_GUID, guid) == 0); + // fix id for vdev_log + VERIFY(nvlist_remove_all(vdev_tree, ZPOOL_CONFIG_ID) == 0); + VERIFY(nvlist_add_uint64(vdev_tree, ZPOOL_CONFIG_ID, id) == 0); + // remove what we are going to replace on config_pool VERIFY(nvlist_remove_all(config_pool, ZPOOL_CONFIG_TOP_GUID) == 0); VERIFY(nvlist_remove_all(config_pool, ZPOOL_CONFIG_GUID) == 0); @@ -94,6 +102,7 @@ // add back what we want VERIFY(nvlist_add_uint64(config_pool, ZPOOL_CONFIG_TOP_GUID, guid) == 0); VERIFY(nvlist_add_uint64(config_pool, ZPOOL_CONFIG_GUID, guid) == 0); + VERIFY(nvlist_add_uint64(config_pool, ZPOOL_CONFIG_ID, id) == 0); VERIFY(nvlist_add_uint64(config_pool, ZPOOL_CONFIG_IS_LOG, is_log) == 0); VERIFY(nvlist_add_nvlist(config_pool, ZPOOL_CONFIG_VDEV_TREE, vdev_tree) == 0); This also fixes a bug (the ID must also be unique and the existing code didn''t work for me because I had 10 disks.) If another disk with the same "ID" is present, it will get masked (since this mark up has a newer date.) If pjjw doesn''t hose a new binary, I''ll put up a link for one. There is also a second bug (with current osol code) that prevents the mounting if the labels don''t match. Using a label created with the same size as pjjw''s suggested junk disk, you can use this command to copy those labels to the other 4 points: # cd /tmp # dd if=/dev/zero of=junk bs=1024k count=64 # dd if=/dev/zero of=junk.log bs=1024k count=64 # zpool create junkpool /tmp/junk log /tmp/junk.log # zpool export junkpool ** Fix it up! ** For file based log devices (this will be slow -- get the data off...): # ./logfix /dev/rdsk/disk_from_your_pool /tmp/junk.log your_old_log_disk_guid your_old_log_disk_id ** Copy labels # dd bs=256k count=1 if=/tmp/junk.log > /tmp/1 # (cat /tmp/1 /tmp/1 ; dd if=/tmp/junk.log bs=256k skip=2 count=252 ; cat /tmp/1 /tmp/1) > /tmp/my.log ** Make the log disk a device so it can be found if this is the first lofi, it will be /dev/{r}lofi/1 # lofiadm -a /tmp/my.log ** Since my pool came from FreeBSD and had different device names, I needed to make files matching. I created a directory with symbolic links to the solaris c5t?d? files as the FreeBSD names. So add this log device to that directory: # mkdir /tmp/fbsd; cd /tmp/fbsd # ln -s /dev/dsk/c5t1d0s4 ad4p5 ... # ln -s /dev/lofi/1 slog0 ** Import your pool ** # zpool import -d /tmp/fbsd/ -f tank -- This message posted from opensolaris.org