DF-2963 / trigger.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /* * 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; } |