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;
}