tunefs.c revision 109597
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1983, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 3538040Scharnierstatic const char copyright[] = 361558Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 371558Srgrimes The Regents of the University of California. All rights reserved.\n"; 381558Srgrimes#endif /* not lint */ 391558Srgrimes 401558Srgrimes#ifndef lint 4138040Scharnier#if 0 421558Srgrimesstatic char sccsid[] = "@(#)tunefs.c 8.2 (Berkeley) 4/19/94"; 4338040Scharnier#endif 4438040Scharnierstatic const char rcsid[] = 4550476Speter "$FreeBSD: head/sbin/tunefs/tunefs.c 109597 2003-01-20 21:15:02Z jmallett $"; 461558Srgrimes#endif /* not lint */ 471558Srgrimes 481558Srgrimes/* 49102231Strhodes * tunefs: change layout parameters to an existing file system. 501558Srgrimes */ 511558Srgrimes#include <sys/param.h> 5242873Sluoqi#include <sys/mount.h> 5396478Sphk#include <sys/disklabel.h> 541558Srgrimes#include <sys/stat.h> 551558Srgrimes 5698542Smckusick#include <ufs/ufs/ufsmount.h> 5798542Smckusick#include <ufs/ufs/dinode.h> 581558Srgrimes#include <ufs/ffs/fs.h> 591558Srgrimes 601558Srgrimes#include <err.h> 611558Srgrimes#include <fcntl.h> 621558Srgrimes#include <fstab.h> 63109597Sjmallett#include <libufs.h> 6438040Scharnier#include <paths.h> 651558Srgrimes#include <stdio.h> 661558Srgrimes#include <stdlib.h> 6758047Ssheldonh#include <string.h> 681558Srgrimes#include <unistd.h> 691558Srgrimes 701558Srgrimes/* the optimization warning string template */ 711558Srgrimes#define OPTWARN "should optimize for %s with minfree %s %d%%" 721558Srgrimes 73109597Sjmallettstruct uufsd disk; 74109597Sjmallett#define sblock disk.d_fs 751558Srgrimes 7692883Simpvoid usage(void); 7792883Simpvoid printfs(void); 781558Srgrimes 791558Srgrimesint 80109597Sjmallettmain(int argc, char *argv[]) 811558Srgrimes{ 8279750Sdd char *special; 8379750Sdd const char *name; 841558Srgrimes struct stat st; 85105120Srwatson int Aflag = 0, active = 0, aflag = 0; 86105120Srwatson int eflag = 0, fflag = 0, lflag = 0, mflag = 0; 8775377Smckusick int nflag = 0, oflag = 0, pflag = 0, sflag = 0; 88103005Sphk int evalue = 0, fvalue = 0; 8975377Smckusick int mvalue = 0, ovalue = 0, svalue = 0; 90105120Srwatson char *avalue = NULL, *lvalue = NULL, *nvalue = NULL; 911558Srgrimes struct fstab *fs; 9279750Sdd const char *chg[2]; 9379750Sdd char device[MAXPATHLEN]; 9442873Sluoqi struct ufs_args args; 9542873Sluoqi struct statfs stfs; 9669314Scharnier int found_arg, ch; 971558Srgrimes 9869314Scharnier if (argc < 3) 9969314Scharnier usage(); 10069314Scharnier found_arg = 0; /* at least one arg is required */ 101105156Srwatson while ((ch = getopt(argc, argv, "Aa:e:f:l:m:n:o:ps:")) != -1) 10269314Scharnier switch (ch) { 103105156Srwatson case 'A': 104105156Srwatson found_arg = 1; 105105156Srwatson Aflag++; 106105156Srwatson break; 107105120Srwatson case 'a': 108105120Srwatson found_arg = 1; 109105120Srwatson name = "ACLs"; 110105120Srwatson avalue = optarg; 111105120Srwatson if (strcmp(avalue, "enable") && strcmp(avalue, "disable")) { 112105120Srwatson errx(10, "bad %s (options are %s)", name, 113105120Srwatson "`enable' or `disable'"); 114105120Srwatson } 115105120Srwatson aflag = 1; 116105120Srwatson break; 11769314Scharnier case 'e': 11869314Scharnier found_arg = 1; 11969314Scharnier name = "maximum blocks per file in a cylinder group"; 12069829Scharnier evalue = atoi(optarg); 12169829Scharnier if (evalue < 1) 12269314Scharnier errx(10, "%s must be >= 1 (was %s)", name, optarg); 12369829Scharnier eflag = 1; 12469314Scharnier break; 12575377Smckusick case 'f': 12675377Smckusick found_arg = 1; 12775377Smckusick name = "average file size"; 12875377Smckusick fvalue = atoi(optarg); 12975377Smckusick if (fvalue < 1) 13075377Smckusick errx(10, "%s must be >= 1 (was %s)", name, optarg); 13175377Smckusick fflag = 1; 13275377Smckusick break; 133105120Srwatson case 'l': 134105120Srwatson found_arg = 1; 135105120Srwatson name = "multilabel MAC file system"; 136105120Srwatson lvalue = optarg; 137105120Srwatson if (strcmp(lvalue, "enable") && strcmp(lvalue, "disable")) { 138105120Srwatson errx(10, "bad %s (options are %s)", name, 139105120Srwatson "`enable' or `disable'"); 140105120Srwatson } 141105120Srwatson lflag = 1; 142105120Srwatson break; 14369314Scharnier case 'm': 14469314Scharnier found_arg = 1; 14569314Scharnier name = "minimum percentage of free space"; 14669829Scharnier mvalue = atoi(optarg); 14769829Scharnier if (mvalue < 0 || mvalue > 99) 14869314Scharnier errx(10, "bad %s (%s)", name, optarg); 14969829Scharnier mflag = 1; 15069314Scharnier break; 15169314Scharnier case 'n': 15269314Scharnier found_arg = 1; 15369314Scharnier name = "soft updates"; 15469829Scharnier nvalue = optarg; 15569829Scharnier if (strcmp(nvalue, "enable") && strcmp(nvalue, "disable")) { 15669314Scharnier errx(10, "bad %s (options are %s)", 15769314Scharnier name, "`enable' or `disable'"); 15869314Scharnier } 15969829Scharnier nflag = 1; 16069314Scharnier break; 16169314Scharnier case 'o': 16269314Scharnier found_arg = 1; 16369314Scharnier name = "optimization preference"; 16469314Scharnier chg[FS_OPTSPACE] = "space"; 16569314Scharnier chg[FS_OPTTIME] = "time"; 16669314Scharnier if (strcmp(optarg, chg[FS_OPTSPACE]) == 0) 16769829Scharnier ovalue = FS_OPTSPACE; 16869314Scharnier else if (strcmp(optarg, chg[FS_OPTTIME]) == 0) 16969829Scharnier ovalue = FS_OPTTIME; 17069314Scharnier else 17169314Scharnier errx(10, "bad %s (options are `space' or `time')", 1721558Srgrimes name); 17369829Scharnier oflag = 1; 17469314Scharnier break; 17569314Scharnier case 'p': 17671790Sben found_arg = 1; 17769829Scharnier pflag = 1; 17869829Scharnier break; 17975377Smckusick case 's': 18075377Smckusick found_arg = 1; 18175377Smckusick name = "expected number of files per directory"; 18275377Smckusick svalue = atoi(optarg); 18375377Smckusick if (svalue < 1) 18475377Smckusick errx(10, "%s must be >= 1 (was %s)", name, optarg); 18575377Smckusick sflag = 1; 18675377Smckusick break; 18769314Scharnier default: 18869314Scharnier usage(); 18969314Scharnier } 19069314Scharnier argc -= optind; 19169314Scharnier argv += optind; 1921558Srgrimes 19369314Scharnier if (found_arg == 0 || argc != 1) 19469314Scharnier usage(); 19569314Scharnier 19669829Scharnier special = argv[0]; 19769829Scharnier fs = getfsfile(special); 19869829Scharnier if (fs) { 19969829Scharnier if (statfs(special, &stfs) == 0 && 20069829Scharnier strcmp(special, stfs.f_mntonname) == 0) { 20169829Scharnier active = 1; 20269829Scharnier } 20369829Scharnier special = fs->fs_spec; 20469829Scharnier } 20569829Scharnieragain: 20669829Scharnier if (stat(special, &st) < 0) { 20769829Scharnier if (*special != '/') { 20869829Scharnier if (*special == 'r') 20969829Scharnier special++; 21084166Siedowse (void)snprintf(device, sizeof(device), "%s%s", 21180277Skris _PATH_DEV, special); 21269829Scharnier special = device; 21369829Scharnier goto again; 21469829Scharnier } 21569829Scharnier err(1, "%s", special); 21669829Scharnier } 21784166Siedowse if (fs == NULL && (st.st_mode & S_IFMT) == S_IFDIR) 218102231Strhodes errx(10, "%s: unknown file system", special); 219109597Sjmallett if (ufs_disk_fillout(&disk, special) == -1) { 220109597Sjmallett if (disk.d_error != NULL) 221109597Sjmallett errx(11, "%s: %s", special, disk.d_error); 222109597Sjmallett else 223109597Sjmallett err(12, "%s", special); 224109597Sjmallett } 22569829Scharnier 22669829Scharnier if (pflag) { 22769829Scharnier printfs(); 22869829Scharnier exit(0); 22969829Scharnier } 230105120Srwatson if (aflag) { 231105120Srwatson name = "ACLs"; 232105120Srwatson if (strcmp(avalue, "enable") == 0) { 233105120Srwatson if (sblock.fs_flags & FS_ACLS) { 234105120Srwatson warnx("%s remains unchanged as enabled", name); 235105120Srwatson } else { 236105120Srwatson sblock.fs_flags |= FS_ACLS; 237105120Srwatson warnx("%s set", name); 238105120Srwatson } 239105120Srwatson } else if (strcmp(avalue, "disable") == 0) { 240105120Srwatson if ((~sblock.fs_flags & FS_ACLS) == 241105120Srwatson FS_ACLS) { 242105120Srwatson warnx("%s remains unchanged as disabled", 243105120Srwatson name); 244105120Srwatson } else { 245105120Srwatson sblock.fs_flags &= ~FS_ACLS; 246105206Srwatson warnx("%s cleared", name); 247105120Srwatson } 248105120Srwatson } 249105120Srwatson } 25069829Scharnier if (eflag) { 25169829Scharnier name = "maximum blocks per file in a cylinder group"; 25269829Scharnier if (sblock.fs_maxbpg == evalue) { 25369829Scharnier warnx("%s remains unchanged as %d", name, evalue); 25469829Scharnier } 25569829Scharnier else { 25669829Scharnier warnx("%s changes from %d to %d", 25769829Scharnier name, sblock.fs_maxbpg, evalue); 25869829Scharnier sblock.fs_maxbpg = evalue; 25969829Scharnier } 26069829Scharnier } 26175377Smckusick if (fflag) { 26275377Smckusick name = "average file size"; 26375377Smckusick if (sblock.fs_avgfilesize == fvalue) { 26475377Smckusick warnx("%s remains unchanged as %d", name, fvalue); 26575377Smckusick } 26675377Smckusick else { 26775377Smckusick warnx("%s changes from %d to %d", 26875377Smckusick name, sblock.fs_avgfilesize, fvalue); 26975377Smckusick sblock.fs_avgfilesize = fvalue; 27075377Smckusick } 27175377Smckusick } 272105120Srwatson if (lflag) { 273105120Srwatson name = "multilabel"; 274105120Srwatson if (strcmp(lvalue, "enable") == 0) { 275105120Srwatson if (sblock.fs_flags & FS_MULTILABEL) { 276105120Srwatson warnx("%s remains unchanged as enabled", name); 277105120Srwatson } else { 278105120Srwatson sblock.fs_flags |= FS_MULTILABEL; 279105120Srwatson warnx("%s set", name); 280105120Srwatson } 281105120Srwatson } else if (strcmp(lvalue, "disable") == 0) { 282105120Srwatson if ((~sblock.fs_flags & FS_MULTILABEL) == 283105120Srwatson FS_MULTILABEL) { 284105120Srwatson warnx("%s remains unchanged as disabled", 285105120Srwatson name); 286105120Srwatson } else { 287105120Srwatson sblock.fs_flags &= ~FS_MULTILABEL; 288105206Srwatson warnx("%s cleared", name); 289105120Srwatson } 290105120Srwatson } 291105120Srwatson } 29269829Scharnier if (mflag) { 29369829Scharnier name = "minimum percentage of free space"; 29469829Scharnier if (sblock.fs_minfree == mvalue) { 29569829Scharnier warnx("%s remains unchanged as %d%%", name, mvalue); 29669829Scharnier } 29769829Scharnier else { 29869829Scharnier warnx("%s changes from %d%% to %d%%", 29969829Scharnier name, sblock.fs_minfree, mvalue); 30069829Scharnier sblock.fs_minfree = mvalue; 30169829Scharnier if (mvalue >= MINFREE && sblock.fs_optim == FS_OPTSPACE) 30269829Scharnier warnx(OPTWARN, "time", ">=", MINFREE); 30369829Scharnier if (mvalue < MINFREE && sblock.fs_optim == FS_OPTTIME) 30469829Scharnier warnx(OPTWARN, "space", "<", MINFREE); 30569829Scharnier } 30669829Scharnier } 30769829Scharnier if (nflag) { 30869829Scharnier name = "soft updates"; 30969829Scharnier if (strcmp(nvalue, "enable") == 0) { 31075498Smckusick if (sblock.fs_flags & FS_DOSOFTDEP) { 31169829Scharnier warnx("%s remains unchanged as enabled", name); 31275498Smckusick } else if (sblock.fs_clean == 0) { 31375498Smckusick warnx("%s cannot be enabled until fsck is run", 31475498Smckusick name); 31569829Scharnier } else { 31669829Scharnier sblock.fs_flags |= FS_DOSOFTDEP; 31769829Scharnier warnx("%s set", name); 31869829Scharnier } 31969829Scharnier } else if (strcmp(nvalue, "disable") == 0) { 32069829Scharnier if ((~sblock.fs_flags & FS_DOSOFTDEP) == FS_DOSOFTDEP) { 32169829Scharnier warnx("%s remains unchanged as disabled", name); 32269829Scharnier } else { 32369829Scharnier sblock.fs_flags &= ~FS_DOSOFTDEP; 32469829Scharnier warnx("%s cleared", name); 32569829Scharnier } 32669829Scharnier } 32769829Scharnier } 32869829Scharnier if (oflag) { 32969829Scharnier name = "optimization preference"; 33069829Scharnier chg[FS_OPTSPACE] = "space"; 33169829Scharnier chg[FS_OPTTIME] = "time"; 33269829Scharnier if (sblock.fs_optim == ovalue) { 33369829Scharnier warnx("%s remains unchanged as %s", name, chg[ovalue]); 33469829Scharnier } 33569829Scharnier else { 33669829Scharnier warnx("%s changes from %s to %s", 33769829Scharnier name, chg[sblock.fs_optim], chg[ovalue]); 33869829Scharnier sblock.fs_optim = ovalue; 33969829Scharnier if (sblock.fs_minfree >= MINFREE && 34069829Scharnier ovalue == FS_OPTSPACE) 34169829Scharnier warnx(OPTWARN, "time", ">=", MINFREE); 34269829Scharnier if (sblock.fs_minfree < MINFREE && 34369829Scharnier ovalue == FS_OPTTIME) 34469829Scharnier warnx(OPTWARN, "space", "<", MINFREE); 34569829Scharnier } 34669829Scharnier } 34775377Smckusick if (sflag) { 34875377Smckusick name = "expected number of files per directory"; 34975377Smckusick if (sblock.fs_avgfpdir == svalue) { 35075377Smckusick warnx("%s remains unchanged as %d", name, svalue); 35175377Smckusick } 35275377Smckusick else { 35375377Smckusick warnx("%s changes from %d to %d", 35475377Smckusick name, sblock.fs_avgfpdir, svalue); 35575377Smckusick sblock.fs_avgfpdir = svalue; 35675377Smckusick } 35775377Smckusick } 35869829Scharnier 359109597Sjmallett sbwrite(&disk, Aflag); 36042873Sluoqi if (active) { 36142873Sluoqi bzero(&args, sizeof(args)); 36242873Sluoqi if (mount("ufs", fs->fs_file, 36342873Sluoqi stfs.f_flags | MNT_UPDATE | MNT_RELOAD, &args) < 0) 36442873Sluoqi err(9, "%s: reload", special); 365102231Strhodes warnx("file system reloaded"); 36642873Sluoqi } 3671558Srgrimes exit(0); 3681558Srgrimes} 3691558Srgrimes 3701558Srgrimesvoid 371109597Sjmallettusage(void) 3721558Srgrimes{ 37338040Scharnier fprintf(stderr, "%s\n%s\n%s\n", 374105156Srwatson"usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]", 375105120Srwatson" [-l enable | disable] [-m minfree] [-n enable | disable]", 376105120Srwatson" [-o space | time] [-p] [-s avgfpdir] special | filesystem"); 3771558Srgrimes exit(2); 3781558Srgrimes} 3791558Srgrimes 3801558Srgrimesvoid 381109597Sjmallettprintfs(void) 3821558Srgrimes{ 383105162Srwatson warnx("ACLs: (-a) %s", 384105162Srwatson (sblock.fs_flags & FS_ACLS)? "enabled" : "disabled"); 385105162Srwatson warnx("MAC multilabel: (-l) %s", 386105162Srwatson (sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled"); 387109468Sjmallett warnx("soft updates: (-n) %s", 38834266Sjulian (sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled"); 3899315Sjoerg warnx("maximum blocks per file in a cylinder group: (-e) %d", 3909315Sjoerg sblock.fs_maxbpg); 39175377Smckusick warnx("average file size: (-f) %d", 39275377Smckusick sblock.fs_avgfilesize); 39375377Smckusick warnx("average number of files in a directory: (-s) %d", 39475377Smckusick sblock.fs_avgfpdir); 3959315Sjoerg warnx("minimum percentage of free space: (-m) %d%%", 3969315Sjoerg sblock.fs_minfree); 3979315Sjoerg warnx("optimization preference: (-o) %s", 3989315Sjoerg sblock.fs_optim == FS_OPTSPACE ? "space" : "time"); 3999315Sjoerg if (sblock.fs_minfree >= MINFREE && 4009315Sjoerg sblock.fs_optim == FS_OPTSPACE) 4019315Sjoerg warnx(OPTWARN, "time", ">=", MINFREE); 4029315Sjoerg if (sblock.fs_minfree < MINFREE && 4039315Sjoerg sblock.fs_optim == FS_OPTTIME) 4049315Sjoerg warnx(OPTWARN, "space", "<", MINFREE); 4059315Sjoerg} 406