Improved and documented workaround for udev

This commit is contained in:
Thomas Schmitt 2011-09-21 13:34:21 +00:00
parent 71c9dc9f28
commit d9e6bde437
4 changed files with 86 additions and 11 deletions

15
README
View File

@ -92,6 +92,21 @@ Make sure to re-compile all source files after running ./configure
make install make install
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Closing and re-opening can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE"
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
An important part of the project, libisofs, is hosted in a bzr repository at An important part of the project, libisofs, is hosted in a bzr repository at

View File

@ -438,6 +438,22 @@ It will not read startup files, will abort on option dev_translation= ,
will not have a fifo buffer, and will not be able to put out help texts or will not have a fifo buffer, and will not be able to put out help texts or
debugging messages. debugging messages.
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Closing and re-opening can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE"
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
System Dependend Drive Permission Examples System Dependend Drive Permission Examples

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.09.20.132438" #define Cdrskin_timestamP "2011.09.21.133344"

View File

@ -1531,6 +1531,33 @@ int sg_grab(struct burn_drive *d)
relase of drive. Unclear why not the official error return relase of drive. Unclear why not the official error return
value -1 of open(2) war used. */ value -1 of open(2) war used. */
if(! burn_drive_is_open(d)) { if(! burn_drive_is_open(d)) {
char msg[120];
#ifndef Libburn_udev_wait_useC
#define Libburn_udev_wait_useC 100000
#endif
#ifndef Libburn_udev_extra_open_cyclE
if (Libburn_udev_wait_useC > 0) {
/* ts B10921 : workaround for udev which might get
a kernel event from open() and might
remove links if it cannot inspect the
drive. This waiting period shall allow udev
to act after it was woken up by the drive scan
activities.
*/
sprintf(msg,
"To avoid collision with udev: Waiting %lu usec before grabbing",
(unsigned long) Libburn_udev_wait_useC);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
usleep(Libburn_udev_wait_useC);
}
#endif /* Libburn_udev_extra_open_cyclE */
try_open:; try_open:;
/* ts A60821 /* ts A60821
@ -1553,21 +1580,34 @@ try_open:;
fd = open(d->devname, open_mode); fd = open(d->devname, open_mode);
os_errno = errno; os_errno = errno;
if (fd >= 0) {
#ifdef Libburn_udev_extra_open_cyclE
/* ts B10920 : workaround for udev which might get /* ts B10920 : workaround for udev which might get
a kernel event from open() and might a kernel event from open() and might
remove links if it cannot inspect the remove links if it cannot inspect the
drive. drive.
ts B10921 : this is more obtrusive than above waiting
before open(). The drive scan already has
opened and closed the drive several times.
So it seems to be merely about giving an
opportunity to udev, before long term grabbing
happens.
*/ */
if (fd >= 0 && Libburn_udev_wait_useC > 0) {
close(fd);
sprintf(msg,
"To avoid collision with udev: Waiting %lu usec before re-opening",
(unsigned long) Libburn_udev_wait_useC);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002, libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Waiting 2 seconds to avoid collision with udev", msg, 0, 0);
0, 0); usleep(Libburn_udev_wait_useC);
close(fd);
usleep(2000000);
fd = open(d->devname, open_mode); fd = open(d->devname, open_mode);
os_errno = errno; os_errno = errno;
} }
#endif /* Libburn_udev_extra_open_cyclE */
if (fd >= 0) { if (fd >= 0) {
sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1); sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1);
if (fd < 0) if (fd < 0)
@ -1591,6 +1631,10 @@ try_open:;
drive_is_in_use:; drive_is_in_use:;
tries++; tries++;
if (tries < max_tries) { if (tries < max_tries) {
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Drive is in use. Waiting 2 seconds before re-try",
0, 0);
usleep(2000000); usleep(2000000);
goto try_open; goto try_open;
} }