Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 318365 | Differences between
and this patch

Collapse All | Expand All

(-)a/fsck/fsck.8 (-1 / +12 lines)
Lines 7-13 Link Here
7
fsck \- check and repair a Linux file system
7
fsck \- check and repair a Linux file system
8
.SH SYNOPSIS
8
.SH SYNOPSIS
9
.B fsck
9
.B fsck
10
.RB [ \-sAVRTMNP ]
10
.RB [ \-lsAVRTMNP ]
11
.RB [ \-C
11
.RB [ \-C
12
.RI [ fd ]]
12
.RI [ fd ]]
13
.RB [ \-t
13
.RB [ \-t
Lines 80-85 variable. Please see the file system-specific checker manual pages for Link Here
80
further details.
80
further details.
81
.SH OPTIONS
81
.SH OPTIONS
82
.TP
82
.TP
83
.B \-l
84
Lock whole-disk device by exclusive
85
.BR flock (2).
86
This option can be used with one device only (e.g. -A and -l are mutually
87
exclusive). This option is recommended when more
88
.B fsck (8)
89
instances are executed in the same time. The option is ignored when used for
90
multiple devices or for non-rotating disk. The fsck does not lock underlying
91
devices if executed to check stacked devices (e.g. MD or DM) -- this feature is
92
not implemented yet.
93
.TP
83
.B \-s
94
.B \-s
84
Serialize
95
Serialize
85
.B fsck
96
.B fsck
(-)a/fsck/fsck.c (-41 / +179 lines)
Lines 31-36 Link Here
31
#include <sys/wait.h>
31
#include <sys/wait.h>
32
#include <sys/signal.h>
32
#include <sys/signal.h>
33
#include <sys/stat.h>
33
#include <sys/stat.h>
34
#include <sys/file.h>
35
#include <fcntl.h>
34
#include <limits.h>
36
#include <limits.h>
35
#include <stdio.h>
37
#include <stdio.h>
36
#include <ctype.h>
38
#include <ctype.h>
Lines 42-47 Link Here
42
#include <errno.h>
44
#include <errno.h>
43
#include <malloc.h>
45
#include <malloc.h>
44
#include <signal.h>
46
#include <signal.h>
47
#include <dirent.h>
48
#include <blkid.h>
45
49
46
#include "fsprobe.h"
50
#include "fsprobe.h"
47
51
Lines 85-90 char *devices[MAX_DEVICES]; Link Here
85
char *args[MAX_ARGS];
89
char *args[MAX_ARGS];
86
int num_devices, num_args;
90
int num_devices, num_args;
87
91
92
int lockdisk = 0;
88
int verbose = 0;
93
int verbose = 0;
89
int doall = 0;
94
int doall = 0;
90
int noexecute = 0;
95
int noexecute = 0;
Lines 214-223 static void parse_escape(char *word) Link Here
214
	*q = 0;
219
	*q = 0;
215
}
220
}
216
221
222
static dev_t get_disk(const char *device)
223
{
224
	 struct stat st;
225
	 dev_t disk;
226
227
	 if (!stat(device, &st) &&
228
	     !blkid_devno_to_wholedisk(st.st_rdev, NULL, 0, &disk))
229
		 return disk;
230
231
	 return 0;
232
}
233
234
static int is_irrotational_disk(dev_t disk)
235
{
236
	 char path[PATH_MAX];
237
	 FILE *f;
238
	 int rc, x;
239
240
	 rc = snprintf(path, sizeof(path),
241
			 "/sys/dev/block/%d:%d/queue/rotational",
242
			 major(disk), minor(disk));
243
244
	 if (rc < 0 || rc + 1 > sizeof(path))
245
		 return 0;
246
247
	 f = fopen(path, "r");
248
	 if (!f)
249
		 return 0;
250
251
	 rc = fscanf(f, "%u", &x);
252
	 fclose(f);
253
254
	 return rc == 1 ? !x : 0;
255
}
256
257
static void lock_disk(struct fsck_instance *inst)
258
{
259
	 dev_t disk = inst->fs->disk ? : get_disk(inst->fs->device);
260
	 char *diskname;
261
262
	 if (!disk || is_irrotational_disk(disk))
263
		 return;
264
265
	 diskname = blkid_devno_to_devname(disk);
266
	 if (!diskname)
267
		 return;
268
269
	 if (verbose)
270
		 printf(_("Locking disk %s ... "), diskname);
271
272
	 inst->lock = open(diskname, O_CLOEXEC | O_RDONLY);
273
	 if (inst->lock >= 0) {
274
		 int rc = -1;
275
276
		 /* inform users that we're waiting on the lock */
277
		 if (verbose &&
278
		     (rc = flock(inst->lock, LOCK_EX | LOCK_NB)) != 0 &&
279
		     errno == EWOULDBLOCK)
280
			 printf(_("(waiting) "));
281
282
		 if (rc != 0 && flock(inst->lock, LOCK_EX) != 0) {
283
			 close(inst->lock);                      /* failed */
284
			 inst->lock = -1;
285
		 }
286
	 }
287
288
	 if (verbose)
289
		 printf("%s.\n", inst->lock >= 0 ? _("success") : _("failed"));
290
291
	 free(diskname);
292
	 return;
293
}
294
295
static void unlock_disk(struct fsck_instance *inst)
296
{
297
	 if (inst->lock >= 0) {
298
		 /* explicitly unlock, don't rely on close(), maybe some library
299
		  * (e.g. liblkid) has still open the device.
300
		  */
301
		 flock(inst->lock, LOCK_UN);
302
		 close(inst->lock);
303
	 }
304
}
305
217
static void free_instance(struct fsck_instance *i)
306
static void free_instance(struct fsck_instance *i)
218
{
307
{
308
	if (lockdisk)
309
		unlock_disk(i);
310
219
	free(i->prog);
311
	free(i->prog);
220
	free(i->device);
221
	free(i->base_device);
312
	free(i->base_device);
222
	free(i);
313
	free(i);
223
	return;
314
	return;
Lines 240-245 static struct fs_info *create_fs_device(const char *device, const char *mntpnt, Link Here
240
	fs->passno = passno;
331
	fs->passno = passno;
241
	fs->flags = 0;
332
	fs->flags = 0;
242
	fs->next = NULL;
333
	fs->next = NULL;
334
	fs->disk = 0;
335
	fs->stacked = 0;
243
336
244
	if (!filesys_info)
337
	if (!filesys_info)
245
		filesys_info = fs;
338
		filesys_info = fs;
Lines 414-421 static int progress_active(NOARGS) Link Here
414
 * Execute a particular fsck program, and link it into the list of
507
 * Execute a particular fsck program, and link it into the list of
415
 * child processes we are waiting for.
508
 * child processes we are waiting for.
416
 */
509
 */
417
static int execute(const char *type, const char *device, const char *mntpt,
510
static int execute(const char *type, struct fs_info *fs, int interactive)
418
		   int interactive)
419
{
511
{
420
	char *s, *argv[80], prog[80];
512
	char *s, *argv[80], prog[80];
421
	int  argc, i;
513
	int  argc, i;
Lines 452-458 static int execute(const char *type, const char *device, const char *mntpt, Link Here
452
		}
544
		}
453
	}
545
	}
454
546
455
	argv[argc++] = string_copy(device);
547
	argv[argc++] = string_copy(fs->device);
456
	argv[argc] = 0;
548
	argv[argc] = 0;
457
549
458
	s = find_fsck(prog);
550
	s = find_fsck(prog);
Lines 464-475 static int execute(const char *type, const char *device, const char *mntpt, Link Here
464
556
465
	if (verbose || noexecute) {
557
	if (verbose || noexecute) {
466
		printf("[%s (%d) -- %s] ", s, num_running,
558
		printf("[%s (%d) -- %s] ", s, num_running,
467
		       mntpt ? mntpt : device);
559
		       fs->mountpt ? : fs->device);
468
		for (i=0; i < argc; i++)
560
		for (i=0; i < argc; i++)
469
			printf("%s ", argv[i]);
561
			printf("%s ", argv[i]);
470
		printf("\n");
562
		printf("\n");
471
	}
563
	}
472
564
565
566
	inst->fs = fs;
567
	inst->lock = -1;
568
569
	if (lockdisk)
570
		lock_disk(inst);
571
572
473
	/* Fork and execute the correct program. */
573
	/* Fork and execute the correct program. */
474
	if (noexecute)
574
	if (noexecute)
475
		pid = -1;
575
		pid = -1;
Lines 492-499 static int execute(const char *type, const char *device, const char *mntpt, Link Here
492
	inst->pid = pid;
592
	inst->pid = pid;
493
	inst->prog = string_copy(prog);
593
	inst->prog = string_copy(prog);
494
	inst->type = string_copy(type);
594
	inst->type = string_copy(type);
495
	inst->device = string_copy(device);
595
	inst->base_device = base_device(fs->device);
496
	inst->base_device = base_device(device);
497
	inst->start_time = time(0);
596
	inst->start_time = time(0);
498
	inst->next = NULL;
597
	inst->next = NULL;
499
598
Lines 597-608 static struct fsck_instance *wait_one(int flags) Link Here
597
		} else {
696
		} else {
598
			printf(_("Warning... %s for device %s exited "
697
			printf(_("Warning... %s for device %s exited "
599
			       "with signal %d.\n"),
698
			       "with signal %d.\n"),
600
			       inst->prog, inst->device, sig);
699
			       inst->prog, inst->fs->device, sig);
601
			status = EXIT_ERROR;
700
			status = EXIT_ERROR;
602
		}
701
		}
603
	} else {
702
	} else {
604
		printf(_("%s %s: status is %x, should never happen.\n"),
703
		printf(_("%s %s: status is %x, should never happen.\n"),
605
		       inst->prog, inst->device, status);
704
		       inst->prog, inst->fs->device, status);
606
		status = EXIT_ERROR;
705
		status = EXIT_ERROR;
607
	}
706
	}
608
	inst->exit_status = status;
707
	inst->exit_status = status;
Lines 641-647 ret_inst: Link Here
641
		instance_list = inst->next;
740
		instance_list = inst->next;
642
	if (verbose > 1)
741
	if (verbose > 1)
643
		printf(_("Finished with %s (exit status %d)\n"),
742
		printf(_("Finished with %s (exit status %d)\n"),
644
		       inst->device, inst->exit_status);
743
		       inst->fs->device, inst->exit_status);
645
	num_running--;
744
	num_running--;
646
	return inst;
745
	return inst;
647
}
746
}
Lines 698-704 static void fsck_device(struct fs_info *fs, int interactive) Link Here
698
		type = DEFAULT_FSTYPE;
797
		type = DEFAULT_FSTYPE;
699
798
700
	num_running++;
799
	num_running++;
701
	retval = execute(type, fs->device, fs->mountpt, interactive);
800
	retval = execute(type, fs, interactive);
702
	if (retval) {
801
	if (retval) {
703
		fprintf(stderr, _("%s: Error %d while executing fsck.%s "
802
		fprintf(stderr, _("%s: Error %d while executing fsck.%s "
704
			"for %s\n"), progname, retval, type, fs->device);
803
			"for %s\n"), progname, retval, type, fs->device);
Lines 924-964 static int ignore(struct fs_info *fs) Link Here
924
	return 0;
1023
	return 0;
925
}
1024
}
926
1025
927
/*
1026
static int count_slaves(dev_t disk)
928
 * Returns TRUE if a partition on the same disk is already being
929
 * checked.
930
 */
931
static int device_already_active(char *device)
932
{
1027
{
933
	struct fsck_instance *inst;
1028
	DIR *dir;
934
	char *base;
1029
	struct dirent *dp;
1030
	char dirname[PATH_MAX];
1031
	int count = 0;
935
1032
936
	if (force_all_parallel)
1033
	snprintf(dirname, sizeof(dirname),
937
		return 0;
1034
			"/sys/dev/block/%u:%u/slaves/",
1035
			major(disk), minor(disk));
938
1036
939
#ifdef BASE_MD
1037
	if (!(dir = opendir(dirname)))
940
	/* Don't check a soft raid disk with any other disk */
1038
		return -1;
941
	if (instance_list &&
1039
942
	    (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) ||
1040
	while ((dp = readdir(dir)) != 0) {
943
	     !strncmp(device, BASE_MD, sizeof(BASE_MD)-1)))
1041
#ifdef _DIRENT_HAVE_D_TYPE
944
		return 1;
1042
		if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
1043
			continue;
945
#endif
1044
#endif
1045
		if (dp->d_name[0] == '.' &&
1046
		    ((dp->d_name[1] == 0) ||
1047
		     ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
1048
			continue;
946
1049
947
	base = base_device(device);
1050
		count++;
948
	/*
949
	 * If we don't know the base device, assume that the device is
950
	 * already active if there are any fsck instances running.
951
	 */
952
	if (!base)
953
		return (instance_list != 0);
954
	for (inst = instance_list; inst; inst = inst->next) {
955
		if (!inst->base_device || !strcmp(base, inst->base_device)) {
956
			free(base);
957
			return 1;
958
		}
959
	}
1051
	}
960
	free(base);
1052
	closedir(dir);
961
	return 0;
1053
	return count;
1054
}
1055
1056
/*
1057
 * Returns TRUE if a partition on the same disk is already being
1058
 * checked.
1059
 */
1060
static int disk_already_active(struct fs_info *fs)
1061
{
1062
	  struct fsck_instance *inst;
1063
1064
	  if (force_all_parallel)
1065
		  return 0;
1066
1067
	  if (instance_list && instance_list->fs->stacked)
1068
		  /* any instance for a stacked device is already running */
1069
		  return 1;
1070
1071
	  if (!fs->disk) {
1072
		  fs->disk = get_disk(fs->device);
1073
		  if (fs->disk)
1074
			  fs->stacked = count_slaves(fs->disk);
1075
	  }
1076
1077
	  /*
1078
	   * If we don't know the base device, assume that the device is
1079
	   * already active if there are any fsck instances running.
1080
	   *
1081
	   * Don't check a stacked device with any other disk too.
1082
	   */
1083
	  if (!fs->disk || fs->stacked)
1084
		  return (instance_list != 0);
1085
1086
	  for (inst = instance_list; inst; inst = inst->next) {
1087
		  if (!inst->fs->disk || fs->disk == inst->fs->disk)
1088
			  return 1;
1089
	  }
1090
	  return 0;
962
}
1091
}
963
1092
964
/* Check all file systems, using the /etc/fstab table. */
1093
/* Check all file systems, using the /etc/fstab table. */
Lines 1038-1044 static int check_all(NOARGS) Link Here
1038
			 * already been spawned, then we need to defer
1167
			 * already been spawned, then we need to defer
1039
			 * this to another pass.
1168
			 * this to another pass.
1040
			 */
1169
			 */
1041
			if (device_already_active(fs->device)) {
1170
			if (disk_already_active(fs)) {
1042
				pass_done = 0;
1171
				pass_done = 0;
1043
				continue;
1172
				continue;
1044
			}
1173
			}
Lines 1188-1193 static void PRS(int argc, char *argv[]) Link Here
1188
					}
1317
					}
1189
				}
1318
				}
1190
				break;
1319
				break;
1320
			case 'l':
1321
				lockdisk++;
1322
				break;
1191
			case 'V':
1323
			case 'V':
1192
				verbose++;
1324
				verbose++;
1193
				break;
1325
				break;
Lines 1298-1303 int main(int argc, char *argv[]) Link Here
1298
	if ((num_devices == 1) || (serialize))
1430
	if ((num_devices == 1) || (serialize))
1299
		interactive = 1;
1431
		interactive = 1;
1300
1432
1433
	if (lockdisk && (doall || num_devices > 1)) {
1434
		fprintf(stderr, _("%s: the -l option can be used with one "
1435
			           "device only -- ignore\n"), progname);
1436
		lockdisk = 0;
1437
	}
1438
1301
	/* If -A was specified ("check all"), do that! */
1439
	/* If -A was specified ("check all"), do that! */
1302
	if (doall)
1440
	if (doall)
1303
		return check_all();
1441
		return check_all();
(-)a/fsck/fsck.h (-1 / +4 lines)
Lines 44-49 struct fs_info { Link Here
44
	int   freq;
44
	int   freq;
45
	int   passno;
45
	int   passno;
46
	int   flags;
46
	int   flags;
47
	dev_t disk;
48
	int   stacked;
47
	struct fs_info *next;
49
	struct fs_info *next;
48
};
50
};
49
51
Lines 56-67 struct fs_info { Link Here
56
struct fsck_instance {
58
struct fsck_instance {
57
	int	pid;
59
	int	pid;
58
	int	flags;
60
	int	flags;
61
	int     lock;           /* flock()ed whole disk file descriptor or -1 */
59
	int	exit_status;
62
	int	exit_status;
60
	time_t	start_time;
63
	time_t	start_time;
61
	char *	prog;
64
	char *	prog;
62
	char *	type;
65
	char *	type;
63
	char *	device;
64
	char *	base_device;
66
	char *	base_device;
67
	struct fs_info *fs;
65
	struct fsck_instance *next;
68
	struct fsck_instance *next;
66
};
69
};
67
70

Return to bug 318365