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

Reply via email to