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