tune2fs.c revision f3db3566b5e1342e49dffc5ec3f418a838584194
1/* 2 * tune2fs.c - Change the file system parameters on 3 * an unmounted second extended file system 4 * 5 * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> 6 * Laboratoire MASI, Institut Blaise Pascal 7 * Universite Pierre et Marie Curie (Paris VI) 8 * 9 * This file can be redistributed under the terms of the GNU General 10 * Public License 11 */ 12 13/* 14 * History: 15 * 93/06/01 - Creation 16 * 93/10/31 - Added the -c option to change the maximal mount counts 17 * 93/12/14 - Added -l flag to list contents of superblock 18 * M.J.E. Mol (marcel@duteca.et.tudelft.nl) 19 * F.W. ten Wolde (franky@duteca.et.tudelft.nl) 20 * 93/12/29 - Added the -e option to change errors behavior 21 * 94/02/27 - Ported to use the ext2fs library 22 * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de) 23 */ 24 25#include <fcntl.h> 26#include <grp.h> 27#include <getopt.h> 28#include <pwd.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32#include <time.h> 33#include <unistd.h> 34#include <sys/types.h> 35 36#include <linux/ext2_fs.h> 37 38#include "ext2fs/ext2fs.h" 39#include "et/com_err.h" 40#include "e2p/e2p.h" 41 42#include "../version.h" 43 44const char * program_name = "tune2fs"; 45char * device_name = NULL; 46int c_flag = 0; 47int e_flag = 0; 48int g_flag = 0; 49int i_flag = 0; 50int l_flag = 0; 51int m_flag = 0; 52int r_flag = 0; 53int u_flag = 0; 54int max_mount_count; 55unsigned long interval; 56unsigned long reserved_ratio = 0; 57unsigned long reserved_blocks = 0; 58unsigned short errors; 59unsigned long resgid = 0; 60unsigned long resuid = 0; 61 62static volatile void usage (void) 63{ 64 fprintf (stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] " 65 "[-g group]\n" 66 "\t[-i interval[d|m|w]] [-l] [-m reserved-blocks-percent]\n" 67 "\t[-r reserved-blocks-count] [-u user] device\n", program_name); 68 exit (1); 69} 70 71void main (int argc, char ** argv) 72{ 73 char c; 74 char * tmp; 75 errcode_t retval; 76 ext2_filsys fs; 77 struct group * gr; 78 struct passwd * pw; 79 80 fprintf (stderr, "tune2fs %s, %s for EXT2 FS %s, %s\n", 81 E2FSPROGS_VERSION, E2FSPROGS_DATE, 82 EXT2FS_VERSION, EXT2FS_DATE); 83 if (argc && *argv) 84 program_name = *argv; 85 initialize_ext2_error_table(); 86 while ((c = getopt (argc, argv, "c:e:g:i:lm:r:u:")) != EOF) 87 switch (c) 88 { 89 case 'c': 90 max_mount_count = strtoul (optarg, &tmp, 0); 91 if (*tmp || max_mount_count > 16000) 92 { 93 com_err (program_name, 0, 94 "bad mounts count - %s", 95 optarg); 96 usage (); 97 } 98 c_flag = 1; 99 break; 100 case 'e': 101 if (strcmp (optarg, "continue") == 0) 102 errors = EXT2_ERRORS_CONTINUE; 103 else if (strcmp (optarg, "remount-ro") == 0) 104 errors = EXT2_ERRORS_RO; 105 else if (strcmp (optarg, "panic") == 0) 106 errors = EXT2_ERRORS_PANIC; 107 else 108 { 109 com_err (program_name, 0, 110 "bad error behavior - %s", 111 optarg); 112 usage (); 113 } 114 e_flag = 1; 115 break; 116 case 'g': 117 resgid = strtoul (optarg, &tmp, 0); 118 if (*tmp) 119 { 120 gr = getgrnam (optarg); 121 if (gr == NULL) 122 tmp = optarg; 123 else 124 resgid = gr->gr_gid; 125 } 126 if (*tmp) 127 { 128 com_err (program_name, 0, 129 "bad gid/group name - %s", 130 optarg); 131 usage (); 132 } 133 g_flag = 1; 134 break; 135 case 'i': 136 interval = strtoul (optarg, &tmp, 0); 137 switch (*tmp) 138 { 139 case '\0': 140 case 'd': 141 case 'D': /* days */ 142 interval *= 86400; 143 if (*tmp != '\0') 144 tmp++; 145 break; 146 case 'm': 147 case 'M': /* months! */ 148 interval *= 86400 * 30; 149 tmp++; 150 break; 151 case 'w': 152 case 'W': /* weeks */ 153 interval *= 86400 * 7; 154 tmp++; 155 break; 156 } 157 if (*tmp || interval > (365 * 86400)) 158 { 159 com_err (program_name, 0, 160 "bad interval - %s", optarg); 161 usage (); 162 } 163 i_flag = 1; 164 break; 165 case 'l': 166 l_flag = 1; 167 break; 168 case 'm': 169 reserved_ratio = strtoul (optarg, &tmp, 0); 170 if (*tmp || reserved_ratio > 50) 171 { 172 com_err (program_name, 0, 173 "bad reserved block ratio - %s", 174 optarg); 175 usage (); 176 } 177 m_flag = 1; 178 break; 179 case 'r': 180 reserved_blocks = strtoul (optarg, &tmp, 0); 181 if (*tmp) 182 { 183 com_err (program_name, 0, 184 "bad reserved blocks count - %s", 185 optarg); 186 usage (); 187 } 188 r_flag = 1; 189 break; 190 case 'u': 191 resuid = strtoul (optarg, &tmp, 0); 192 if (*tmp) 193 { 194 pw = getpwnam (optarg); 195 if (pw == NULL) 196 tmp = optarg; 197 else 198 resuid = pw->pw_uid; 199 } 200 if (*tmp) 201 { 202 com_err (program_name, 0, 203 "bad uid/user name - %s", 204 optarg); 205 usage (); 206 } 207 u_flag = 1; 208 break; 209 default: 210 usage (); 211 } 212 if (optind < argc - 1 || optind == argc) 213 usage (); 214 if (!c_flag && !e_flag && !g_flag && !i_flag && !l_flag && !m_flag 215 && !r_flag && !u_flag) 216 usage (); 217 device_name = argv[optind]; 218 retval = ext2fs_open (device_name, 219 (c_flag || e_flag || g_flag || i_flag || m_flag 220 || r_flag || u_flag) ? EXT2_FLAG_RW : 0, 221 0, 0, unix_io_manager, &fs); 222 if (retval) 223 { 224 com_err (program_name, retval, "while trying to open %s", 225 device_name); 226 printf("Couldn't find valid filesystem superblock.\n"); 227 exit(1); 228 } 229 230 if (c_flag) 231 { 232 fs->super->s_max_mnt_count = max_mount_count; 233 ext2fs_mark_super_dirty(fs); 234 printf ("Setting maximal mount count to %d\n", max_mount_count); 235 } 236 if (e_flag) 237 { 238 fs->super->s_errors = errors; 239 ext2fs_mark_super_dirty(fs); 240 printf ("Setting error behavior to %d\n", errors); 241 } 242 if (g_flag) 243#ifdef EXT2_DEF_RESGID 244 { 245 fs->super->s_def_resgid = resgid; 246 ext2fs_mark_super_dirty(fs); 247 printf ("Setting reserved blocks gid to %lu\n", resgid); 248 } 249#else 250 com_err (program_name, 0, 251 "The -g option is not supported by this version -- " 252 "Recompile with a newer kernel"); 253#endif 254 if (i_flag) 255 { 256 fs->super->s_checkinterval = interval; 257 ext2fs_mark_super_dirty(fs); 258 printf ("Setting interval between check %lu seconds\n", interval); 259 } 260 if (m_flag) 261 { 262 fs->super->s_r_blocks_count = (fs->super->s_blocks_count / 100) 263 * reserved_ratio; 264 ext2fs_mark_super_dirty(fs); 265 printf ("Setting reserved blocks percentage to %lu (%lu blocks)\n", 266 reserved_ratio, fs->super->s_r_blocks_count); 267 } 268 if (r_flag) 269 { 270 if (reserved_blocks >= fs->super->s_blocks_count) 271 { 272 com_err (program_name, 0, 273 "reserved blocks count is too big (%ul)", 274 reserved_blocks); 275 exit (1); 276 } 277 fs->super->s_r_blocks_count = reserved_blocks; 278 ext2fs_mark_super_dirty(fs); 279 printf ("Setting reserved blocks count to %lu\n", 280 reserved_blocks); 281 } 282 if (u_flag) 283#ifdef EXT2_DEF_RESUID 284 { 285 fs->super->s_def_resuid = resuid; 286 ext2fs_mark_super_dirty(fs); 287 printf ("Setting reserved blocks uid to %lu\n", resuid); 288 } 289#else 290 com_err (program_name, 0, 291 "The -u option is not supported by this version -- " 292 "Recompile with a newer kernel"); 293#endif 294 if (l_flag) 295 list_super (fs->super); 296 ext2fs_close (fs); 297 exit (0); 298} 299