The problem is originally caused by a race condition between cryptsetup (actually libdevicemapper) and UDEV. In a UDEV system cryptsetup should not add or remove the device node by itself but this is not so easy to fix I think.
Anyway, it should be no problem if HAL correctly recognizes all additions/removals of nodes under /dev/mapper but this is not the case. If UDEV gets a 'device added' notification and the node is already in place then it leaves the node as it is and continues. On the other hand if UDEV gets a 'device removed' kernel notification and the device node is not present then no 'RUN' rules are executed! One can see this in the debug logs below. In the failed case the 'udev_node_remove' call is missing and, most important, also the 'pass_env_to_socket' calls. Due to this HAL will not know that the device node was removed!
== good notification ==
Jan 10 20:26:30 axel udevd[2679]: udev_event_run: seq 2918 forked, pid [8792], 'remove' 'block', 0 seconds old
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.udev/names/mapper\x2fluks_crypto_10926a57-5d12-4800-9422-e16288e999db/\x2fblock\x2fdm-2'
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.udev/names/disk\x2fby-id\x2fdm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db/\x2fblock\x2fdm-2'
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.udev/names/disk\x2fby-uuid\x2fd66d2764-0ebf-4dd0-8b38-19b96d58a1cf/\x2fblock\x2fdm-2'
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.udev/names/disk\x2fby-label\x2fBackup/\x2fblock\x2fdm-2'
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_remove: removing device node '/dev/mapper/luks_crypto_10926a57-5d12-4800-9422-e16288e999db'
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_update_symlinks: update symlink 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db' of '/block/dm-2'
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-id\x2fdm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db': No such file or directory
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db'
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db'
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_update_symlinks: update symlink 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'of '/block/dm-2'
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-uuid\x2fd66d2764-0ebf-4dd0-8b38-19b96d58a1cf': No such file or directory
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_update_symlinks: update symlink 'disk/by-label/Backup' of '/block/dm-2'
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-label\x2fBackup': No such file or directory
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-label/Backup'
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-label/Backup'
Jan 10 20:26:30 axel udevd-event[8792]: pass_env_to_socket: passed 770 bytes to socket '/org/freedesktop/hal/udev_event',
Jan 10 20:26:30 axel udevd-event[8792]: pass_env_to_socket: passed -1 bytes to socket '/org/kernel/udev/monitor',
Jan 10 20:26:30 axel udevd-event[8792]: udev_event_run: seq 2918 finished
== failed notification ==
Jan 10 20:27:08 axel udevd[2679]: udev_event_run: seq 2950 forked, pid [8911], 'remove' 'block', 0 seconds old
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.udev/names/mapper\x2fluks_crypto_10926a57-5d12-4800-9422-e16288e999db/\x2fblock\x2fdm-2'
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.udev/names/disk\x2fby-id\x2fdm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db/\x2fblock\x2fdm-2'
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.udev/names/disk\x2fby-uuid\x2fd66d2764-0ebf-4dd0-8b38-19b96d58a1cf/\x2fblock\x2fdm-2'
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.udev/names/disk\x2fby-label\x2fBackup/\x2fblock\x2fdm-2'
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_update_symlinks: update symlink 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db' of '/block/dm-2'
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-id\x2fdm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db': No such file or directory
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db'
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-id/dm-name-luks_crypto_10926a57-5d12-4800-9422-e16288e999db'
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_update_symlinks: update symlink 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'of '/block/dm-2'
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-uuid\x2fd66d2764-0ebf-4dd0-8b38-19b96d58a1cf': No such file or directory
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-uuid/d66d2764-0ebf-4dd0-8b38-19b96d58a1cf'
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_update_symlinks: update symlink 'disk/by-label/Backup' of '/block/dm-2'
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_get_devices_by_name: no index directory '/dev/.udev/names/disk\x2fby-label\x2fBackup': No such file or directory
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-label/Backup'
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-label/Backup'
Jan 10 20:27:08 axel udevd-event[8911]: udev_event_run: seq 2950 finished
Jan 10 20:27:08 axel udevd[2679]: udev_done: seq 2950, pid [8911] exit with 1, 0 seconds old
In fact this bug shows up in two problems which were already described above:
1. Volume not mounted
Cause: cryptsetup first creates a temporary device node (temporary-cryptsetup-XXXXX), immediately removes it and creates the final node. If cryptsetup removes the temporary node _before_ UDEV then no notification is passed to HAL. After this the final node is created -> notification is passed to HAL but is ignored because HAL already knows '/sys/block/dm-X' -> HAL keeps pointing to the temporary node -> cannot mount
2. No passphrase popup
Cause: When the device was disconnected last time UDEV came too late and the clear text device node was already removed by cryptsetup -> no notification of device removal is passed to HAL -> HAL keeps the clear text device node -> when device is plugged again HAL thinks it is already decrypted because of the stale clear text node entry
The fix should be quite simple by patching UDEV to tolerate the fact that a device node may have already been removed. It looks also more consistent because when a device is added and the device node is already there then UDEV happily keeps the node and proceeds. The following patch worked for me on Gutsy to surpress the artifacts...
--- old/udev_node.c 2007-06-23 17:44:48.000000000 +0200
+++ new/udev_node.c 2008-01-14 23:21:56.000000000 +0100
@@ -401,7 +401,7 @@ int udev_node_remove(struct udevice *ude
strlcat(filename, udev->name, sizeof(filename));
if (stat(filename, &stats) != 0) {
dbg("device node '%s' not found", filename);
- return -1;
+ goto already_removed;
}
if (udev->devt && stats.st_rdev != udev->devt) {
info("device node '%s' points to a different device, skip removal", filename);
@@ -414,6 +414,7 @@ int udev_node_remove(struct udevice *ude
if (retval)
return retval;
+already_removed:
setenv("DEVNAME", filename, 1);
num = udev->partitions;
if (num > 0) {
The problem is originally caused by a race condition between cryptsetup (actually libdevicemapper) and UDEV. In a UDEV system cryptsetup should not add or remove the device node by itself but this is not so easy to fix I think.
Anyway, it should be no problem if HAL correctly recognizes all additions/removals of nodes under /dev/mapper but this is not the case. If UDEV gets a 'device added' notification and the node is already in place then it leaves the node as it is and continues. On the other hand if UDEV gets a 'device removed' kernel notification and the device node is not present then no 'RUN' rules are executed! One can see this in the debug logs below. In the failed case the 'udev_node_remove' call is missing and, most important, also the 'pass_env_ to_socket' calls. Due to this HAL will not know that the device node was removed!
== good notification == udev/names/ mapper\ x2fluks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db/\x2fblock\ x2fdm-2' udev/names/ disk\x2fby- id\x2fdm- name-luks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db/\x2fblock\ x2fdm-2' udev/names/ disk\x2fby- uuid\x2fd66d276 4-0ebf- 4dd0-8b38- 19b96d58a1cf/ \x2fblock\ x2fdm-2' udev/names/ disk\x2fby- label\x2fBackup /\x2fblock\ x2fdm-2' luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' update_ symlinks: update symlink 'disk/by- id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- id\x2fdm- name-luks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db': No such file or directory id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' update_ symlinks: update symlink 'disk/by- uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf'of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- uuid\x2fd66d276 4-0ebf- 4dd0-8b38- 19b96d58a1cf' : No such file or directory uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf' uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf' update_ symlinks: update symlink 'disk/by- label/Backup' of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- label\x2fBackup ': No such file or directory label/Backup' label/Backup' op/hal/ udev_event' , udev/monitor' ,
Jan 10 20:26:30 axel udevd[2679]: udev_event_run: seq 2918 forked, pid [8792], 'remove' 'block', 0 seconds old
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.
Jan 10 20:26:30 axel udevd-event[8792]: name_index: removing index: '/dev/.
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_remove: removing device node '/dev/mapper/
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: udev_node_
Jan 10 20:26:30 axel udevd-event[8792]: udev_db_
Jan 10 20:26:30 axel udevd-event[8792]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: update_link: no reference left, remove 'disk/by-
Jan 10 20:26:30 axel udevd-event[8792]: pass_env_to_socket: passed 770 bytes to socket '/org/freedeskt
Jan 10 20:26:30 axel udevd-event[8792]: pass_env_to_socket: passed -1 bytes to socket '/org/kernel/
Jan 10 20:26:30 axel udevd-event[8792]: udev_event_run: seq 2918 finished
== failed notification == udev/names/ mapper\ x2fluks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db/\x2fblock\ x2fdm-2' udev/names/ disk\x2fby- id\x2fdm- name-luks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db/\x2fblock\ x2fdm-2' udev/names/ disk\x2fby- uuid\x2fd66d276 4-0ebf- 4dd0-8b38- 19b96d58a1cf/ \x2fblock\ x2fdm-2' udev/names/ disk\x2fby- label\x2fBackup /\x2fblock\ x2fdm-2' update_ symlinks: update symlink 'disk/by- id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- id\x2fdm- name-luks_ crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db': No such file or directory id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' id/dm-name- luks_crypto_ 10926a57- 5d12-4800- 9422-e16288e999 db' update_ symlinks: update symlink 'disk/by- uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf'of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- uuid\x2fd66d276 4-0ebf- 4dd0-8b38- 19b96d58a1cf' : No such file or directory uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf' uuid/d66d2764- 0ebf-4dd0- 8b38-19b96d58a1 cf' update_ symlinks: update symlink 'disk/by- label/Backup' of '/block/dm-2' get_devices_ by_name: no index directory '/dev/. udev/names/ disk\x2fby- label\x2fBackup ': No such file or directory label/Backup' label/Backup'
Jan 10 20:27:08 axel udevd[2679]: udev_event_run: seq 2950 forked, pid [8911], 'remove' 'block', 0 seconds old
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.
Jan 10 20:27:08 axel udevd-event[8911]: name_index: removing index: '/dev/.
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: udev_node_
Jan 10 20:27:08 axel udevd-event[8911]: udev_db_
Jan 10 20:27:08 axel udevd-event[8911]: update_link: found -1 devices with name 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: update_link: no reference left, remove 'disk/by-
Jan 10 20:27:08 axel udevd-event[8911]: udev_event_run: seq 2950 finished
Jan 10 20:27:08 axel udevd[2679]: udev_done: seq 2950, pid [8911] exit with 1, 0 seconds old
In fact this bug shows up in two problems which were already described above:
1. Volume not mounted cryptsetup- XXXXX), immediately removes it and creates the final node. If cryptsetup removes the temporary node _before_ UDEV then no notification is passed to HAL. After this the final node is created -> notification is passed to HAL but is ignored because HAL already knows '/sys/block/dm-X' -> HAL keeps pointing to the temporary node -> cannot mount
Cause: cryptsetup first creates a temporary device node (temporary-
2. No passphrase popup
Cause: When the device was disconnected last time UDEV came too late and the clear text device node was already removed by cryptsetup -> no notification of device removal is passed to HAL -> HAL keeps the clear text device node -> when device is plugged again HAL thinks it is already decrypted because of the stale clear text node entry
The fix should be quite simple by patching UDEV to tolerate the fact that a device node may have already been removed. It looks also more consistent because when a device is added and the device node is already there then UDEV happily keeps the node and proceeds. The following patch worked for me on Gutsy to surpress the artifacts...
--- old/udev_node.c 2007-06-23 17:44:48.000000000 +0200 remove( struct udevice *ude remove( struct udevice *ude
+++ new/udev_node.c 2008-01-14 23:21:56.000000000 +0100
@@ -401,7 +401,7 @@ int udev_node_
strlcat(filename, udev->name, sizeof(filename));
if (stat(filename, &stats) != 0) {
dbg("device node '%s' not found", filename);
- return -1;
+ goto already_removed;
}
if (udev->devt && stats.st_rdev != udev->devt) {
info("device node '%s' points to a different device, skip removal", filename);
@@ -414,6 +414,7 @@ int udev_node_
if (retval)
return retval;
+already_removed:
setenv("DEVNAME", filename, 1);
num = udev->partitions;
if (num > 0) {