| 730 | } |
| 731 | |
| 732 | static bool reopen_store(struct gossmap *map, u64 ended_off) |
| 733 | { |
| 734 | u64 equivalent_off; |
| 735 | u8 verbyte; |
| 736 | u8 expected_uuid[32], uuid[32]; |
| 737 | struct gossip_hdr ghdr; |
| 738 | bool changed; |
| 739 | |
| 740 | /* This tells us the equivalent offset in new map */ |
| 741 | equivalent_off = map_be64(map, ended_off + 2); |
| 742 | map_copy(map, ended_off + 2 + 8, expected_uuid, sizeof(expected_uuid)); |
| 743 | close(map->fd); |
| 744 | |
| 745 | map->fd = open(map->fname, O_RDONLY); |
| 746 | if (map->fd < 0) |
| 747 | err(1, "Failed to reopen %s", map->fname); |
| 748 | |
| 749 | /* If mmap isn't disabled, we try to mmap if we can. */ |
| 750 | map->map_size = lseek(map->fd, 0, SEEK_END); |
| 751 | if (map->mmap) { |
| 752 | map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0); |
| 753 | if (map->mmap == MAP_FAILED) |
| 754 | map->mmap = NULL; |
| 755 | } |
| 756 | |
| 757 | if (map->map_size < 1 + sizeof(ghdr) + 2 + sizeof(uuid)) |
| 758 | errx(1, "Truncated gossip_store len %"PRIu64, map->map_size); |
| 759 | |
| 760 | /* version then ghdr then uuid. */ |
| 761 | verbyte = map_u8(map, 0); |
| 762 | if (GOSSIP_STORE_MAJOR_VERSION(verbyte) != 0 || GOSSIP_STORE_MINOR_VERSION(verbyte) < 16) |
| 763 | errx(1, "Bad gossip_store version %u", verbyte); |
| 764 | |
| 765 | if (map_be16(map, 1 + sizeof(struct gossip_hdr)) != WIRE_GOSSIP_STORE_UUID) |
| 766 | errx(1, "First gossip_store record is not uuid?"); |
| 767 | map_copy(map, 1 + sizeof(struct gossip_hdr) + 2, uuid, sizeof(uuid)); |
| 768 | |
| 769 | /* FIXME: we can skip if uuid is as expected, but we'd have to re-calc all |
| 770 | * our offsets anyway. It's not worth it, given how fast we are. */ |
| 771 | if (memcmp(uuid, expected_uuid, sizeof(uuid)) == 0) { |
| 772 | map->logcb(map->cbarg, LOG_DBG, |
| 773 | "Reopened gossip_store, reduced to offset %"PRIu64, |
| 774 | equivalent_off); |
| 775 | } else { |
| 776 | /* Start from scratch */ |
| 777 | map->logcb(map->cbarg, LOG_INFORM, |
| 778 | "Reopened gossip_store, but we missed some (%s vs %s)", |
| 779 | tal_hexstr(tmpctx, uuid, sizeof(uuid)), |
| 780 | tal_hexstr(tmpctx, expected_uuid, sizeof(expected_uuid))); |
| 781 | } |
| 782 | |
| 783 | tal_free(map->channels); |
| 784 | tal_free(map->nodes); |
| 785 | tal_free(map->chan_arr); |
| 786 | tal_free(map->node_arr); |
| 787 | init_map_structs(map); |
| 788 | map->map_end = 1; |
| 789 | map->generation++; |
no test coverage detected