]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - misc/tune2fs.c
ChangeLog, debugfs.c:
[thirdparty/e2fsprogs.git] / misc / tune2fs.c
CommitLineData
3839e657
TT
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 *
19c78dc0
TT
9 * Copyright 1995, 1996, 1997 by Theodore Ts'o.
10 *
11 * %Begin-Header%
12 * This file may be redistributed under the terms of the GNU Public
13 * License.
14 * %End-Header%
3839e657
TT
15 */
16
17/*
18 * History:
19 * 93/06/01 - Creation
20 * 93/10/31 - Added the -c option to change the maximal mount counts
21 * 93/12/14 - Added -l flag to list contents of superblock
22 * M.J.E. Mol (marcel@duteca.et.tudelft.nl)
23 * F.W. ten Wolde (franky@duteca.et.tudelft.nl)
24 * 93/12/29 - Added the -e option to change errors behavior
25 * 94/02/27 - Ported to use the ext2fs library
26 * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
27 */
28
29#include <fcntl.h>
f3db3566 30#include <grp.h>
a418d3ad 31#ifdef HAVE_GETOPT_H
3839e657 32#include <getopt.h>
a418d3ad 33#endif
f3db3566 34#include <pwd.h>
3839e657
TT
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <time.h>
39#include <unistd.h>
f3db3566 40#include <sys/types.h>
3839e657
TT
41
42#include <linux/ext2_fs.h>
43
44#include "ext2fs/ext2fs.h"
45#include "et/com_err.h"
1e3472c5 46#include "uuid/uuid.h"
3839e657
TT
47#include "e2p/e2p.h"
48
49#include "../version.h"
50
51const char * program_name = "tune2fs";
52char * device_name = NULL;
1e3472c5
TT
53char * new_label = NULL;
54char * new_last_mounted = NULL;
55char * new_UUID = NULL;
3839e657 56int c_flag = 0;
1e3472c5 57int C_flag = 0;
3839e657 58int e_flag = 0;
f3db3566 59int g_flag = 0;
3839e657
TT
60int i_flag = 0;
61int l_flag = 0;
1e3472c5 62int L_flag = 0;
3839e657 63int m_flag = 0;
1e3472c5 64int M_flag = 0;
f3db3566 65int r_flag = 0;
521e3685 66int s_flag = -1;
f3db3566 67int u_flag = 0;
1e3472c5
TT
68int U_flag = 0;
69int max_mount_count, mount_count;
3839e657
TT
70unsigned long interval;
71unsigned long reserved_ratio = 0;
f3db3566 72unsigned long reserved_blocks = 0;
3839e657 73unsigned short errors;
f3db3566
TT
74unsigned long resgid = 0;
75unsigned long resuid = 0;
3839e657 76
1e3472c5
TT
77#ifndef HAVE_STRCASECMP
78static int strcasecmp (char *s1, char *s2)
79{
80 while (*s1 && *s2) {
81 int ch1 = *s1++, ch2 = *s2++;
82 if (isupper (ch1))
83 ch1 = tolower (ch1);
84 if (isupper (ch2))
85 ch2 = tolower (ch2);
86 if (ch1 != ch2)
87 return ch1 - ch2;
88 }
89 return *s1 ? 1 : *s2 ? -1 : 0;
90}
91#endif
92
3839e657
TT
93static volatile void usage (void)
94{
95 fprintf (stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] "
f3db3566 96 "[-g group]\n"
521e3685 97 "\t[-i interval[d|m|w]] [-l] [-s] [-m reserved-blocks-percent]\n"
1e3472c5
TT
98 "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
99 "\t[-L volume-label] [-M last-mounted-dir] [-U UUID] "
100 "device\n", program_name);
3839e657
TT
101 exit (1);
102}
103
104void main (int argc, char ** argv)
105{
106 char c;
107 char * tmp;
108 errcode_t retval;
109 ext2_filsys fs;
1e3472c5 110 struct ext2fs_sb *sb;
f3db3566
TT
111 struct group * gr;
112 struct passwd * pw;
1e3472c5 113 int open_flag = 0;
3839e657
TT
114
115 fprintf (stderr, "tune2fs %s, %s for EXT2 FS %s, %s\n",
116 E2FSPROGS_VERSION, E2FSPROGS_DATE,
117 EXT2FS_VERSION, EXT2FS_DATE);
118 if (argc && *argv)
119 program_name = *argv;
120 initialize_ext2_error_table();
521e3685 121 while ((c = getopt (argc, argv, "c:e:g:i:lm:r:s:u:C:L:M:U:")) != EOF)
3839e657
TT
122 switch (c)
123 {
124 case 'c':
125 max_mount_count = strtoul (optarg, &tmp, 0);
126 if (*tmp || max_mount_count > 16000)
127 {
128 com_err (program_name, 0,
129 "bad mounts count - %s",
130 optarg);
131 usage ();
132 }
133 c_flag = 1;
1e3472c5
TT
134 open_flag = EXT2_FLAG_RW;
135 break;
136 case 'C':
137 mount_count = strtoul (optarg, &tmp, 0);
138 if (*tmp || mount_count > 16000)
139 {
140 com_err (program_name, 0,
141 "bad mounts count - %s",
142 optarg);
143 usage ();
144 }
145 C_flag = 1;
146 open_flag = EXT2_FLAG_RW;
3839e657
TT
147 break;
148 case 'e':
149 if (strcmp (optarg, "continue") == 0)
150 errors = EXT2_ERRORS_CONTINUE;
151 else if (strcmp (optarg, "remount-ro") == 0)
152 errors = EXT2_ERRORS_RO;
153 else if (strcmp (optarg, "panic") == 0)
154 errors = EXT2_ERRORS_PANIC;
155 else
156 {
157 com_err (program_name, 0,
158 "bad error behavior - %s",
159 optarg);
160 usage ();
161 }
162 e_flag = 1;
1e3472c5 163 open_flag = EXT2_FLAG_RW;
3839e657 164 break;
f3db3566
TT
165 case 'g':
166 resgid = strtoul (optarg, &tmp, 0);
167 if (*tmp)
168 {
169 gr = getgrnam (optarg);
170 if (gr == NULL)
171 tmp = optarg;
a418d3ad 172 else {
f3db3566 173 resgid = gr->gr_gid;
a418d3ad
TT
174 *tmp =0;
175 }
f3db3566
TT
176 }
177 if (*tmp)
178 {
179 com_err (program_name, 0,
180 "bad gid/group name - %s",
181 optarg);
182 usage ();
183 }
184 g_flag = 1;
1e3472c5 185 open_flag = EXT2_FLAG_RW;
f3db3566 186 break;
3839e657
TT
187 case 'i':
188 interval = strtoul (optarg, &tmp, 0);
1e3472c5
TT
189 switch (*tmp) {
190 case 's':
191 tmp++;
192 break;
193 case '\0':
194 case 'd':
195 case 'D': /* days */
196 interval *= 86400;
197 if (*tmp != '\0')
f3db3566 198 tmp++;
1e3472c5
TT
199 break;
200 case 'm':
201 case 'M': /* months! */
202 interval *= 86400 * 30;
203 tmp++;
204 break;
205 case 'w':
206 case 'W': /* weeks */
207 interval *= 86400 * 7;
208 tmp++;
209 break;
3839e657
TT
210 }
211 if (*tmp || interval > (365 * 86400))
212 {
213 com_err (program_name, 0,
214 "bad interval - %s", optarg);
215 usage ();
216 }
217 i_flag = 1;
1e3472c5 218 open_flag = EXT2_FLAG_RW;
3839e657
TT
219 break;
220 case 'l':
221 l_flag = 1;
222 break;
1e3472c5
TT
223 case 'L':
224 new_label = optarg;
225 L_flag = 1;
226 open_flag = EXT2_FLAG_RW;
227 break;
3839e657
TT
228 case 'm':
229 reserved_ratio = strtoul (optarg, &tmp, 0);
230 if (*tmp || reserved_ratio > 50)
231 {
232 com_err (program_name, 0,
233 "bad reserved block ratio - %s",
234 optarg);
235 usage ();
236 }
237 m_flag = 1;
1e3472c5
TT
238 open_flag = EXT2_FLAG_RW;
239 break;
240 case 'M':
241 new_last_mounted = optarg;
242 M_flag = 1;
243 open_flag = EXT2_FLAG_RW;
3839e657 244 break;
f3db3566
TT
245 case 'r':
246 reserved_blocks = strtoul (optarg, &tmp, 0);
247 if (*tmp)
248 {
249 com_err (program_name, 0,
250 "bad reserved blocks count - %s",
251 optarg);
252 usage ();
253 }
254 r_flag = 1;
1e3472c5 255 open_flag = EXT2_FLAG_RW;
f3db3566 256 break;
521e3685
TT
257 case 's':
258 s_flag = atoi(optarg);
259 open_flag = EXT2_FLAG_RW;
260 break;
f3db3566
TT
261 case 'u':
262 resuid = strtoul (optarg, &tmp, 0);
263 if (*tmp)
264 {
265 pw = getpwnam (optarg);
266 if (pw == NULL)
267 tmp = optarg;
a418d3ad 268 else {
f3db3566 269 resuid = pw->pw_uid;
a418d3ad
TT
270 *tmp = 0;
271 }
f3db3566
TT
272 }
273 if (*tmp)
274 {
275 com_err (program_name, 0,
276 "bad uid/user name - %s",
277 optarg);
278 usage ();
279 }
280 u_flag = 1;
1e3472c5
TT
281 open_flag = EXT2_FLAG_RW;
282 break;
283 case 'U':
284 new_UUID = optarg;
285 U_flag = 1;
286 open_flag = EXT2_FLAG_RW;
f3db3566 287 break;
3839e657
TT
288 default:
289 usage ();
290 }
291 if (optind < argc - 1 || optind == argc)
292 usage ();
1e3472c5
TT
293 if (!open_flag && !l_flag)
294 usage();
3839e657 295 device_name = argv[optind];
1e3472c5
TT
296 retval = ext2fs_open (device_name, open_flag, 0, 0,
297 unix_io_manager, &fs);
3839e657
TT
298 if (retval)
299 {
300 com_err (program_name, retval, "while trying to open %s",
301 device_name);
302 printf("Couldn't find valid filesystem superblock.\n");
303 exit(1);
304 }
1e3472c5 305 sb = (struct ext2fs_sb *) fs->super;
3839e657 306
1e3472c5 307 if (c_flag) {
3839e657
TT
308 fs->super->s_max_mnt_count = max_mount_count;
309 ext2fs_mark_super_dirty(fs);
1e3472c5
TT
310 printf ("Setting maximal mount count to %d\n",
311 max_mount_count);
3839e657 312 }
1e3472c5
TT
313 if (C_flag) {
314 fs->super->s_mnt_count = mount_count;
315 ext2fs_mark_super_dirty(fs);
316 printf ("Setting current mount count to %d\n", mount_count);
317 }
318 if (e_flag) {
3839e657
TT
319 fs->super->s_errors = errors;
320 ext2fs_mark_super_dirty(fs);
321 printf ("Setting error behavior to %d\n", errors);
322 }
f3db3566
TT
323 if (g_flag)
324#ifdef EXT2_DEF_RESGID
325 {
326 fs->super->s_def_resgid = resgid;
327 ext2fs_mark_super_dirty(fs);
328 printf ("Setting reserved blocks gid to %lu\n", resgid);
329 }
330#else
331 com_err (program_name, 0,
332 "The -g option is not supported by this version -- "
333 "Recompile with a newer kernel");
334#endif
3839e657
TT
335 if (i_flag)
336 {
337 fs->super->s_checkinterval = interval;
338 ext2fs_mark_super_dirty(fs);
339 printf ("Setting interval between check %lu seconds\n", interval);
340 }
341 if (m_flag)
342 {
343 fs->super->s_r_blocks_count = (fs->super->s_blocks_count / 100)
344 * reserved_ratio;
345 ext2fs_mark_super_dirty(fs);
1e3472c5 346 printf ("Setting reserved blocks percentage to %lu (%u blocks)\n",
3839e657
TT
347 reserved_ratio, fs->super->s_r_blocks_count);
348 }
f3db3566
TT
349 if (r_flag)
350 {
351 if (reserved_blocks >= fs->super->s_blocks_count)
352 {
353 com_err (program_name, 0,
354 "reserved blocks count is too big (%ul)",
355 reserved_blocks);
356 exit (1);
357 }
358 fs->super->s_r_blocks_count = reserved_blocks;
359 ext2fs_mark_super_dirty(fs);
360 printf ("Setting reserved blocks count to %lu\n",
361 reserved_blocks);
362 }
521e3685
TT
363 if (s_flag == 1) {
364#ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
365 if (sb->s_feature_ro_compat &
366 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
367 fprintf(stderr, "\nThe filesystem already "
368 " has spare superblocks.\n");
369 else {
370 sb->s_feature_ro_compat |=
371 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
372 fs->super->s_state &= ~EXT2_VALID_FS;
373 ext2fs_mark_super_dirty(fs);
374 printf("\nSparse superblock flag set. "
375 "Please run e2fsck on the filesystem.\n");
376 }
377#else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
378 com_err (program_name, 0,
379 "The -s option is not supported by this version -- "
380 "Recompile with a newer kernel");
381#endif /* EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
382 }
383 if (s_flag == 0) {
384#ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
385 if (!(sb->s_feature_ro_compat &
386 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
387 fprintf(stderr, "\nThe filesystem already "
388 " does not support spare superblocks.\n");
389 else {
390 sb->s_feature_ro_compat &=
391 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
392 fs->super->s_state &= ~EXT2_VALID_FS;
393 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
394 ext2fs_mark_super_dirty(fs);
395 printf("\nSparse superblock flag cleared. "
396 "Please run e2fsck on the filesystem.\n");
397 }
398#else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
399 com_err (program_name, 0,
400 "The -s option is not supported by this version -- "
401 "Recompile with a newer kernel");
402#endif /* EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
403 }
404
f3db3566
TT
405 if (u_flag)
406#ifdef EXT2_DEF_RESUID
407 {
408 fs->super->s_def_resuid = resuid;
409 ext2fs_mark_super_dirty(fs);
410 printf ("Setting reserved blocks uid to %lu\n", resuid);
411 }
412#else
413 com_err (program_name, 0,
414 "The -u option is not supported by this version -- "
415 "Recompile with a newer kernel");
416#endif
1e3472c5
TT
417 if (L_flag) {
418 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
419 strncpy(sb->s_volume_name, new_label,
420 sizeof(sb->s_volume_name));
421 ext2fs_mark_super_dirty(fs);
422 }
423 if (M_flag) {
424 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
425 strncpy(sb->s_last_mounted, new_last_mounted,
426 sizeof(sb->s_last_mounted));
427 ext2fs_mark_super_dirty(fs);
428 }
429 if (U_flag) {
430 if (strcasecmp(new_UUID, "null") == 0) {
431 uuid_clear(sb->s_uuid);
432 } else if (strcasecmp(new_UUID, "random") == 0) {
433 uuid_generate(sb->s_uuid);
434 } else if (uuid_parse(new_UUID, sb->s_uuid)) {
435 com_err(program_name, 0, "Invalid UUID format\n");
436 exit(1);
437 }
438 ext2fs_mark_super_dirty(fs);
439 }
440
3839e657
TT
441 if (l_flag)
442 list_super (fs->super);
443 ext2fs_close (fs);
444 exit (0);
445}