ping? -- WBR, Vadim Zhukov
---------- Forwarded message ---------- From: Vadim Zhukov <persg...@gmail.com> Date: 2015-10-01 21:59 GMT+03:00 Subject: Allow bioctl to go through all controllers at once To: tech@openbsd.org Hi all. I've recently found that this patch still produces M's in my tree. What it does is going through all bio(4)-enabled controllers in system, like ifconfig -A does. I didn't add SMALL_KERNEL ifdefs since its very useful on ramdisks, IMHO, but I don't insist on that. Any objections/okays/showers? -- WBR, Vadim Zhukov Index: sys/dev/bio.c =================================================================== RCS file: /cvs/src/sys/dev/bio.c,v retrieving revision 1.17 diff -u -p -r1.17 bio.c --- sys/dev/bio.c 26 Aug 2015 22:28:57 -0000 1.17 +++ sys/dev/bio.c 1 Oct 2015 18:53:18 -0000 @@ -52,6 +52,7 @@ int bioopen(dev_t, int, int, struct proc int bio_delegate_ioctl(struct bio_mapping *, u_long, caddr_t); struct bio_mapping *bio_lookup(char *); int bio_validate(void *); +int bio_listcontrollers(struct bioc_controllerlist *); void bioattach(int nunits) @@ -89,6 +90,9 @@ bioioctl(dev_t dev, u_long cmd, caddr_t return (ENOENT); break; + case BIOCLISTCONTROLLERS: + return (bio_listcontrollers((struct bioc_controllerlist*)addr)); + case BIOCINQ: case BIOCDISK: case BIOCVOL: @@ -138,6 +142,32 @@ bio_unregister(struct device *dev) free(bm, M_DEVBUF, sizeof(*bm)); } } +} + +int +bio_listcontrollers(struct bioc_controllerlist *bcl) { + struct bio_mapping *bm; + int error, i; + + if (bcl->bcl_size < 0) + return EINVAL; + if (bcl->bcl_size == 0) { + LIST_FOREACH(bm, &bios, bm_link) + bcl->bcl_size++; + return 0; + } + i = 0; + LIST_FOREACH(bm, &bios, bm_link) { + error = copyoutstr(bm->bm_dev->dv_xname, + bcl->bcl_list[i].bc_xname, + sizeof(bcl->bcl_list[i].bc_xname), NULL); + if (error) + return (error); + if (++i == bcl->bcl_size) + break; + } + bcl->bcl_size = i; + return 0; } struct bio_mapping * Index: sys/dev/biovar.h =================================================================== RCS file: /cvs/src/sys/dev/biovar.h,v retrieving revision 1.44 diff -u -p -r1.44 biovar.h --- sys/dev/biovar.h 29 May 2015 00:33:37 -0000 1.44 +++ sys/dev/biovar.h 1 Oct 2015 18:53:18 -0000 @@ -277,6 +277,15 @@ struct bioc_patrol { int bp_autonow; }; +#define BIOCLISTCONTROLLERS _IOWR('B', 43, struct bioc_controllerlist) +struct bioc_controller { + char bc_xname[16]; +}; +struct bioc_controllerlist { + struct bioc_controller *bcl_list; + int bcl_size; +}; + /* kernel and userspace defines */ #define BIOC_INQ 0x0001 #define BIOC_DISK 0x0002 Index: sbin/bioctl/bioctl.c =================================================================== RCS file: /cvs/src/sbin/bioctl/bioctl.c,v retrieving revision 1.129 diff -u -p -r1.129 bioctl.c --- sbin/bioctl/bioctl.c 18 Jul 2015 23:23:20 -0000 1.129 +++ sbin/bioctl/bioctl.c 1 Oct 2015 18:53:18 -0000 @@ -69,7 +69,8 @@ void bio_kdf_generate(struct sr_crypto void derive_key_pkcs(int, u_int8_t *, size_t, u_int8_t *, size_t, char *, int); -void bio_inq(char *); +void bio_listall(); +void bio_inq(char *, int); void bio_alarm(char *); int bio_getvolbyname(char *); void bio_setstate(char *, int, char *); @@ -110,12 +111,17 @@ main(int argc, char *argv[]) u_int16_t cr_level = 0; int biodev = 0; - if (argc < 2) - usage(); + if (argc < 2) { + bio_listall(); + return 0; + } - while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:O:Pp:qr:R:st:u:v")) != + while ((ch = getopt(argc, argv, "Aa:b:C:c:dH:hik:l:O:Pp:qr:R:st:u:v")) != -1) { switch (ch) { + case 'A': + bio_listall(); + return 0; case 'a': /* alarm */ func |= BIOC_ALARM; al_arg = optarg; @@ -243,7 +249,7 @@ main(int argc, char *argv[]) } else if (changepass && !biodev) { bio_changepass(devicename); } else if (func & BIOC_INQ) { - bio_inq(devicename); + bio_inq(devicename, 0); } else if (func == BIOC_ALARM) { bio_alarm(al_arg); } else if (func == BIOC_BLINK) { @@ -273,7 +279,7 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-hiqv] [-a alarm-function] " + "usage: %s [-Ahiqv] [-a alarm-function] " "[-b channel:target[.lun]]\n" "\t[-H channel:target[.lun]] " "[-R device | channel:target[.lun]]\n" @@ -355,6 +361,43 @@ str2patrol(const char *string, struct ti } void +bio_listall(void) +{ + struct bio_locate bl; + struct bioc_controllerlist cl; + int rv; + + memset(&cl, 0, sizeof(cl)); + memset(&bl, 0, sizeof(bl)); + + devh = open("/dev/bio", O_RDONLY); + if (devh == -1) + err(1, "Can't open %s", "/dev/bio"); + + rv = ioctl(devh, BIOCLISTCONTROLLERS, &cl); + if (rv == -1) + err(1, "1 BIOCLISTCONTROLLERS"); + if (cl.bcl_size == 0) + return; + + cl.bcl_list = calloc(cl.bcl_size, sizeof(struct bioc_controller)); + if (cl.bcl_list == NULL) + err(1, "calloc"); + rv = ioctl(devh, BIOCLISTCONTROLLERS, &cl); + if (rv == -1) + err(1, "2 BIOCLISTCONTROLLERS"); + while (cl.bcl_size--) { + bl.bl_name = cl.bcl_list[cl.bcl_size].bc_xname; + if (ioctl(devh, BIOCLOCATE, &bl)) + errx(1, "Can't locate %s device via %s", + bl.bl_name, "/dev/bio"); + bio_cookie = bl.bl_bio.bio_cookie; + bio_inq(NULL, 1); + } + free(cl.bcl_list); +} + +void bio_status(struct bio_status *bs) { extern char *__progname; @@ -378,7 +421,7 @@ bio_status(struct bio_status *bs) } void -bio_inq(char *name) +bio_inq(char *name, int ignorenotsupp) { char *status, *cache; char size[64], scsiname[16], volname[32]; @@ -394,9 +437,10 @@ bio_inq(char *name) bi.bi_bio.bio_cookie = bio_cookie; if (ioctl(devh, BIOCINQ, &bi)) { - if (errno == ENOTTY) - bio_diskinq(name); - else + if (errno == ENOTTY) { + if (!ignorenotsupp) + bio_diskinq(name); + } else err(1, "BIOCINQ"); return; }