]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
umount: when we fail to detach a loopback device, set the auto-clear flag 14409/head
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Dec 2019 17:37:24 +0000 (18:37 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Dec 2019 17:37:24 +0000 (18:37 +0100)
We might get lucky and this cleans up things later on automatically for
us.

src/shutdown/umount.c

index cc86f4180e816b0a5416c110aef1639276bbd760..8a5e80eeaa15a8e77334bbf920d6c8bf22a96141 100644 (file)
@@ -340,7 +340,30 @@ static int delete_loopback(const char *device) {
                 if (errno == ENXIO) /* Nothing bound, didn't do anything */
                         return 0;
 
-                return -errno;
+                if (errno != EBUSY)
+                        return log_debug_errno(errno, "Failed to clear loopback device %s: %m", device);
+
+                if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
+                        if (errno == ENXIO) /* What? Suddenly detached after all? That's fine by us then. */
+                                return 1;
+
+                        log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device);
+                        return -EBUSY; /* propagate original error */
+                }
+
+                if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) /* someone else already set LO_FLAGS_AUTOCLEAR for us? fine by us */
+                        return -EBUSY; /* propagate original error */
+
+                info.lo_flags |= LO_FLAGS_AUTOCLEAR;
+                if (ioctl(fd, LOOP_SET_STATUS64, &info) < 0) {
+                        if (errno == ENXIO) /* Suddenly detached after all? Fine by us */
+                                return 1;
+
+                        log_debug_errno(errno, "Failed to set LO_FLAGS_AUTOCLEAR flag for loop device %s, ignoring: %m", device);
+                } else
+                        log_debug("Successfully set LO_FLAGS_AUTOCLEAR flag for loop device %s.", device);
+
+                return -EBUSY;
         }
 
         if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {