The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6595
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) === Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
From 63f1dea8ceb0dc8d265b32def4c07522a554545d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Fri, 6 Dec 2019 00:59:34 -0500 Subject: [PATCH] lxd/storage: Port volume attach/detach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage.go | 148 +++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 59 deletions(-) diff --git a/lxd/storage.go b/lxd/storage.go index 86ad48d88a..842ee72577 100644 --- a/lxd/storage.go +++ b/lxd/storage.go @@ -33,11 +33,12 @@ import ( func init() { // Expose storageVolumeMount to the device package as StorageVolumeMount. device.StorageVolumeMount = storageVolumeMount + // Expose storageVolumeUmount to the device package as StorageVolumeUmount. device.StorageVolumeUmount = storageVolumeUmount + // Expose storageRootFSApplyQuota to the device package as StorageRootFSApplyQuota. device.StorageRootFSApplyQuota = storageRootFSApplyQuota - } // lxdStorageLockMap is a hashmap that allows functions to check whether the @@ -413,18 +414,24 @@ func storagePoolInit(s *state.State, poolName string) (storage, error) { return storageInit(s, "default", poolName, "", -1) } -func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName string, volumeType int, c *containerLXC) (storage, error) { - st, err := storageInit(s, "default", poolName, volumeName, volumeType) +func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName string, volumeType int, c *containerLXC) error { + // Load the DB records + poolID, pool, err := s.Cluster.StoragePoolGet(poolName) if err != nil { - return nil, err + return err } - poolVolumePut := st.GetStoragePoolVolumeWritable() + _, volume, err := s.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volumeName, volumeType, poolID) + if err != nil { + return err + } + + poolVolumePut := volume.Writable() // Check if unmapped if shared.IsTrue(poolVolumePut.Config["security.unmapped"]) { // No need to look at containers and maps for unmapped volumes - return st, nil + return nil } // Get the on-disk idmap for the volume @@ -433,7 +440,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str lastIdmap, err = idmapsetFromString(poolVolumePut.Config["volatile.idmap.last"]) if err != nil { logger.Errorf("Failed to unmarshal last idmapping: %s", poolVolumePut.Config["volatile.idmap.last"]) - return nil, err + return err } } @@ -447,19 +454,19 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str nextIdmap, err = c.NextIdmap() } if err != nil { - return nil, err + return err } if nextIdmap != nil { nextJsonMap, err = idmapsetToJSON(nextIdmap) if err != nil { - return nil, err + return err } } } poolVolumePut.Config["volatile.idmap.next"] = nextJsonMap - // get mountpoint of storage volume + // Get mountpoint of storage volume remapPath := storagePools.GetStoragePoolVolumeMountPoint(poolName, volumeName) if !nextIdmap.Equals(lastIdmap) { @@ -468,7 +475,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) { volumeUsedBy, err := storagePoolVolumeUsedByInstancesGet(s, "default", poolName, volumeName) if err != nil { - return nil, err + return err } if len(volumeUsedBy) > 1 { @@ -491,11 +498,11 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str ctNextIdmap, err = ct.NextIdmap() } if err != nil { - return nil, fmt.Errorf("Failed to retrieve idmap of container") + return fmt.Errorf("Failed to retrieve idmap of container") } if !nextIdmap.Equals(ctNextIdmap) { - return nil, fmt.Errorf("Idmaps of container %v and storage volume %v are not identical", ctName, volumeName) + return fmt.Errorf("Idmaps of container %v and storage volume %v are not identical", ctName, volumeName) } } } else if len(volumeUsedBy) == 1 { @@ -503,54 +510,44 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str // we can shift the storage volume. // I'm not sure if we want some locking here. if volumeUsedBy[0] != c.Name() { - return nil, fmt.Errorf("idmaps of container and storage volume are not identical") + return fmt.Errorf("idmaps of container and storage volume are not identical") } } } - // mount storage volume - ourMount, err := st.StoragePoolVolumeMount() - if err != nil { - return nil, err - } - if ourMount { - defer func() { - _, err := st.StoragePoolVolumeUmount() - if err != nil { - logger.Warnf("Failed to unmount storage volume") - } - }() - } - - // unshift rootfs + // Unshift rootfs if lastIdmap != nil { var err error - if st.GetStorageType() == storageTypeZfs { + if pool.Driver == "zfs" { err = lastIdmap.UnshiftRootfs(remapPath, zfsIdmapSetSkipper) } else { err = lastIdmap.UnshiftRootfs(remapPath, nil) } + if err != nil { logger.Errorf("Failed to unshift \"%s\"", remapPath) - return nil, err + return err } + logger.Debugf("Unshifted \"%s\"", remapPath) } - // shift rootfs + // Shift rootfs if nextIdmap != nil { var err error - if st.GetStorageType() == storageTypeZfs { + if pool.Driver == "zfs" { err = nextIdmap.ShiftRootfs(remapPath, zfsIdmapSetSkipper) } else { err = nextIdmap.ShiftRootfs(remapPath, nil) } + if err != nil { logger.Errorf("Failed to shift \"%s\"", remapPath) - return nil, err + return err } + logger.Debugf("Shifted \"%s\"", remapPath) } logger.Debugf("Shifted storage volume") @@ -562,25 +559,19 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str jsonIdmap, err = idmapsetToJSON(nextIdmap) if err != nil { logger.Errorf("Failed to marshal idmap") - return nil, err + return err } } - // update last idmap + // Update last idmap poolVolumePut.Config["volatile.idmap.last"] = jsonIdmap - st.SetStoragePoolVolumeWritable(&poolVolumePut) - - poolID, err := s.Cluster.StoragePoolGetID(poolName) - if err != nil { - return nil, err - } err = s.Cluster.StoragePoolVolumeUpdate(volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config) if err != nil { - return nil, err + return err } - return st, nil + return nil } func storagePoolVolumeInit(s *state.State, project, poolName, volumeName string, volumeType int) (storage, error) { @@ -834,14 +825,45 @@ func storageVolumeMount(state *state.State, poolName string, volumeName string, } volumeType, _ := storagePools.VolumeTypeNameToType(volumeTypeName) - s, err := storagePoolVolumeAttachInit(state, poolName, volumeName, volumeType, c) - if err != nil { - return err - } + pool, err := storagePools.GetPoolByName(state, poolName) + if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented { + // Mount the storage volume + ourMount, err := pool.MountCustomVolume(volumeName, nil) + if err != nil { + return err + } - _, err = s.StoragePoolVolumeMount() - if err != nil { - return err + if ourMount { + defer pool.UnmountCustomVolume(volumeName, nil) + } + + // Custom storage volumes do not currently support projects, so hardcode "default" project. + err = storagePoolVolumeAttachPrepare(state, poolName, volumeName, volumeType, c) + if err != nil { + return err + } + } else { + // Load the volume + s, err := storageInit(state, "default", poolName, volumeName, volumeType) + if err != nil { + return err + } + + // Mount the storage volume + ourMount, err := s.StoragePoolVolumeMount() + if err != nil { + return err + } + + if ourMount { + defer s.StoragePoolVolumeUmount() + } + + // Custom storage volumes do not currently support projects, so hardcode "default" project. + err = storagePoolVolumeAttachPrepare(state, poolName, volumeName, volumeType, c) + if err != nil { + return err + } } return nil @@ -849,15 +871,23 @@ func storageVolumeMount(state *state.State, poolName string, volumeName string, // storageVolumeUmount unmounts a storage volume on a pool. func storageVolumeUmount(state *state.State, poolName string, volumeName string, volumeType int) error { - // Custom storage volumes do not currently support projects, so hardcode "default" project. - s, err := storagePoolVolumeInit(state, "default", poolName, volumeName, volumeType) - if err != nil { - return err - } + pool, err := storagePools.GetPoolByName(state, poolName) + if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented { + _, err = pool.UnmountCustomVolume(volumeName, nil) + if err != nil { + return err + } + } else { + // Custom storage volumes do not currently support projects, so hardcode "default" project. + s, err := storagePoolVolumeInit(state, "default", poolName, volumeName, volumeType) + if err != nil { + return err + } - _, err = s.StoragePoolVolumeUmount() - if err != nil { - return err + _, err = s.StoragePoolVolumeUmount() + if err != nil { + return err + } } return nil
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel