From owner-svn-src-all@FreeBSD.ORG Mon Sep 19 16:25:37 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AAD6C106566B; Mon, 19 Sep 2011 16:25:37 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 550B08FC12; Mon, 19 Sep 2011 16:25:37 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8JGPb44087496; Mon, 19 Sep 2011 16:25:37 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8JGPbRD087493; Mon, 19 Sep 2011 16:25:37 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201109191625.p8JGPbRD087493@svn.freebsd.org> From: John Baldwin Date: Mon, 19 Sep 2011 16:25:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225673 - stable/8/usr.sbin/mfiutil X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Sep 2011 16:25:37 -0000 Author: jhb Date: Mon Sep 19 16:25:37 2011 New Revision: 225673 URL: http://svn.freebsd.org/changeset/base/225673 Log: MFC 225331: Move the logic to parse volume cache commands out into a separate function and use a loop so that multiple cache commands can be strung together on the command line into a single update to the volume's properties. Modified: stable/8/usr.sbin/mfiutil/mfi_volume.c stable/8/usr.sbin/mfiutil/mfiutil.8 Directory Properties: stable/8/usr.sbin/mfiutil/ (props changed) Modified: stable/8/usr.sbin/mfiutil/mfi_volume.c ============================================================================== --- stable/8/usr.sbin/mfiutil/mfi_volume.c Mon Sep 19 16:01:53 2011 (r225672) +++ stable/8/usr.sbin/mfiutil/mfi_volume.c Mon Sep 19 16:25:37 2011 (r225673) @@ -111,16 +111,16 @@ mfi_ld_set_props(int fd, struct mfi_ld_p } static int -update_cache_policy(int fd, struct mfi_ld_props *props, uint8_t new_policy, - uint8_t mask) +update_cache_policy(int fd, struct mfi_ld_props *old, struct mfi_ld_props *new) { int error; uint8_t changes, policy; - policy = (props->default_cache_policy & ~mask) | new_policy; - if (policy == props->default_cache_policy) + if (old->default_cache_policy == new->default_cache_policy && + old->disk_cache_policy == new->disk_cache_policy) return (0); - changes = policy ^ props->default_cache_policy; + policy = new->default_cache_policy; + changes = policy ^ old->default_cache_policy; if (changes & MR_LD_CACHE_ALLOW_WRITE_CACHE) printf("%s caching of I/O writes\n", policy & MR_LD_CACHE_ALLOW_WRITE_CACHE ? "Enabling" : @@ -142,9 +142,21 @@ update_cache_policy(int fd, struct mfi_l printf("%s write caching with bad BBU\n", policy & MR_LD_CACHE_WRITE_CACHE_BAD_BBU ? "Enabling" : "Disabling"); + if (old->disk_cache_policy != new->disk_cache_policy) { + switch (new->disk_cache_policy) { + case MR_PD_CACHE_ENABLE: + printf("Enabling write-cache on physical drives\n"); + break; + case MR_PD_CACHE_DISABLE: + printf("Disabling write-cache on physical drives\n"); + break; + case MR_PD_CACHE_UNCHANGED: + printf("Using default write-cache setting on physical drives\n"); + break; + } + } - props->default_cache_policy = policy; - if (mfi_ld_set_props(fd, props) < 0) { + if (mfi_ld_set_props(fd, new) < 0) { error = errno; warn("Failed to set volume properties"); return (error); @@ -152,12 +164,130 @@ update_cache_policy(int fd, struct mfi_l return (0); } +static void +stage_cache_setting(struct mfi_ld_props *props, uint8_t new_policy, + uint8_t mask) +{ + + props->default_cache_policy &= ~mask; + props->default_cache_policy |= new_policy; +} + +/* + * Parse a single cache directive modifying the passed in policy. + * Returns -1 on a parse error and the number of arguments consumed + * on success. + */ +static int +process_cache_command(int ac, char **av, struct mfi_ld_props *props) +{ + uint8_t policy; + + /* I/O cache settings. */ + if (strcmp(av[0], "all") == 0 || strcmp(av[0], "enable") == 0) { + stage_cache_setting(props, MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + return (1); + } + if (strcmp(av[0], "none") == 0 || strcmp(av[0], "disable") == 0) { + stage_cache_setting(props, 0, MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + return (1); + } + if (strcmp(av[0], "reads") == 0) { + stage_cache_setting(props, MR_LD_CACHE_ALLOW_READ_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + return (1); + } + if (strcmp(av[0], "writes") == 0) { + stage_cache_setting(props, MR_LD_CACHE_ALLOW_WRITE_CACHE, + MR_LD_CACHE_ALLOW_READ_CACHE | + MR_LD_CACHE_ALLOW_WRITE_CACHE); + return (1); + } + + /* Write cache behavior. */ + if (strcmp(av[0], "write-back") == 0) { + stage_cache_setting(props, MR_LD_CACHE_WRITE_BACK, + MR_LD_CACHE_WRITE_BACK); + return (1); + } + if (strcmp(av[0], "write-through") == 0) { + stage_cache_setting(props, 0, MR_LD_CACHE_WRITE_BACK); + return (1); + } + if (strcmp(av[0], "bad-bbu-write-cache") == 0) { + if (ac < 2) { + warnx("cache: bad BBU setting required"); + return (-1); + } + if (strcmp(av[1], "enable") == 0) + policy = MR_LD_CACHE_WRITE_CACHE_BAD_BBU; + else if (strcmp(av[1], "disable") == 0) + policy = 0; + else { + warnx("cache: invalid bad BBU setting"); + return (-1); + } + stage_cache_setting(props, policy, + MR_LD_CACHE_WRITE_CACHE_BAD_BBU); + return (2); + } + + /* Read cache behavior. */ + if (strcmp(av[0], "read-ahead") == 0) { + if (ac < 2) { + warnx("cache: read-ahead setting required"); + return (-1); + } + if (strcmp(av[1], "none") == 0) + policy = 0; + else if (strcmp(av[1], "always") == 0) + policy = MR_LD_CACHE_READ_AHEAD; + else if (strcmp(av[1], "adaptive") == 0) + policy = MR_LD_CACHE_READ_AHEAD | + MR_LD_CACHE_READ_ADAPTIVE; + else { + warnx("cache: invalid read-ahead setting"); + return (-1); + } + stage_cache_setting(props, policy, MR_LD_CACHE_READ_AHEAD | + MR_LD_CACHE_READ_ADAPTIVE); + return (2); + } + + /* Drive write-cache behavior. */ + if (strcmp(av[0], "write-cache") == 0) { + if (ac < 2) { + warnx("cache: write-cache setting required"); + return (-1); + } + if (strcmp(av[1], "enable") == 0) + props->disk_cache_policy = MR_PD_CACHE_ENABLE; + else if (strcmp(av[1], "disable") == 0) + props->disk_cache_policy = MR_PD_CACHE_DISABLE; + else if (strcmp(av[1], "default") == 0) + props->disk_cache_policy = MR_PD_CACHE_UNCHANGED; + else { + warnx("cache: invalid write-cache setting"); + return (-1); + } + return (2); + } + + warnx("cache: Invalid command"); + return (-1); +} + static int volume_cache(int ac, char **av) { - struct mfi_ld_props props; - int error, fd; - uint8_t target_id, policy; + struct mfi_ld_props props, new; + int error, fd, consumed; + uint8_t target_id; if (ac < 2) { warnx("cache: volume required"); @@ -235,113 +365,19 @@ volume_cache(int ac, char **av) printf("Cache Disabled Due to Dead Battery\n"); error = 0; } else { - if (strcmp(av[2], "all") == 0 || strcmp(av[2], "enable") == 0) - error = update_cache_policy(fd, &props, - MR_LD_CACHE_ALLOW_READ_CACHE | - MR_LD_CACHE_ALLOW_WRITE_CACHE, - MR_LD_CACHE_ALLOW_READ_CACHE | - MR_LD_CACHE_ALLOW_WRITE_CACHE); - else if (strcmp(av[2], "none") == 0 || - strcmp(av[2], "disable") == 0) - error = update_cache_policy(fd, &props, 0, - MR_LD_CACHE_ALLOW_READ_CACHE | - MR_LD_CACHE_ALLOW_WRITE_CACHE); - else if (strcmp(av[2], "reads") == 0) - error = update_cache_policy(fd, &props, - MR_LD_CACHE_ALLOW_READ_CACHE, - MR_LD_CACHE_ALLOW_READ_CACHE | - MR_LD_CACHE_ALLOW_WRITE_CACHE); - else if (strcmp(av[2], "writes") == 0) - error = update_cache_policy(fd, &props, - MR_LD_CACHE_ALLOW_WRITE_CACHE, - MR_LD_CACHE_ALLOW_READ_CACHE | - MR_LD_CACHE_ALLOW_WRITE_CACHE); - else if (strcmp(av[2], "write-back") == 0) - error = update_cache_policy(fd, &props, - MR_LD_CACHE_WRITE_BACK, - MR_LD_CACHE_WRITE_BACK); - else if (strcmp(av[2], "write-through") == 0) - error = update_cache_policy(fd, &props, 0, - MR_LD_CACHE_WRITE_BACK); - else if (strcmp(av[2], "read-ahead") == 0) { - if (ac < 4) { - warnx("cache: read-ahead setting required"); - close(fd); - return (EINVAL); - } - if (strcmp(av[3], "none") == 0) - policy = 0; - else if (strcmp(av[3], "always") == 0) - policy = MR_LD_CACHE_READ_AHEAD; - else if (strcmp(av[3], "adaptive") == 0) - policy = MR_LD_CACHE_READ_AHEAD | - MR_LD_CACHE_READ_ADAPTIVE; - else { - warnx("cache: invalid read-ahead setting"); - close(fd); - return (EINVAL); - } - error = update_cache_policy(fd, &props, policy, - MR_LD_CACHE_READ_AHEAD | - MR_LD_CACHE_READ_ADAPTIVE); - } else if (strcmp(av[2], "bad-bbu-write-cache") == 0) { - if (ac < 4) { - warnx("cache: bad BBU setting required"); + new = props; + av += 2; + ac -= 2; + while (ac > 0) { + consumed = process_cache_command(ac, av, &new); + if (consumed < 0) { close(fd); return (EINVAL); } - if (strcmp(av[3], "enable") == 0) - policy = MR_LD_CACHE_WRITE_CACHE_BAD_BBU; - else if (strcmp(av[3], "disable") == 0) - policy = 0; - else { - warnx("cache: invalid bad BBU setting"); - close(fd); - return (EINVAL); - } - error = update_cache_policy(fd, &props, policy, - MR_LD_CACHE_WRITE_CACHE_BAD_BBU); - } else if (strcmp(av[2], "write-cache") == 0) { - if (ac < 4) { - warnx("cache: write-cache setting required"); - close(fd); - return (EINVAL); - } - if (strcmp(av[3], "enable") == 0) - policy = MR_PD_CACHE_ENABLE; - else if (strcmp(av[3], "disable") == 0) - policy = MR_PD_CACHE_DISABLE; - else if (strcmp(av[3], "default") == 0) - policy = MR_PD_CACHE_UNCHANGED; - else { - warnx("cache: invalid write-cache setting"); - close(fd); - return (EINVAL); - } - error = 0; - if (policy != props.disk_cache_policy) { - switch (policy) { - case MR_PD_CACHE_ENABLE: - printf("Enabling write-cache on physical drives\n"); - break; - case MR_PD_CACHE_DISABLE: - printf("Disabling write-cache on physical drives\n"); - break; - case MR_PD_CACHE_UNCHANGED: - printf("Using default write-cache setting on physical drives\n"); - break; - } - props.disk_cache_policy = policy; - if (mfi_ld_set_props(fd, &props) < 0) { - error = errno; - warn("Failed to set volume properties"); - } - } - } else { - warnx("cache: Invalid command"); - close(fd); - return (EINVAL); + av += consumed; + ac -= consumed; } + error = update_cache_policy(fd, &props, &new); } close(fd); Modified: stable/8/usr.sbin/mfiutil/mfiutil.8 ============================================================================== --- stable/8/usr.sbin/mfiutil/mfiutil.8 Mon Sep 19 16:01:53 2011 (r225672) +++ stable/8/usr.sbin/mfiutil/mfiutil.8 Mon Sep 19 16:25:37 2011 (r225673) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 20, 2011 +.Dd September 2, 2011 .Dt MFIUTIL 8 .Os .Sh NAME @@ -103,7 +103,7 @@ .Cm locate Ar drive Brq "on | off" .Nm .Op Fl u Ar unit -.Cm cache Ar volume Op Ar setting Op Ar value +.Cm cache Ar volume Op Ar setting Oo Ar value Oc Op ... .Nm .Op Fl u Ar unit .Cm name Ar volume Ar name @@ -367,19 +367,23 @@ Change the state of the external LED ass .Pp The logical volume management commands include: .Bl -tag -width indent -.It Cm cache Ar volume Op Ar setting Op Ar value +.It Cm cache Ar volume Op Ar setting Oo Ar value Oc Op ... If no .Ar setting -argument is supplied, then the current cache policy for +arguments are supplied, then the current cache policy for .Ar volume is displayed; otherwise, the cache policy for .Ar volume is modified. -The optional +One or more .Ar setting -argument can be one of the following values: +arguments may be given. +Some settings take an additional +.Ar value +argument as noted below. +The valid settings are: .Bl -tag -width indent .It Cm enable Enable caching for both read and write I/O operations.