From 6ca20ec771ab7c0ebf64c20021ca795746cf3ccb 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 --- daemon/graphdriver/devmapper/device_setup.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/daemon/graphdriver/devmapper/device_setup.go b/daemon/graphdriver/devmapper/device_setup.go index 05a295cb69..00d0ea349f 100644 --- a/daemon/graphdriver/devmapper/device_setup.go +++ b/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 8b7bd58869725dce2f0fcfd582d23dc5e0cfcf8e 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 --- daemon/graphdriver/devmapper/deviceset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index d52a7f5914..95d9df7cb0 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/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 58a453f3f06c1daf34544da8aa16bb95e8e18010 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 --- daemon/graphdriver/devmapper/device_setup.go | 42 ++++++-------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/daemon/graphdriver/devmapper/device_setup.go b/daemon/graphdriver/devmapper/device_setup.go index 00d0ea349f..30463f23a2 100644 --- a/daemon/graphdriver/devmapper/device_setup.go +++ b/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)) }