DragonFlyBSD Kernel Audit
DF-2963 / trigger.c
← back to finding ↓ download raw
/*
 * DF-2963 trigger: demonstrate /dev/vn0s127 == /dev/vn0s0 identity.
 *
 * 1. stat() each slice node: st_rdev(vn0s127) must equal st_rdev(vn0s0)
 *    (dkmakeminor drops slice bit 7), while st_ino differs (two devfs nodes).
 * 2. read first sector via vn0s127: must return ENTRY0ZONE (slice 0's data),
 *    not ENTRY127ZONE (the data the name promises).
 * 3. DIOCGPART on vn0s127 reports slice 0's extent.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/diskslice.h>

static void
show_rdev(const char *path)
{
	struct stat st;
	if (stat(path, &st) < 0) {
		printf("%-16s : stat failed: %s\n", path, strerror(errno));
		return;
	}
	printf("%-16s : st_ino=%10llu st_rdev=0x%08llx\n",
	       path,
	       (unsigned long long)st.st_ino,
	       (unsigned long long)st.st_rdev);
}

static void
show_data(const char *path)
{
	char buf[512];
	int fd = open(path, O_RDONLY);
	if (fd < 0) {
		printf("%-16s : open failed: %s\n", path, strerror(errno));
		return;
	}
	memset(buf, 0, sizeof(buf));
	if (read(fd, buf, sizeof(buf)) < 0) {
		printf("%-16s : read failed: %s\n", path, strerror(errno));
	} else {
		char tag[33];
		memcpy(tag, buf, 32);
		tag[32] = 0;
		printf("%-16s : first-sector tag = \"%s\"\n", path, tag);
	}
	close(fd);
}

static void
show_part(const char *path)
{
	struct partinfo pi;
	int fd = open(path, O_RDONLY);
	if (fd < 0) {
		printf("%-16s : open failed: %s\n", path, strerror(errno));
		return;
	}
	memset(&pi, 0, sizeof(pi));
	if (ioctl(fd, DIOCGPART, &pi) < 0) {
		printf("%-16s : DIOCGPART failed: %s\n", path, strerror(errno));
	} else {
		printf("%-16s : media_offset=%llu media_blocks=%llu\n",
		       path,
		       (unsigned long long)pi.media_offset,
		       (unsigned long long)pi.media_blocks);
	}
	close(fd);
}

int
main(int argc, char **argv)
{
	const char *base = argc > 1 ? argv[1] : "/dev/vn0";
	char p0[64], p126[64], p127[64];
	uint64_t lbas[3] = { 34, 160, 1000 };
	int fd, i;
	char buf[512];

	snprintf(p0,   sizeof(p0),   "%ss0",   base);
	snprintf(p126, sizeof(p126), "%ss126", base);
	snprintf(p127, sizeof(p127), "%ss127", base);

	printf("== st_rdev comparison (duplicate dev_t) ==\n");
	show_rdev(p0);
	show_rdev(p126);
	show_rdev(p127);

	printf("\n== data read through each slice node ==\n");
	show_data(p0);
	show_data(p126);
	show_data(p127);

	printf("\n== DIOCGPART extent reported per node ==\n");
	show_part(p0);
	show_part(p126);
	show_part(p127);

	printf("\n== raw control reads (via %s) ==\n", base);
	fd = open(base, O_RDONLY);
	if (fd >= 0) {
		for (i = 0; i < 3; i++) {
			if (pread(fd, buf, 512, (off_t)lbas[i] * 512) == 512) {
				char tag[33];
				memcpy(tag, buf, 32);
				tag[32] = 0;
				printf("raw LBA %-5llu : \"%s\"\n",
				       (unsigned long long)lbas[i], tag);
			}
		}
		close(fd);
	} else {
		printf("open %s failed: %s\n", base, strerror(errno));
	}
	return 0;
}