uint16_t label_lookup_write( label_table_t * from, label_table_t * to, char * label, uint16_t address ) { uint16_t found_address; if ((found_address = label_lookup(from, label))) return found_address; label_write(to, label, address); return 0; }
int main(int argc, char **argv) { int fd_pool; int fd_log; vdev_label_t vl_pool; vdev_label_t vl_log; nvlist_t *config_pool; nvlist_t *config_log; uint64_t guid; // ZPOOL_CONFIG_GUID uint64_t is_log; // ZPOOL_CONFIG_IS_LOG nvlist_t *vdev_tree; // ZPOOL_CONFIG_VDEV_TREE char *buf; size_t buflen; VERIFY(argc == 4); 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(pread64(fd_pool, &vl_pool, sizeof (vdev_label_t), 0) == sizeof (vdev_label_t)); VERIFY(nvlist_unpack(vl_pool.vl_vdev_phys.vp_nvlist, sizeof (vl_pool.vl_vdev_phys.vp_nvlist), &config_pool, 0) == 0); VERIFY(pread64(fd_log, &vl_log, sizeof (vdev_label_t), 0) == sizeof (vdev_label_t)); VERIFY(nvlist_unpack(vl_log.vl_vdev_phys.vp_nvlist, sizeof (vl_log.vl_vdev_phys.vp_nvlist), &config_log, 0) == 0); // save what we want from config_log -- is_log, vdev_tree VERIFY(nvlist_lookup_uint64(config_log, ZPOOL_CONFIG_IS_LOG, &is_log) == 0); VERIFY(nvlist_lookup_nvlist(config_log, ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) == 0); // fix guid for vdev_log VERIFY(nvlist_remove_all(vdev_tree, ZPOOL_CONFIG_GUID) == 0); VERIFY(nvlist_add_uint64(vdev_tree, ZPOOL_CONFIG_GUID, guid) == 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); VERIFY(nvlist_remove_all(config_pool, ZPOOL_CONFIG_VDEV_TREE) == 0); // 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_IS_LOG, is_log) == 0); VERIFY(nvlist_add_nvlist(config_pool, ZPOOL_CONFIG_VDEV_TREE, vdev_tree) == 0); buf = vl_pool.vl_vdev_phys.vp_nvlist; buflen = sizeof (vl_pool.vl_vdev_phys.vp_nvlist); VERIFY(nvlist_pack(config_pool, &buf, &buflen, NV_ENCODE_XDR, 0) == 0); label_write(fd_log, offsetof(vdev_label_t, vl_vdev_phys), VDEV_PHYS_SIZE, &vl_pool.vl_vdev_phys); fsync(fd_log); return (0); }