DF-4801 / prime.c
/* DF-4801 helper: send ONE VINUM_SETSTATE(object_up, blocksize) ioctl. * * `vinum setstate -f up sd` (userland) loops the ioctl until the revive * finishes; we need exactly ONE revive_block call to prime the sd into * sd_reviving with the cursor at byte 64k, then stop driving it. * * Build: cc -O -o /tmp/prime /tmp/prime.c * Run: /tmp/prime <sdno> -> expect reply error=35 (EAGAIN), sd reviving */ #include <sys/ioccom.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #define L 'F' #define MAX_IOCTL_REPLY 256 struct vimsg { int index; int type; /* 1 = sd_object */ int state; /* 3 = object_up */ int op; int force; int recurse; int verify; int otherobject; int rename; long long offset; int blocksize; }; struct virep { int error; char msg[MAX_IOCTL_REPLY - sizeof(int)]; }; #define VINUM_SETSTATE_DF _IOC(IOC_IN | IOC_OUT, L, 76, MAX_IOCTL_REPLY) int main(int argc, char **argv) { struct vimsg msg; struct virep *rep = (struct virep *)&msg; int fd; if (argc < 2) { fprintf(stderr, "usage: %s sdno\n", argv[0]); return 2; } fd = open("/dev/vinum/controld", O_RDWR); if (fd < 0) { perror("controld"); return 1; } memset(&msg, 0, sizeof(msg)); msg.index = atoi(argv[1]); msg.type = 1; /* sd_object */ msg.state = 3; /* object_up -> start_object -> revive_block */ msg.force = 1; msg.blocksize = 65536; /* one 64k block: cursor lands at byte 64k */ ioctl(fd, VINUM_SETSTATE_DF, &msg); printf("prime: error=%d msg=%s\n", rep->error, rep->msg); return 0; } |