mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-18 10:04:20 +03:00
Retry DM_DEVICE_REMOVE ioctl if device is busy.
This is a workaround for long-lasting problem with using the WATCH udev rule. When trying to remove a DM device, this one can still be opened while processing the event in parallel (generated based on the WATCH udev rule). Let's use this until we have a proper solution.
This commit is contained in:
parent
cc9dc919e6
commit
8171b93700
@ -1,5 +1,6 @@
|
|||||||
Version 1.02.68 -
|
Version 1.02.68 -
|
||||||
==================================
|
==================================
|
||||||
|
Retry DM_DEVICE_REMOVE ioctl if device is busy.
|
||||||
Remove unused passed parameters for _mirror_emit_segment_line().
|
Remove unused passed parameters for _mirror_emit_segment_line().
|
||||||
Add dm_config and string character escaping functions to libdevmapper.
|
Add dm_config and string character escaping functions to libdevmapper.
|
||||||
Mark unreleased memory pools as internal error.
|
Mark unreleased memory pools as internal error.
|
||||||
|
@ -1539,11 +1539,14 @@ static const char *_sanitise_message(char *message)
|
|||||||
return sanitised_message;
|
return sanitised_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DM_REMOVE_IOCTL_RETRIES 25
|
||||||
|
|
||||||
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
||||||
unsigned repeat_count)
|
unsigned repeat_count)
|
||||||
{
|
{
|
||||||
struct dm_ioctl *dmi;
|
struct dm_ioctl *dmi;
|
||||||
int ioctl_with_uevent;
|
int ioctl_with_uevent;
|
||||||
|
int retries = DM_REMOVE_IOCTL_RETRIES;
|
||||||
|
|
||||||
dmi = _flatten(dmt, repeat_count);
|
dmi = _flatten(dmt, repeat_count);
|
||||||
if (!dmi) {
|
if (!dmi) {
|
||||||
@ -1627,11 +1630,23 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
|||||||
dmt->sector, _sanitise_message(dmt->message),
|
dmt->sector, _sanitise_message(dmt->message),
|
||||||
dmi->data_size);
|
dmi->data_size);
|
||||||
#ifdef DM_IOCTLS
|
#ifdef DM_IOCTLS
|
||||||
|
repeat_dm_ioctl:
|
||||||
if (ioctl(_control_fd, command, dmi) < 0) {
|
if (ioctl(_control_fd, command, dmi) < 0) {
|
||||||
if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
|
if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
|
||||||
(dmt->type == DM_DEVICE_MKNODES) ||
|
(dmt->type == DM_DEVICE_MKNODES) ||
|
||||||
(dmt->type == DM_DEVICE_STATUS)))
|
(dmt->type == DM_DEVICE_STATUS)))
|
||||||
dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
|
dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
|
||||||
|
/*
|
||||||
|
* FIXME: This is a workaround for asynchronous events generated
|
||||||
|
* as a result of using the WATCH udev rule with which we
|
||||||
|
* have no way of synchronizing. Processing such events in
|
||||||
|
* parallel causes devices to be open.
|
||||||
|
*/
|
||||||
|
else if (errno == EBUSY && (dmt->type == DM_DEVICE_REMOVE) && retries--) {
|
||||||
|
log_debug("device-mapper: device is busy, retrying removal");
|
||||||
|
usleep(200000);
|
||||||
|
goto repeat_dm_ioctl;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (_log_suppress)
|
if (_log_suppress)
|
||||||
log_verbose("device-mapper: %s ioctl "
|
log_verbose("device-mapper: %s ioctl "
|
||||||
|
Loading…
x
Reference in New Issue
Block a user