The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2982
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === For loop-backed btrfs pools we actually mount the loop device and so it's fine to use LO_FLAGS_AUTOCLEAR since the loop device is guaranteed to be kept around for as long as the mount exists. When we implement lvm loop-backed pools however, we do not mount the loop device so we need to make sure that it is not deconfigured automatically when we close all handles to it. Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 79a63c21b2f28971d61e2ea51ddd434f8049ed9a Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Wed, 1 Mar 2017 02:24:27 +0100 Subject: [PATCH] storage_cgo: make flag argument configurable For loop-backed btrfs pools we actually mount the loop device and so it's fine to use LO_FLAGS_AUTOCLEAR since the loop device is guaranteed to be kept around for as long as the mount exists. When we implement lvm loop-backed pools however, we do not mount the loop device so we need to make sure that it is not deconfigured automatically when we close all handles to it. Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- lxd/storage_btrfs.go | 5 ++++- lxd/storage_cgo.go | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go index 7d62ae3..a69aac9 100644 --- a/lxd/storage_btrfs.go +++ b/lxd/storage_btrfs.go @@ -338,7 +338,10 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) { mountSource := source if filepath.IsAbs(source) { if !shared.IsBlockdevPath(source) && s.d.BackingFs != "btrfs" { - loopF, err := prepareLoopDev(source) + // Since we mount the loop device LO_FLAGS_AUTOCLEAR is + // fine since the loop device will be kept around for as + // long as the mount exists. + loopF, err := prepareLoopDev(source, LO_FLAGS_AUTOCLEAR) if err != nil { return false, fmt.Errorf("Could not prepare loop device.") } diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go index 95ede6f..d7a6ba3 100644 --- a/lxd/storage_cgo.go +++ b/lxd/storage_cgo.go @@ -197,7 +197,7 @@ on_error: return fd_tmp; } -int prepare_loop_dev(const char *source, char *loop_dev) +int prepare_loop_dev(const char *source, char *loop_dev, int flags) { int ret; struct loop_info64 lo64; @@ -220,7 +220,7 @@ int prepare_loop_dev(const char *source, char *loop_dev) goto on_error; memset(&lo64, 0, sizeof(lo64)); - lo64.lo_flags = LO_FLAGS_AUTOCLEAR; + lo64.lo_flags = flags; ret = ioctl(fd_loop, LOOP_SET_STATUS64, &lo64); if (ret < 0) @@ -248,10 +248,12 @@ import ( "unsafe" ) +const LO_FLAGS_AUTOCLEAR int = C.LO_FLAGS_AUTOCLEAR + // prepareLoopDev() detects and sets up a loop device for source. It returns an // open file descriptor to the free loop device and the path of the free loop // device. It's the callers responsibility to close the open file descriptor. -func prepareLoopDev(source string) (*os.File, error) { +func prepareLoopDev(source string, flags int) (*os.File, error) { cLoopDev := C.malloc(C.size_t(C.LO_NAME_SIZE)) if cLoopDev == nil { return nil, fmt.Errorf("Failed to allocate memory in C.") @@ -265,7 +267,7 @@ func prepareLoopDev(source string) (*os.File, error) { return os.NewFile(uintptr(loopFd), C.GoString((*C.char)(cLoopDev))), nil } - loopFd, err := C.prepare_loop_dev(cSource, (*C.char)(cLoopDev)) + loopFd, err := C.prepare_loop_dev(cSource, (*C.char)(cLoopDev), C.int(flags)) if loopFd < 0 { if err != nil { return nil, fmt.Errorf("Failed to prepare loop device: %s.", err)
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel