On Sun 2011.02.20 at 10:30 -0500, Okan Demirmen wrote:
On Sun 2011.02.20 at 13:28 +0100, Mark Kettenis wrote:
Date: Sun, 20 Feb 2011 07:03:25 -0500
From: Kenneth R Westerback<kwesterb...@rogers.com>
On Sun, Feb 20, 2011 at 12:39:06PM +0100, Mark Kettenis wrote:
Date: Sun, 20 Feb 2011 19:54:21 +1000
From: David Gwynne<l...@animata.net>
how to manipulate write cache policy?
the lsi firmwares dont implement handling of the mod page changes
unfortunately. you could call the ioctl this implements yourself
though from userland.
David, while I think that implementing the cache manipulation ioctls
for mpii(4) is a good idea, there is a problem here. We don't have a
tool in base that actually issues those ioctls. And unless I'm
misreading the diff, this still leaves the cache disabled on the
stupid Dell.
DIOCSCACHE is called in sdattach() to enable write cache for all
disks that DIOCGCACHE reports as having write cache disabled. Or are
you concerned that we have no way to manipulate it from userland
if/when the default needs to be modified?
Ah, that's the bit I was missing. A userland tool to display and
manipulate the cache settings would still be good though.
Functionality should probably be added to bioctl(8). A bit
unfortunate that both the -c and -C options are already taken.
Ah, I had a diff for bioctl (enable/disable WCE/RCD) based on dlg's
sample, but I think marco wanted more of a policy of when to do WCE/RCD
rather than a switch - I'll send it along when I get home later this
week.
I'm not certain this is wanted, but I said I would forward along this
very simplisitc patch, so here it is. If something like this is wanted,
it can be re-worked to take multiple args to -e and such, but again,
only if this is deemed necessary in a userland tool outside of scsi(8).
Index: bioctl.8
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.8,v
retrieving revision 1.84
diff -u -p -r1.84 bioctl.8
--- bioctl.8 22 Dec 2010 16:25:32 -0000 1.84
+++ bioctl.8 2 Mar 2011 10:44:23 -0000
@@ -35,6 +35,7 @@
.Op Fl hiqv
.Op Fl a Ar alarm-function
.Op Fl b Ar channel:target[.lun]
+.Op Fl e Ar flag
.Op Fl H Ar channel:target[.lun]
.Op Fl R Ar device \*(Ba channel:target[.lun]
.Op Fl u Ar channel:target[.lun]
@@ -128,6 +129,24 @@ digits to four or less.
.It Fl i
Enumerate the selected RAID devices.
This is the default if no other option is given.
+.It Fl e Ar flag
+Pass
+.Ar flag
+to
+.Nm .
+May be one of:
+.Bl -tag -width disable -compact
+.It Ar q
+Query the read/write cache status.
+.It Ar R
+Enable the read cache.
+.It Ar r
+Disable the read cache.
+.It Ar W
+Enable the write cache.
+.It Ar w
+Disable the write cache.
+.El
.It Fl q
Show vendor, product, revision, and serial number for the given disk.
.It Fl R Ar device \*(Ba channel:target[.lun]
Index: bioctl.c
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.c,v
retrieving revision 1.98
diff -u -p -r1.98 bioctl.c
--- bioctl.c 1 Dec 2010 19:40:18 -0000 1.98
+++ bioctl.c 2 Mar 2011 10:44:23 -0000
@@ -77,6 +77,7 @@ void bio_changepass(char *);
u_int32_t bio_createflags(char *);
char *bio_vis(char *);
void bio_diskinq(char *);
+void bio_cache(char *, char *);
int devh = -1;
int human;
@@ -97,17 +98,17 @@ main(int argc, char *argv[])
char *devicename = NULL;
char *realname = NULL, *al_arg = NULL;
char *bl_arg = NULL, *dev_list = NULL;
- char *key_disk = NULL;
+ char *key_disk = NULL, *ca_arg = NULL;
const char *errstr;
int ch, rv, blink = 0, changepass = 0, diskinq = 0;
- int ss_func = 0;
+ int ss_func = 0, diskcache = 0;
u_int16_t cr_level = 0;
int biodev = 0;
if (argc< 2)
usage();
- while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:Pp:qr:R:svu:")) !=
+ while ((ch = getopt(argc, argv, "a:b:C:c:de:H:hik:l:Pp:qr:R:svu:")) !=
-1) {
switch (ch) {
case 'a': /* alarm */
@@ -133,6 +134,10 @@ main(int argc, char *argv[])
/* delete volume */
func |= BIOC_DELETERAID;
break;
+ case 'e': /* cache */
+ diskcache = 1;
+ ca_arg = optarg;
+ break;
case 'u': /* unblink */
func |= BIOC_BLINK;
blink = BIOC_SBUNBLINK;
@@ -219,6 +224,8 @@ main(int argc, char *argv[])
if (diskinq) {
bio_diskinq(devicename);
+ } else if (diskcache) {
+ bio_cache(devicename, ca_arg);
} else if (changepass&& !biodev) {
bio_changepass(devicename);
} else if (func& BIOC_INQ) {
@@ -252,7 +259,8 @@ usage(void)
fprintf(stderr,
"usage: %s [-hiqv] [-a alarm-function] "
"[-b channel:target[.lun]]\n"
- "\t[-H channel:target[.lun]] "
+ "\t[-e flag] "
+ "[-H channel:target[.lun]] "
"[-R device | channel:target[.lun]\n"
"\t[-u channel:target[.lun]] "
"device\n"
@@ -1104,4 +1112,43 @@ derive_key_pkcs(int rounds, u_int8_t *ke
memset(passphrase, 0, sizeof(passphrase));
return;
+}
+
+void
+bio_cache(char *sd_dev, char *arg)
+{
+ int set = 1;
+ struct dk_cache dkc;
+
+ if (ioctl(devh, DIOCGCACHE,&dkc) == -1)
+ err(1, "DIOCGCACHE");
+
+ switch (arg[0]) {
+ case 'q': /* query cache */
+ set = 0;
+ break;
+ case 'r': /* disable read cache */
+ dkc.rdcache = 0;
+ break;
+ case 'R': /* enable read cache */
+ dkc.rdcache = 1;
+ break;
+ case 'w': /* disable write cache */
+ dkc.wrcache = 0;
+ break;
+ case 'W': /* enable write cache */
+ dkc.wrcache = 1;
+ break;
+ default:
+ errx(1, "invalid cache option: %s", arg);
+ }
+
+ if (set) {
+ if (ioctl(devh, DIOCSCACHE,&dkc) == -1)
+ err(1, "ioctl DIOCSCACHE");
+ }
+
+ printf("%s: write cache: %s, read cache: %s\n", sd_dev,
+ dkc.wrcache ? "enabled" : "disabled",
+ dkc.rdcache ? "enabled" : "disabled");
}