From d92c40217f7cb9701d448a4ee0bf8307e0ff83e9 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Fri, 11 Aug 2017 08:00:00 -0700 Subject: [PATCH 1/3] devmapper autoconfig: add mkdir I tried using dm.directlvm_device but it ended up with the following error: > Error starting daemon: error initializing graphdriver: error > writing docker thinp autoextend profile: open > /etc/lvm/profile/docker-thinpool.profile: no such file or directory The reason is /etc/lvm/profile directory does not exist. I think it is better to try creating it beforehand. Signed-off-by: Kir Kolyshkin Upstream-commit: 6ca20ec771ab7c0ebf64c20021ca795746cf3ccb Component: engine --- .../engine/daemon/graphdriver/devmapper/device_setup.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/engine/daemon/graphdriver/devmapper/device_setup.go b/components/engine/daemon/graphdriver/devmapper/device_setup.go index 05a295cb69..00d0ea349f 100644 --- a/components/engine/daemon/graphdriver/devmapper/device_setup.go +++ b/components/engine/daemon/graphdriver/devmapper/device_setup.go @@ -172,6 +172,8 @@ func writeLVMConfig(root string, cfg directLVMConfig) error { } func setupDirectLVM(cfg directLVMConfig) error { + lvmProfileDir := "/etc/lvm/profile" + pvCreate, err := exec.LookPath("pvcreate") if err != nil { return errors.Wrap(err, "error looking up command `pvcreate` while setting up direct lvm") @@ -197,6 +199,11 @@ func setupDirectLVM(cfg directLVMConfig) error { return errors.Wrap(err, "error looking up command `lvchange` while setting up direct lvm") } + err = os.MkdirAll(lvmProfileDir, 0755) + if err != nil { + return errors.Wrap(err, "error creating lvm profile directory") + } + if cfg.AutoExtendPercent == 0 { cfg.AutoExtendPercent = 20 } @@ -237,7 +244,7 @@ func setupDirectLVM(cfg directLVMConfig) error { } profile := fmt.Sprintf("activation{\nthin_pool_autoextend_threshold=%d\nthin_pool_autoextend_percent=%d\n}", cfg.AutoExtendThreshold, cfg.AutoExtendPercent) - err = ioutil.WriteFile("/etc/lvm/profile/docker-thinpool.profile", []byte(profile), 0600) + err = ioutil.WriteFile(lvmProfileDir+"/docker-thinpool.profile", []byte(profile), 0600) if err != nil { return errors.Wrap(err, "error writing docker thinp autoextend profile") } From 94157b8e90100e3f79941609ea2b2a03b439769a Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Fri, 11 Aug 2017 08:03:41 -0700 Subject: [PATCH 2/3] devmapper: refer to dockerd man page ...not the docker one. Signed-off-by: Kir Kolyshkin Upstream-commit: 8b7bd58869725dce2f0fcfd582d23dc5e0cfcf8e Component: engine --- components/engine/daemon/graphdriver/devmapper/deviceset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go index d52a7f5914..95d9df7cb0 100644 --- a/components/engine/daemon/graphdriver/devmapper/deviceset.go +++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go @@ -1860,7 +1860,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) { if devices.thinPoolDevice == "" { if devices.metadataLoopFile != "" || devices.dataLoopFile != "" { - logrus.Warn("devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man docker` to refer to dm.thinpooldev section.") + logrus.Warn("devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man dockerd` to refer to dm.thinpooldev section.") } } From ded67f686e990254f1bb1ced0459f5131573f008 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 14 Aug 2017 13:06:16 +0300 Subject: [PATCH 3/3] devmapper autosetup: add check for thin_check I was able to successfully use device mapper autoconfig feature (commit 5ef07d79c) but it stopped working after a reboot. Investigation shown that the dm device was not activated because of a missing binary, that is not used during initial setup, but every following time. Here's an error shown when trying to manually activate the device: > kir@kd:~/go/src/github.com/docker/docker$ sudo lvchange -a y /dev/docker/thinpool > /usr/sbin/thin_check: execvp failed: No such file or directory > Check of pool docker/thinpool failed (status:2). Manual repair required! Surely, there is no solution to this other than to have a package that provides the thin_check binary installed beforehand. Due to the fact the issue revealed itself way later than DM setup was performed, it was somewhat harder to investigate. With this in mind, let's check for binary presense before setting up DM, refusing to proceed if the binary is not there, saving a user from later frustration. While at it, eliminate repeated binary checking code. The downside is that the binary lookup is happening more than once now -- I think the clarity of code overweights this minor de-optimization. Signed-off-by: Kir Kolyshkin Upstream-commit: 58a453f3f06c1daf34544da8aa16bb95e8e18010 Component: engine --- .../graphdriver/devmapper/device_setup.go | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/components/engine/daemon/graphdriver/devmapper/device_setup.go b/components/engine/daemon/graphdriver/devmapper/device_setup.go index 00d0ea349f..30463f23a2 100644 --- a/components/engine/daemon/graphdriver/devmapper/device_setup.go +++ b/components/engine/daemon/graphdriver/devmapper/device_setup.go @@ -173,33 +173,15 @@ func writeLVMConfig(root string, cfg directLVMConfig) error { func setupDirectLVM(cfg directLVMConfig) error { lvmProfileDir := "/etc/lvm/profile" + binaries := []string{"pvcreate", "vgcreate", "lvcreate", "lvconvert", "lvchange", "thin_check"} - pvCreate, err := exec.LookPath("pvcreate") - if err != nil { - return errors.Wrap(err, "error looking up command `pvcreate` while setting up direct lvm") + for _, bin := range binaries { + if _, err := exec.LookPath(bin); err != nil { + return errors.Wrap(err, "error looking up command `"+bin+"` while setting up direct lvm") + } } - vgCreate, err := exec.LookPath("vgcreate") - if err != nil { - return errors.Wrap(err, "error looking up command `vgcreate` while setting up direct lvm") - } - - lvCreate, err := exec.LookPath("lvcreate") - if err != nil { - return errors.Wrap(err, "error looking up command `lvcreate` while setting up direct lvm") - } - - lvConvert, err := exec.LookPath("lvconvert") - if err != nil { - return errors.Wrap(err, "error looking up command `lvconvert` while setting up direct lvm") - } - - lvChange, err := exec.LookPath("lvchange") - if err != nil { - return errors.Wrap(err, "error looking up command `lvchange` while setting up direct lvm") - } - - err = os.MkdirAll(lvmProfileDir, 0755) + err := os.MkdirAll(lvmProfileDir, 0755) if err != nil { return errors.Wrap(err, "error creating lvm profile directory") } @@ -219,26 +201,26 @@ func setupDirectLVM(cfg directLVMConfig) error { cfg.ThinpMetaPercent = 1 } - out, err := exec.Command(pvCreate, "-f", cfg.Device).CombinedOutput() + out, err := exec.Command("pvcreate", "-f", cfg.Device).CombinedOutput() if err != nil { return errors.Wrap(err, string(out)) } - out, err = exec.Command(vgCreate, "docker", cfg.Device).CombinedOutput() + out, err = exec.Command("vgcreate", "docker", cfg.Device).CombinedOutput() if err != nil { return errors.Wrap(err, string(out)) } - out, err = exec.Command(lvCreate, "--wipesignatures", "y", "-n", "thinpool", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpPercent)).CombinedOutput() + out, err = exec.Command("lvcreate", "--wipesignatures", "y", "-n", "thinpool", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpPercent)).CombinedOutput() if err != nil { return errors.Wrap(err, string(out)) } - out, err = exec.Command(lvCreate, "--wipesignatures", "y", "-n", "thinpoolmeta", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpMetaPercent)).CombinedOutput() + out, err = exec.Command("lvcreate", "--wipesignatures", "y", "-n", "thinpoolmeta", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpMetaPercent)).CombinedOutput() if err != nil { return errors.Wrap(err, string(out)) } - out, err = exec.Command(lvConvert, "-y", "--zero", "n", "-c", "512K", "--thinpool", "docker/thinpool", "--poolmetadata", "docker/thinpoolmeta").CombinedOutput() + out, err = exec.Command("lvconvert", "-y", "--zero", "n", "-c", "512K", "--thinpool", "docker/thinpool", "--poolmetadata", "docker/thinpoolmeta").CombinedOutput() if err != nil { return errors.Wrap(err, string(out)) } @@ -249,6 +231,6 @@ func setupDirectLVM(cfg directLVMConfig) error { return errors.Wrap(err, "error writing docker thinp autoextend profile") } - out, err = exec.Command(lvChange, "--metadataprofile", "docker-thinpool", "docker/thinpool").CombinedOutput() + out, err = exec.Command("lvchange", "--metadataprofile", "docker-thinpool", "docker/thinpool").CombinedOutput() return errors.Wrap(err, string(out)) }