Package: udev
Version: 175-7.2
Tags: patch

Dear maintainer,

I've noticed an unexpected behavior regarding CD ejection handling.

After a disc has been mounted with udisks (which can be done by executing `$ 
udisks --mount /dev/device'
command or by just clicking its icon in any major Desktop Environment), the 
tray is being unlocked, and
the disc can be ejected by just pressing the hardware button on the drive.

The problem is it's not being unmounted, so inserting another disc has no 
effect.

The source of the issue is udisks using userspace rather than in-kernel 
polling. See the following code
from src/poller.c:
-------------------- 8< --------------------
if (is_cdrom)
  {
    /* optical drives need special care
     *
     *  - use O_NONBLOCK to avoid closing the door
     *  - use O_EXCL to avoid interferring with cd burning software / audio 
playback / etc
     */
    fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
    if (fd != -1)
      {
        close (fd);
      }
  }
-------------------- >8 --------------------
- open() with O_EXCL option returns -1 (EBUSY) if the device is mounted. So 
udisks doesn't poll
mounted devices, which leads to the described behavior.

I've tried compiling udisks without O_EXCL, and it "solves" the original issue, 
but stops polling of *all*
devices while something is burning a CD, which is unacceptable.

sysctl dev.cdrom.lock setting has no effect since udisks explicitly unlocks the 
tray after mounting (from
src/device.c):
-------------------- 8< --------------------
/* If the kernel and device support sending EJECT_REQUEST change uevents
 * and we use in-kernel polling, keep the door locked, as udev calls
 * eject on pressing the button. Otherwise unlock it, to keep the
 * hardware button working without userspace support */
if (!device->priv->using_in_kernel_polling)
  unlock_cd_tray (device);
-------------------- >8 --------------------

So the only rational solution would be to enable in-kernel polling so that 
udisks can just recieve
DISC_EJECT_REQUEST uevent and unmount the disc.

In fact, udev package contains a rule to do exactly that (see 
60-persistent-storage.rules):
-------------------- 8< --------------------
# enable in-kernel media-presence polling
ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", \
        ATTR{parameters/events_dfl_poll_msecs}=="0", \
        ATTR{parameters/events_dfl_poll_msecs}="2000"
-------------------- >8 --------------------
- but it fails:
-------------------- 8< --------------------
$ cat /sys/module/block/parameters/events_dfl_poll_msecs
0
$ cat /sys/block/sr1/events_poll_msecs
-1
-------------------- >8 --------------------

After I execute `# echo 2000 > /sys/block/sr1/events_poll_msecs', the issue 
vanishes.

Looks like the problem with the rule is that it assumes block is a module, 
while it is built-in.

I've found that Ubuntu applies a patch (attached) to the udev package. I guess, 
it can be applied to the
Debian udev package too.

-- 
Алексей Шилин
Description: Set default polling interval on CD drives as well. The events_dfl_poll_msecs will not trigger if "block" is not a module, but built in. This will avoid udisks etc. having to poll from userspace, and provide proper ejection when the hardware eject button is pressed.
Author: Martin Pitt <martin.pitt@ubuntu.com>
Bug-Ubuntu: https://launchpad.net/bugs/890592

Index: precise/rules/rules.d/60-persistent-storage.rules
===================================================================
--- precise.orig/rules/rules.d/60-persistent-storage.rules	2012-02-06 09:09:39.413371483 +0100
+++ precise/rules/rules.d/60-persistent-storage.rules	2012-03-28 11:33:05.900794721 +0200
@@ -10,6 +10,7 @@
 
 # enable in-kernel media-presence polling
 ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", ATTR{parameters/events_dfl_poll_msecs}="2000"
+ACTION=="add", ATTR{removable}=="1", ATTR{events_poll_msecs}=="-1", ATTR{events_poll_msecs}="2000"
 
 SUBSYSTEM!="block", GOTO="persistent_storage_end"
 

Reply via email to