View | Details | Raw Unified | Return to bug 630434
Collapse All | Expand All

(-)sysconfig-0.71.30/tools/udevmountd.c (-40 / +109 lines)
Lines 24-29 Link Here
24
#include <unistd.h>
24
#include <unistd.h>
25
#include <fcntl.h>
25
#include <fcntl.h>
26
#include <string.h>
26
#include <string.h>
27
#include <dirent.h>
27
#include <sys/types.h>
28
#include <sys/types.h>
28
#include <sys/stat.h>
29
#include <sys/stat.h>
29
#include <sys/wait.h>
30
#include <sys/wait.h>
Lines 63-74 char *mount_status_str[] = { Link Here
63
#ifdef TEST
64
#ifdef TEST
64
#define DEFAULT_LOGLEVEL LOG_DEBUG
65
#define DEFAULT_LOGLEVEL LOG_DEBUG
65
#else
66
#else
66
#define DEFAULT_LOGLEVEL LOG_ERR
67
#define DEFAULT_LOGLEVEL LOG_DEBUG
67
#endif
68
#endif
68
69
69
/* How log to wait for the background process to terminate */
70
/* How log to wait for the background process to terminate */
70
#define SIGNAL_TIMEOUT 10
71
#define SIGNAL_TIMEOUT 10
71
72
73
/* Multipath daemon program */
74
#define MPATHD_PROG "/sbin/multipathd"
75
72
/* Fsck program to call */
76
/* Fsck program to call */
73
#ifdef TEST
77
#ifdef TEST
74
#define FSCK_PROG "./fsck_test"
78
#define FSCK_PROG "./fsck_test"
Lines 84-89 char *mount_status_str[] = { Link Here
84
88
85
static char *dev;
89
static char *dev;
86
static char *mnt;
90
static char *mnt;
91
static char *action;
87
static int major;
92
static int major;
88
static int minor;
93
static int minor;
89
static unsigned int passno;
94
static unsigned int passno;
Lines 144-150 static void terminate_child(int signo) Link Here
144
 *
149
 *
145
 * Copied from udev.
150
 * Copied from udev.
146
 */
151
 */
147
static int run_program(char **argv)
152
static int run_program(char **argv, char *buf, int len)
148
{
153
{
149
	int status;
154
	int status;
150
	int outpipe[2] = {-1, -1};
155
	int outpipe[2] = {-1, -1};
Lines 212-217 static int run_program(char **argv) Link Here
212
		err("fork of '%s' failed: %s\n", argv[0], strerror(errno));
217
		err("fork of '%s' failed: %s\n", argv[0], strerror(errno));
213
		return -1;
218
		return -1;
214
	default:
219
	default:
220
		if (buf)
221
			buf[0] = '\0';
215
		/* read from child if requested */
222
		/* read from child if requested */
216
		if (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) {
223
		if (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) {
217
			ssize_t count;
224
			ssize_t count;
Lines 270-275 static int run_program(char **argv) Link Here
270
					inbuf[count] = '\0';
277
					inbuf[count] = '\0';
271
278
272
					pos = inbuf;
279
					pos = inbuf;
280
					if (buf)
281
						strncpy(buf, inbuf, len);
273
					while ((line = strsep(&pos, "\n")))
282
					while ((line = strsep(&pos, "\n")))
274
						if (pos && line[0] != '\0')
283
						if (pos && line[0] != '\0')
275
							warn("%s\n", line);
284
							warn("%s\n", line);
Lines 325-330 static int run_program(char **argv) Link Here
325
}
334
}
326
335
327
/*
336
/*
337
 * check_dev - Check if the device number matches
338
 *
339
 * Check if the device number of the event matches with the
340
 * device number of the device node and if the device does not
341
 * has any 'holders' in /sys/block/XX. If not than we can
342
 * discard this event.
343
 */
344
int check_dev(void)
345
{
346
	struct stat stbuf;
347
	char buf[256];
348
	DIR *dirfd;
349
	struct dirent *dp;
350
351
	if (stat(dev, &stbuf) < 0) {
352
		fprintf(stderr,"Cannot stat '%s': %d\n", dev, errno);
353
		return -ENODEV;
354
	}
355
356
	if (!S_ISBLK(stbuf.st_mode)) {
357
		fprintf(stderr,"Not a block device\n");
358
		return -ENOTBLK;
359
	}
360
	sprintf(buf,"/sys/dev/block/%d:%d/holders", major, minor);
361
	dirfd = opendir(buf);
362
	/* Can happen during remove, not an error */
363
	if (!dirfd)
364
		return 0;
365
	while ((dp = readdir(dirfd)) != NULL) {
366
		if (!strcmp(dp->d_name,".") || !strcmp(dp->d_name, ".."))
367
			continue;
368
		fprintf(stderr, "Device %d:%d claimed by %s\n",
369
			major, minor, dp->d_name);
370
		closedir(dirfd);
371
		return -EBUSY;
372
	}
373
	closedir(dirfd);
374
375
	return 0;
376
}
377
378
/*
328
 * run_fsck - Run fsck and mount
379
 * run_fsck - Run fsck and mount
329
 *
380
 *
330
 * Get an exclusive lock on the lock file and call
381
 * Get an exclusive lock on the lock file and call
Lines 335-341 static int run_program(char **argv) Link Here
335
int run_fsck(char *fstype, char *fsopts)
386
int run_fsck(char *fstype, char *fsopts)
336
{
387
{
337
	struct flock lock;
388
	struct flock lock;
338
	char buf[256];
389
	char buf[32];
390
	char argbuf[32];
339
	char *argv[9];
391
	char *argv[9];
340
	mount_status status = MOUNT_UNCHECKED;
392
	mount_status status = MOUNT_UNCHECKED;
341
	int rc, i, num;
393
	int rc, i, num;
Lines 357-369 int run_fsck(char *fstype, char *fsopts) Link Here
357
		return errno;
409
		return errno;
358
	}
410
	}
359
411
412
	/* Check for multipathing */
413
	info("Check for multipath on '%s'\n", dev);
414
415
	memset(buf,0x0,32);
416
	strcpy(buf,"waiting");
417
	num = write(lock_fd, buf, 32);
418
419
	sprintf(argbuf,"-kshow daemon");
420
	argv[0] = MPATHD_PROG;
421
	argv[1] = argbuf;
422
	argv[2] = NULL;
423
424
	rc = run_program(argv, argbuf, 32);
425
	if (rc < 0) {
426
		status = MOUNT_FAILED;
427
	} else {
428
		if (strlen(argbuf) > 3 && !strncmp(argbuf,"pid", 3)) {
429
			/*
430
			 * If multipath is running, it will notify us
431
			 * again via the 'change' event.
432
			 * No action required at this point.
433
			 */
434
			if (!strncmp(action, "add", 3)) {
435
				status = MOUNT_SKIPPED;
436
				goto out_unlock;
437
			}
438
		}
439
	}
440
360
	if (passno == 0)
441
	if (passno == 0)
361
		goto skip_fsck;
442
		goto skip_fsck;
362
443
363
	info("Starting fsck on '%s'\n", dev);
444
	info("Starting fsck on '%s'\n", dev);
364
445
446
	memset(buf, 0x0, 32);
365
	strcpy(buf,"checking");
447
	strcpy(buf,"checking");
366
	num = write(lock_fd, buf, 20);
448
	num = write(lock_fd, buf, 32);
367
449
368
	argv[0] = FSCK_PROG;
450
	argv[0] = FSCK_PROG;
369
	argv[1] = "-p";
451
	argv[1] = "-p";
Lines 379-385 int run_fsck(char *fstype, char *fsopts) Link Here
379
	i++;
461
	i++;
380
	argv[i] = NULL;
462
	argv[i] = NULL;
381
463
382
	rc = run_program(argv);
464
	rc = run_program(argv, NULL, 0);
383
	if (rc < 0) {
465
	if (rc < 0) {
384
		status = MOUNT_FAILED;
466
		status = MOUNT_FAILED;
385
	} else {
467
	} else {
Lines 407-415 int run_fsck(char *fstype, char *fsopts) Link Here
407
skip_fsck:
489
skip_fsck:
408
	info("Mounting dev '%s' on '%s'\n", dev, mnt);
490
	info("Mounting dev '%s' on '%s'\n", dev, mnt);
409
491
492
	memset(buf, 0x0, 32);
410
	strcpy(buf, "mounting");
493
	strcpy(buf, "mounting");
411
	lseek(lock_fd, 0, SEEK_SET);
494
	lseek(lock_fd, 0, SEEK_SET);
412
	num = write(lock_fd, buf, 20);
495
	num = write(lock_fd, buf, 32);
413
496
414
	argv[0] = MOUNT_PROG;
497
	argv[0] = MOUNT_PROG;
415
	i = 1;
498
	i = 1;
Lines 431-446 skip_fsck: Link Here
431
	i++;
514
	i++;
432
	argv[i] = NULL;
515
	argv[i] = NULL;
433
516
434
	rc = run_program(argv);
517
	rc = run_program(argv, NULL, 0);
435
	if (rc == 0)
518
	if (rc == 0)
436
		status = MOUNT_MOUNTED;
519
		status = MOUNT_MOUNTED;
437
520
438
	info("mount done (%d), status %s\n", rc, mount_status_str[status]);
521
	info("mount done (%d), status %s\n", rc, mount_status_str[status]);
439
522
440
out_unlock:
523
out_unlock:
524
	memset(buf, 0x0, 32);
441
	strcpy(buf,mount_status_str[status]);
525
	strcpy(buf,mount_status_str[status]);
442
	lseek(lock_fd, 0, SEEK_SET);
526
	lseek(lock_fd, 0, SEEK_SET);
443
	num = write(lock_fd, buf, 20);
527
	num = write(lock_fd, buf, 32);
444
528
445
	lock.l_type = F_UNLCK;
529
	lock.l_type = F_UNLCK;
446
	lock.l_start = 0;
530
	lock.l_start = 0;
Lines 504-510 int daemonize_fsck(char *fstype, char *f Link Here
504
		fd = open("/dev/null", O_RDWR);
588
		fd = open("/dev/null", O_RDWR);
505
		fd = dup(0);
589
		fd = dup(0);
506
		fd = dup(0);
590
		fd = dup(0);
507
		openlog("udev.mountd", LOG_CONS, LOG_DAEMON);
591
		openlog("udev.mountd", 0, LOG_DAEMON);
508
		run_fsck(fstype, fsopts);
592
		run_fsck(fstype, fsopts);
509
		closelog();
593
		closelog();
510
		exit(0);
594
		exit(0);
Lines 590-625 int remove_lock(void) Link Here
590
}
674
}
591
675
592
/*
676
/*
593
 * check_dev - Check if the device number matches
594
 *
595
 * Check if the device number of the event matches with the
596
 * device number of the device node. If not than we can
597
 * discard this event.
598
 */
599
int check_dev(void)
600
{
601
	struct stat stbuf;
602
603
	if (stat(dev, &stbuf) < 0) {
604
		fprintf(stderr,"Cannot stat '%s': %d\n", dev, errno);
605
		return -ENODEV;
606
	}
607
608
	if (!S_ISBLK(stbuf.st_mode)) {
609
		fprintf(stderr,"Not a block device\n");
610
		return -ENOTBLK;
611
	}
612
613
	if (stbuf.st_rdev != makedev(major,minor)) {
614
		fprintf(stdout, "Invalid device (fstab %d:%d, event %d:%d)\n",
615
			major(stbuf.st_rdev), minor(stbuf.st_rdev),
616
			major, minor);
617
		return -EINVAL;
618
	}
619
	return 0;
620
}
621
622
/*
623
 * check_mnt - Check if the device is mounted
677
 * check_mnt - Check if the device is mounted
624
 *
678
 *
625
 * Compare the device number from the event
679
 * Compare the device number from the event
Lines 698-703 int main(int argc, char **argv, char **e Link Here
698
	/* Scan environment */
752
	/* Scan environment */
699
	while (envp && *envp) {
753
	while (envp && *envp) {
700
		ep = *envp;
754
		ep = *envp;
755
		if (!strncmp(ep, "ACTION", 6) && strlen(ep) > 7) {
756
			action = malloc(strlen(ep + 7) + 1);
757
			if (!action)
758
				return ENOMEM;
759
			strcpy(action, ep + 7);
760
		}
701
		if (!strncmp(ep, "MAJOR", 5) && strlen(ep) > 6) {
761
		if (!strncmp(ep, "MAJOR", 5) && strlen(ep) > 6) {
702
			major = strtoul(ep + 6, &ptr, 10);
762
			major = strtoul(ep + 6, &ptr, 10);
703
			if (ptr == ep + 6) {
763
			if (ptr == ep + 6) {
Lines 788-801 int main(int argc, char **argv, char **e Link Here
788
			fprintf(stdout,"FSCK_STATE=unknown\n");
848
			fprintf(stdout,"FSCK_STATE=unknown\n");
789
			return 0;
849
			return 0;
790
		}
850
		}
851
		if (err == -ENOENT && op == MOUNT_REMOVE)
852
			goto skip_mount;
853
791
		return -err;
854
		return -err;
792
	}
855
	}
793
856
794
	/* Check if the device is mounted */
857
	/* Check if the device is mounted */
795
	err = check_mnt();
858
	err = check_mnt();
796
	if (err < 0)
859
	if (err < 0) {
860
		if (err == -EINVAL && op == MOUNT_FSCK) {
861
			fprintf(stdout,"FSCK_STATE=skipped\n");
862
			return 0;
863
		}
797
		return EINVAL;
864
		return EINVAL;
865
	}
798
866
867
skip_mount:
799
	/* The real action */
868
	/* The real action */
800
	if (op == MOUNT_FSCK) {
869
	if (op == MOUNT_FSCK) {
801
		if (err == 0) {
870
		if (err == 0) {
(-)sysconfig-0.71.30/config/hardware/81-mount.rules (-3 / +1 lines)
Lines 5-13 ACTION=="add", SUBSYSTEM=="block", KERNE Link Here
5
ACTION=="add", SUBSYSTEM=="block", KERNEL=="md*", GOTO="skip_mount"
5
ACTION=="add", SUBSYSTEM=="block", KERNEL=="md*", GOTO="skip_mount"
6
# don't handle crypto devices, boot.crypto does that already (bnc#569942)
6
# don't handle crypto devices, boot.crypto does that already (bnc#569942)
7
ACTION=="change", SUBSYSTEM=="block", KERNEL=="dm-*", ENV{DM_TARGET_TYPES}=="crypt", GOTO="skip_mount"
7
ACTION=="change", SUBSYSTEM=="block", KERNEL=="dm-*", ENV{DM_TARGET_TYPES}=="crypt", GOTO="skip_mount"
8
ACTION=="add", SUBSYSTEM=="block", ENV{FSTAB_OPTS}=="*nofail*", IMPORT="udevmountd"
8
ACTION=="add|change", SUBSYSTEM=="block", ENV{FSTAB_OPTS}=="*nofail*", IMPORT="udevmountd"
9
ACTION=="change", SUBSYSTEM=="block", KERNEL=="dm-*", ENV{FSTAB_OPTS}=="*nofail*", IMPORT="udevmountd"
10
ACTION=="change", SUBSYSTEM=="block", KERNEL=="md*", ENV{FSTAB_OPTS}=="*nofail*", IMPORT="udevmountd"
11
9
12
ACTION=="add|change", ENV{FSCK_STATE}=="unknown|clean", RUN+="udevmountd add"
10
ACTION=="add|change", ENV{FSCK_STATE}=="unknown|clean", RUN+="udevmountd add"
13
ACTION=="remove", ENV{FSTAB_OPTS}=="*nofail*", RUN+="udevmountd remove"
11
ACTION=="remove", ENV{FSTAB_OPTS}=="*nofail*", RUN+="udevmountd remove"

Return to bug 630434