The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/3038
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) === Addresses #3036. Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From fa23309bb02473491c7be5db9e8220b786df614a Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Wed, 8 Mar 2017 00:42:59 +0100 Subject: [PATCH] patches: detect logical volume size Addresses #3036. Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- lxd/patches.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lxd/storage_lvm.go | 18 +++++++++++ 2 files changed, 110 insertions(+) diff --git a/lxd/patches.go b/lxd/patches.go index 3c527ba..4105ebe 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -40,6 +40,7 @@ var patches = []patch{ {name: "storage_api_keys", run: patchStorageApiKeys}, {name: "storage_api_update_storage_configs", run: patchStorageApiUpdateStorageConfigs}, {name: "storage_api_lxd_on_btrfs", run: patchStorageApiLxdOnBtrfs}, + {name: "storage_api_lvm_detect_lv_size", run: patchStorageApiDetectLVSize}, } type patch struct { @@ -2130,3 +2131,94 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error { return nil } + +func patchStorageApiDetectLVSize(name string, d *Daemon) error { + pools, err := dbStoragePools(d.db) + if err != nil { + if err == NoSuchObjectError { + return nil + } + shared.LogErrorf("Failed to query database: %s", err) + return err + } + + for _, poolName := range pools { + poolID, pool, err := dbStoragePoolGet(d.db, poolName) + if err != nil { + shared.LogErrorf("Failed to query database: %s", err) + return err + } + + // Make sure that config is not empty. + if pool.Config == nil { + pool.Config = map[string]string{} + + // Insert default values. + err = storagePoolFillDefault(poolName, pool.Driver, pool.Config) + if err != nil { + return err + } + } + + // We're only interested in LVM pools. + if pool.Driver != "lvm" { + continue + } + + // Get all storage volumes on the storage pool. + volumes, err := dbStoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes) + if err != nil { + if err == NoSuchObjectError { + continue + } + return err + } + + poolName := pool.Config["lvm.vg_name"] + if poolName == "" { + shared.LogErrorf("The \"lvm.vg_name\" key should not be empty.") + return fmt.Errorf("The \"lvm.vg_name\" key should not be empty.") + } + + for _, volume := range volumes { + // Make sure that config is not empty. + if volume.Config == nil { + volume.Config = map[string]string{} + + // Insert default values. + err := storageVolumeFillDefault(volume.Name, volume.Config, pool) + if err != nil { + return err + } + } + + // It shouldn't be possible that false volume types + // exist in the db, so it's safe to ignore the error. + volumeTypeApiEndpoint, _ := storagePoolVolumeTypeNameToApiEndpoint(volume.Type) + lvmName := containerNameToLVName(volume.Name) + lvmLvDevPath := getLvmDevPath(poolName, volumeTypeApiEndpoint, lvmName) + size, err := lvmGetLVSize(lvmLvDevPath) + if err != nil { + shared.LogErrorf("Failed to detect size of logical volume: %s.", err) + return err + } + + if volume.Config["size"] == size { + continue + } + + volume.Config["size"] = size + + // It shouldn't be possible that false volume types + // exist in the db, so it's safe to ignore the error. + volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type) + // Update the volume config. + err = dbStoragePoolVolumeUpdate(d.db, volume.Name, volumeType, poolID, volume.Config) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 60ecaa5..2784156 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -88,6 +88,24 @@ func storageLVExists(lvName string) (bool, error) { return true, nil } +func lvmGetLVSize(lvPath string) (string, error) { + msg, err := shared.TryRunCommand("lvs", "--noheadings", "-o", "size", "--nosuffix", "--units", "b", lvPath) + if err != nil { + return "", fmt.Errorf("Failed to retrieve size of logical volume: %s: %s.", string(msg), err) + } + + sizeString := string(msg) + sizeString = strings.TrimSpace(sizeString) + size, err := strconv.ParseInt(sizeString, 10, 64) + if err != nil { + return "", err + } + + detectedSize := shared.GetByteSizeString(size, 0) + + return detectedSize, nil +} + func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) { output, err := exec.Command("vgs", "--noheadings", "-o", "lv_attr", fmt.Sprintf("%s/%s", vgName, poolName)).Output() if err != nil {
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel