From 58a453f3f06c1daf34544da8aa16bb95e8e18010 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 14 Aug 2017 13:06:16 +0300 Subject: [PATCH] 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)) }