The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/1847
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) ===
From cd6663f2a1cd55448ec6f76b582df21235291c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Sun, 3 Apr 2016 17:14:51 -0400 Subject: [PATCH 1/2] zfs: Dynamically mount/umount filesystems 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_zfs.go | 80 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go index 438d2a7..eb3d4af 100644 --- a/lxd/storage_zfs.go +++ b/lxd/storage_zfs.go @@ -84,10 +84,24 @@ func (s *storageZfs) Init(config map[string]interface{}) (storage, error) { // Things we don't need to care about func (s *storageZfs) ContainerStart(container container) error { + fs := fmt.Sprintf("containers/%s", container.Name()) + + err := s.zfsMount(fs) + if err != nil && !s.zfsMounted(fs) { + return err + } + return nil } func (s *storageZfs) ContainerStop(container container) error { + fs := fmt.Sprintf("containers/%s", container.Name()) + + err := s.zfsUnmount(fs) + if err != nil { + return err + } + return nil } @@ -101,6 +115,12 @@ func (s *storageZfs) ContainerCreate(container container) error { return err } + err = s.zfsMount(fs) + if err != nil && !s.zfsMounted(fs) { + return err + } + defer s.zfsUnmount(fs) + err = os.Symlink(cPath+".zfs", cPath) if err != nil { return err @@ -140,6 +160,12 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s return err } + err = s.zfsMount(fs) + if err != nil && !s.zfsMounted(fs) { + return err + } + defer s.zfsUnmount(fs) + err = os.Symlink(cPath+".zfs", cPath) if err != nil { return err @@ -288,6 +314,12 @@ func (s *storageZfs) ContainerCopy(container container, sourceContainer containe return err } + err = s.zfsMount(destFs) + if err != nil && !s.zfsMounted(destFs) { + return nil + } + defer s.zfsUnmount(destFs) + cPath := container.Path() err = os.Symlink(cPath+".zfs", cPath) if err != nil { @@ -311,6 +343,12 @@ func (s *storageZfs) ContainerCopy(container container, sourceContainer containe return err } + err = s.zfsMount(destFs) + if err != nil && !s.zfsMounted(destFs) { + return nil + } + defer s.zfsUnmount(destFs) + output, err := storageRsyncCopy(sourceContainer.Path(), container.Path()) if err != nil { return fmt.Errorf("rsync failed: %s", string(output)) @@ -358,20 +396,6 @@ func (s *storageZfs) ContainerRename(container container, newName string) error return err } - // In case ZFS didn't mount the filesystem, do it ourselves - if !shared.PathExists(shared.VarPath(fmt.Sprintf("containers/%s.zfs", newName))) { - for i := 0; i < 20; i++ { - err = s.zfsMount(fmt.Sprintf("containers/%s", newName)) - if err == nil { - break - } - time.Sleep(500 * time.Millisecond) - } - if err != nil { - return err - } - } - // In case the change of mountpoint didn't remove the old path, do it ourselves if shared.PathExists(shared.VarPath(fmt.Sprintf("containers/%s.zfs", oldName))) { err = os.Remove(shared.VarPath(fmt.Sprintf("containers/%s.zfs", oldName))) @@ -571,6 +595,11 @@ func (s *storageZfs) ContainerSnapshotStart(container container) error { return err } + err = s.zfsMount(destFs) + if err != nil && !s.zfsMounted(destFs) { + return nil + } + return nil } @@ -583,7 +612,12 @@ func (s *storageZfs) ContainerSnapshotStop(container container) error { sName := fields[1] destFs := fmt.Sprintf("snapshots/%s/%s", cName, sName) - err := s.zfsDestroy(destFs) + err := s.zfsUnmount(destFs) + if err != nil { + return nil + } + + err = s.zfsDestroy(destFs) if err != nil { return err } @@ -622,6 +656,12 @@ func (s *storageZfs) ImageCreate(fingerprint string) error { return err } + err = s.zfsMount(fs) + if err != nil && !s.zfsMounted(fs) { + return err + } + defer s.zfsUnmount(fs) + err = untarImage(imagePath, subvol) if err != nil { return err @@ -701,6 +741,7 @@ func (s *storageZfs) zfsClone(source string, name string, dest string, dotZfs bo "clone", "-p", "-o", fmt.Sprintf("mountpoint=%s", mountpoint), + "-o", "canmount=noauto", fmt.Sprintf("%s/%s@%s", s.zfsPool, source, name), fmt.Sprintf("%s/%s", s.zfsPool, dest)).CombinedOutput() if err != nil { @@ -734,6 +775,7 @@ func (s *storageZfs) zfsClone(source string, name string, dest string, dotZfs bo "clone", "-p", "-o", fmt.Sprintf("mountpoint=%s", mountpoint), + "-o", "canmount=noauto", fmt.Sprintf("%s/%s@%s", s.zfsPool, sub, name), fmt.Sprintf("%s/%s", s.zfsPool, destSubvol)).CombinedOutput() if err != nil { @@ -751,6 +793,7 @@ func (s *storageZfs) zfsCreate(path string) error { "create", "-p", "-o", fmt.Sprintf("mountpoint=%s.zfs", shared.VarPath(path)), + "-o", "canmount=noauto", fmt.Sprintf("%s/%s", s.zfsPool, path)).CombinedOutput() if err != nil { s.log.Error("zfs create failed", log.Ctx{"output": string(output)}) @@ -979,6 +1022,10 @@ func (s *storageZfs) zfsSnapshotRename(path string, oldName string, newName stri } func (s *storageZfs) zfsUnmount(path string) error { + if !s.zfsMounted(path) { + return nil + } + output, err := exec.Command( "zfs", "unmount", @@ -1363,9 +1410,8 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []c * before doing a recv. */ zfsName := fmt.Sprintf("containers/%s", container.Name()) - fsPath := shared.VarPath(fmt.Sprintf("containers/%s.zfs", container.Name())) for i := 0; i < 20; i++ { - if shared.IsMountPoint(fsPath) || s.zfsMounted(zfsName) { + if s.zfsMounted(zfsName) { if err := s.zfsUnmount(zfsName); err != nil { shared.Log.Error("zfs umount error for", "path", zfsName, "err", err) } From 061abc91c5fd086981a7692066417b2d057f8c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Sun, 3 Apr 2016 17:19:46 -0400 Subject: [PATCH 2/2] Stop container storage after startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need keeping the mount on the host. Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/container_lxc.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go index 7262e00..1cc62d2 100644 --- a/lxd/container_lxc.go +++ b/lxd/container_lxc.go @@ -1151,9 +1151,15 @@ func (c *containerLXC) Start(stateful bool) error { return err } + err = c.StorageStop() + if err != nil { + return err + } + os.RemoveAll(c.StatePath()) c.stateful = false return dbContainerSetStateful(c.daemon.db, c.id, false) + } else if c.stateful { /* stateless start required when we have state, let's delete it */ err := os.RemoveAll(c.StatePath()) @@ -1191,6 +1197,11 @@ func (c *containerLXC) Start(stateful bool) error { err) } + err = c.StorageStop() + if err != nil { + return err + } + return nil } @@ -1433,13 +1444,6 @@ func (c *containerLXC) OnStop(target string) error { // Make sure we can't call go-lxc functions by mistake c.fromHook = true - // Stop the storage for this container - err := c.StorageStop() - if err != nil { - wg.Done() - return err - } - // Unload the apparmor profile AAUnloadProfile(c) @@ -1474,7 +1478,7 @@ func (c *containerLXC) OnStop(target string) error { } // Clean all the unix devices - err = c.removeUnixDevices() + err := c.removeUnixDevices() if err != nil { shared.Log.Error("Unable to remove unix devices", log.Ctx{"err": err}) }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel