DF-4594 / stick.c
/* * DF-4594 trigger: issue a bare VINUM_CREATE ioctl carrying a * "read <dev>" config line WITHOUT the VINUM_STARTCONFIG / * VINUM_RELEASECONFIG wrapper the vinum(8) CLI normally uses. * * vinum_scandisk() (sys/dev/raid/vinum/vinumio.c:747-753) returns ENOENT * early when no vinum drives are found, leaving: * - vinum_conf.flags |= VF_READING_CONFIG set forever (cleared only by * finish_config(), which the CLI normally calls), and * - the drivelist[] allocation leaked. * * With VF_READING_CONFIG stuck, the daemon refuses every later * daemon_save_config() (sys/dev/raid/vinum/vinumdaemon.c:126), so * subsequent configuration changes are never persisted. * * Usage: ./stick /dev/vn1 (any device with no vinum label) */ #include <sys/ioctl.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> /* replicated from sys/dev/raid/vinum/vinumio.h (kernel-private header) */ #include <sys/ioccom.h> #define VINUM_L 'F' struct vinum_ioctl_reply { int error; char msg[1024 - sizeof(int)]; }; #define VINUM_CREATE _IOC(IOC_IN | IOC_OUT, VINUM_L, 64, 1024) int main(int argc, char **argv) { char buf[1024]; struct vinum_ioctl_reply *reply = (struct vinum_ioctl_reply *)buf; int fd; if (argc != 2) { fprintf(stderr, "usage: %s <non-vinum-device>\n", argv[0]); return 2; } fd = open("/dev/vinum/control", O_RDWR); if (fd < 0) { perror("open /dev/vinum/Control (need root, vinum kldloaded)"); return 1; } snprintf(buf, sizeof(buf), "read %s", argv[1]); if (ioctl(fd, VINUM_CREATE, buf) < 0) { perror("ioctl(VINUM_CREATE)"); close(fd); return 1; } if (reply->error) printf("kernel replied: error=%d msg=%s\n", reply->error, reply->msg); else printf("VINUM_CREATE accepted (scandisk ran; VF_READING_CONFIG now stuck, drivelist leaked)\n"); close(fd); return 0; } |