diff options
authorSamuel Mendoza-Jonas <>2018-12-04 12:49:28 +1100
committerSamuel Mendoza-Jonas <>2019-01-09 10:38:49 +1100
commit8b9d8bf7c9837832347dd8018b9910cc7d2b4371 (patch)
parent017aada974ef9c322cad412a9832fa1df265267b (diff)
discover/devmapper: Retry dm-device remove if busyv1.7.4
Buildroot's libdm is not built with --enable-udev_sync, so device-mapper actions are not able to sync or wait for udev events. (see 185676316, "discover/devmapper: Disable libdm udev sync support") This can cause an issue when tearing down a snapshot in devmapper_destroy_snapshot() which performs a DM_DEVICE_REMOVE task against the snapshot, origin, and base devices one after the other. In some cases if the interval between these actions is too short the action can fail as the preceding device hasn't disappeared yet and the device being removed is still busy. Since we don't yet have a way to tell exactly when the device is ready, pause for a short time and retry the action, letting devmapper_destroy_snapshot() continue and, for example, letting mount_device() fall back to the physical device. Signed-off-by: Samuel Mendoza-Jonas <> (cherry picked from commit 89cde533356d47b34a80679602c3900572b2dca6)
1 files changed, 20 insertions, 5 deletions
diff --git a/discover/devmapper.c b/discover/devmapper.c
index d8445e6..795201f 100644
--- a/discover/devmapper.c
+++ b/discover/devmapper.c
@@ -457,24 +457,33 @@ static int destroy_device(const char *dm_name)
struct dm_task *task;
uint32_t cookie;
- int rc = -1;
+ int rc, retries = 0;
task = dm_task_create(DM_DEVICE_REMOVE);
if (!task) {
- pb_log("%s: could not create dm_task\n", __func__);
+ pb_debug("%s: could not create dm_task\n", __func__);
return -1;
if (!dm_task_set_name(task, dm_name)) {
- pb_log("No dm device named '%s'\n", dm_name);
+ rc = dm_task_get_errno(task);
+ pb_debug("%s: Couldn't set name for %s, %s (%d)\n",
+ __func__, dm_name, strerror(rc), rc);
goto out;
- if (!set_cookie(task, &cookie))
+ if (!set_cookie(task, &cookie)) {
+ rc = dm_task_get_errno(task);
+ pb_debug("%s: set_cookie failed, %s (%d)\n",
+ __func__, strerror(rc), rc);
goto out;
+ }
if (!dm_task_run(task)) {
- pb_log("Unable to remove device '%s'\n", dm_name);
+ rc = dm_task_get_errno(task);
+ pb_debug("%s: Unable to remove device '%s', %s (%d)\n",
+ __func__, dm_name, strerror(rc), rc);
goto out;
@@ -485,6 +494,12 @@ static int destroy_device(const char *dm_name)
+ if (rc == EBUSY && retries < 5) {
+ pb_log("%s: Device busy, retry %d..\n", __func__, retries);
+ usleep(100000);
+ retries++;
+ goto retry;
+ }
return rc;
OpenPOWER on IntegriCloud