udevadm settle (udev 146) & pam-mount (1.32) via mount (util-linux-ng 2.16.1)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi there,

I'm trying to figure out some interaction between pam-mount and udev
which, for some time now, fail to log me in.

First of, the invocation:

+-login---mount---mount.crypto_LUKS---cryptsetup---udevadm

After the getty replaces itself with login the pam module pam_mount
calls mount. This in turn determines that the partition to be mounted is
LUKS encrypted, and calls cryptsetup. Cryptsetup receives the password,
unlocks the partition, and calls udevadm settle in order to avoid some
problems in interaction with LVM.

udevadm settle never returns.

strace reveals why:

rt_sigaction(SIGALRM, {0x40cf10, [], SA_RESTORER, 0x7f03082606d0}, NULL,
8) = 0
rt_sigaction(SIGUSR1, {0x40cf10, [], SA_RESTORER, 0x7f03082606d0}, NULL,
8) = 0
alarm(180)                              = 0
getuid()                                = 0
socket(PF_FILE, SOCK_DGRAM, 0)          = 4
rt_sigprocmask(SIG_BLOCK, [USR1 ALRM], ~[TRAP KILL SEGV STOP RTMIN
RT_1], 8) = 0
sendto(4,
"udev-146\0\0\0\0\0\0\0\0\352\35\255\336\10\0\0\0\0\0\0\0\0\0\0\0\0"...,
280, 0, {sa_family=AF_FILE, path=@"/org/kernel/udev/udevd"...}, 25) = 280
rt_sigsuspend(~[TRAP KILL SEGV STOP RTMIN RT_1] <unfinished ...>

and the code:

        /* guarantee that the udev daemon isn't pre-processing */
        if (getuid() == 0) {
                struct udev_ctrl *uctrl;

                uctrl = udev_ctrl_new_from_socket(udev,
UDEV_CTRL_SOCK_PATH);
                if (uctrl != NULL) {
                        sigset_t mask, oldmask;

                        sigemptyset(&mask);
                        sigaddset(&mask, SIGUSR1);
                        sigaddset(&mask, SIGALRM);
                        sigprocmask(SIG_BLOCK, &mask, &oldmask);
                        if (udev_ctrl_send_settle(uctrl) > 0)
                                sigsuspend(&oldmask);
                        sigprocmask(SIG_SETMASK, &oldmask, NULL);
                        udev_ctrl_unref(uctrl);
                }
        }

The problem here is that SIGUSR1 and SIGALRM are both blocked in oldmask
already, and never reach udevadm. No care is ever taken to ensure those
signals are not blocked.

The attached patch is one of the many possible ways to rectify the solution.

Regards,
Christian
diff -ur udev-146/udev/udevadm-settle.c udev-146.new/udev/udevadm-settle.c
--- udev-146/udev/udevadm-settle.c	2009-08-01 16:38:44.000000000 +0300
+++ udev-146.new/udev/udevadm-settle.c	2009-10-29 20:56:50.105716340 +0300
@@ -171,6 +171,8 @@
 			sigaddset(&mask, SIGUSR1);
 			sigaddset(&mask, SIGALRM);
 			sigprocmask(SIG_BLOCK, &mask, &oldmask);
+			sigdelset(&oldmask, SIGUSR1);
+			sigdelset(&oldmask, SIGALRM);
 			if (udev_ctrl_send_settle(uctrl) > 0)
 				sigsuspend(&oldmask);
 			sigprocmask(SIG_SETMASK, &oldmask, NULL);

[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux