summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/loop-util.c13
-rw-r--r--src/shared/loop-util.h4
2 files changed, 14 insertions, 3 deletions
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
index 8be4dbf938..047e213634 100644
--- a/src/shared/loop-util.c
+++ b/src/shared/loop-util.c
@@ -129,7 +129,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
if (d->fd >= 0) {
- if (d->nr >= 0) {
+ if (d->nr >= 0 && !d->relinquished) {
if (ioctl(d->fd, LOOP_CLR_FD) < 0)
log_debug_errno(errno, "Failed to clear loop device: %m");
@@ -138,7 +138,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
safe_close(d->fd);
}
- if (d->nr >= 0) {
+ if (d->nr >= 0 && !d->relinquished) {
_cleanup_close_ int control = -1;
control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
@@ -155,3 +155,12 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
return NULL;
}
+
+void loop_device_relinquish(LoopDevice *d) {
+ assert(d);
+
+ /* Don't attempt to clean up the loop device anymore from this point on. Leave the clean-ing up to the kernel
+ * itself, using the loop device "auto-clear" logic we already turned on when creating the device. */
+
+ d->relinquished = true;
+}
diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h
index 5c847c4ac3..45fead5f18 100644
--- a/src/shared/loop-util.h
+++ b/src/shared/loop-util.h
@@ -29,11 +29,13 @@ struct LoopDevice {
int fd;
int nr;
char *node;
+ bool relinquished;
};
int loop_device_make(int fd, int open_flags, LoopDevice **ret);
int loop_device_make_by_path(const char *path, int open_flags, LoopDevice **ret);
LoopDevice* loop_device_unref(LoopDevice *d);
-
DEFINE_TRIVIAL_CLEANUP_FUNC(LoopDevice*, loop_device_unref);
+
+void loop_device_relinquish(LoopDevice *d);