[lxc-devel] [lxd/master] [RFC] storage: custom storage volume snapshot API

monstermunchkin on Github lxc-bot at linuxcontainers.org
Thu Aug 23 14:52:47 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180823/81f4ac36/attachment.bin>
-------------- next part --------------
From 3c33c79c9c6a4f4db524ae14f337107bfdbc8c04 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 11:24:29 +0200
Subject: [PATCH 01/81] db: add StorageVolumeKind to indicate snapshots

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/storage_volumes.go | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 6ba9721051..eaeec607da 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -4,10 +4,41 @@ import (
 	"database/sql"
 	"fmt"
 	"sort"
+	"time"
 
 	"github.com/lxc/lxd/lxd/db/query"
 )
 
+// StorageVolumeArgs is a value object holding all db-related details about a
+// storage volume.
+type StorageVolumeArgs struct {
+	Name string
+
+	// At least one of Type or TypeName must be set.
+	Type     int
+	TypeName string
+
+	// At least one of PoolID or PoolName must be set.
+	PoolID   int64
+	PoolName string
+
+	Kind StorageVolumeKind
+
+	Config       map[string]string
+	Description  string
+	CreationDate time.Time
+}
+
+// StorageVolumeKind encodes the type of storage volume (either regular or snapshot).
+type StorageVolumeKind int
+
+// Numerical codes for storage volume types.
+const (
+	StorageVolumeKindValid    StorageVolumeKind = 0
+	StorageVolumeKindRegular  StorageVolumeKind = 0
+	StorageVolumeKindSnapshot StorageVolumeKind = 1
+)
+
 // StorageVolumeNodeAddresses returns the addresses of all nodes on which the
 // volume with the given name if defined.
 //

From 4839145c2a1e2018607b45a8589dbf96f51cc411 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 11:25:05 +0200
Subject: [PATCH 02/81] db: update schema

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/cluster/schema.go |  3 ++-
 lxd/db/cluster/update.go | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index cd15668986..5e885244e8 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -234,6 +234,7 @@ CREATE TABLE storage_volumes (
     node_id INTEGER NOT NULL,
     type INTEGER NOT NULL,
     description TEXT,
+    kind INTEGER NOT NULL DEFAULT 0,
     UNIQUE (storage_pool_id, node_id, name, type),
     FOREIGN KEY (storage_pool_id) REFERENCES storage_pools (id) ON DELETE CASCADE,
     FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
@@ -247,5 +248,5 @@ CREATE TABLE storage_volumes_config (
     FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
 );
 
-INSERT INTO schema (version, updated_at) VALUES (10, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (11, strftime("%s"))
 `
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index c4fbc0a32e..c4a7613fdd 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -40,14 +40,24 @@ var updates = map[int]schema.Update{
 	8:  updateFromV7,
 	9:  updateFromV8,
 	10: updateFromV9,
+	11: updateFromV10,
+}
+
+func updateFromV10(tx *sql.Tx) error {
+	stmt := `
+ALTER TABLE storage_volumes ADD COLUMN kind INTEGER NOT NULL DEFAULT 0;
+UPDATE storage_volumes SET kind = 0;
+`
+	_, err := tx.Exec(stmt)
+	return err
 }
 
 // Add a new 'type' column to the operations table.
 func updateFromV9(tx *sql.Tx) error {
 	stmts := `
 	ALTER TABLE operations ADD COLUMN type INTEGER NOT NULL DEFAULT 0;
-        UPDATE operations SET type = 0;
-`
+	UPDATE operations SET type = 0;
+	`
 	_, err := tx.Exec(stmts)
 	return err
 }

From ae6dc819058e247a21e62e1c9cfe7fc76539b4e2 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 15:37:57 +0200
Subject: [PATCH 03/81] patches: patchStorageApiRenameContainerSnapshotsDir()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/patches.go | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/lxd/patches.go b/lxd/patches.go
index 7ae943ed2c..5f8a340617 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -60,6 +60,7 @@ var patches = []patch{
 	{name: "lvm_node_specific_config_keys", run: patchLvmNodeSpecificConfigKeys},
 	{name: "candid_rename_config_key", run: patchCandidConfigKey},
 	{name: "move_backups", run: patchMoveBackups},
+	{name: "storage_api_rename_container_snapshots_dir", run: patchStorageApiRenameContainerSnapshotsDir},
 }
 
 type patch struct {
@@ -3069,6 +3070,36 @@ func patchMoveBackups(name string, d *Daemon) error {
 	return nil
 }
 
+func patchStorageApiRenameContainerSnapshotsDir(name string, d *Daemon) error {
+	storagePoolsPath := shared.VarPath("storage-pools")
+	storagePoolsDir, err := os.Open(storagePoolsPath)
+	if err != nil {
+		return err
+	}
+
+	// Get a list of all storage pools.
+	storagePoolNames, err := storagePoolsDir.Readdirnames(-1)
+	storagePoolsDir.Close()
+	if err != nil {
+		return err
+	}
+
+	for _, poolName := range storagePoolNames {
+		containerSnapshotDirOld := shared.VarPath("storage-pools", poolName, "snapshots")
+		containerSnapshotDirNew := shared.VarPath("storage-pools", poolName, "containers-snapshots")
+		err := shared.FileMove(containerSnapshotDirOld, containerSnapshotDirNew)
+		if err != nil {
+			if os.IsNotExist(err) {
+				continue
+			}
+
+			return err
+		}
+	}
+
+	return nil
+}
+
 // Patches end here
 
 // Here are a couple of legacy patches that were originally in

From 7d24d7a576adcb86d813a00462bff9fa18543695 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 14:21:36 +0200
Subject: [PATCH 04/81] storage: s/snapshots/containers-snapshots/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/api_internal.go           |  6 ++----
 lxd/backup.go                 |  2 +-
 lxd/container_post.go         |  3 +--
 lxd/storage.go                |  2 +-
 lxd/storage_btrfs.go          | 15 ++++++++-------
 lxd/storage_ceph.go           | 20 ++++----------------
 lxd/storage_ceph_migration.go | 12 ++----------
 lxd/storage_ceph_utils.go     |  2 +-
 lxd/storage_dir.go            |  8 +++-----
 lxd/storage_lvm.go            |  7 +++----
 lxd/storage_lvm_utils.go      |  4 ++--
 lxd/storage_zfs.go            | 12 ++++++------
 12 files changed, 34 insertions(+), 59 deletions(-)

diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 84b67dfea7..6c399a22c3 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -398,8 +398,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	}
 
 	// Read in the backup.yaml file.
-	backupYamlPath := shared.VarPath("storage-pools", containerPoolName,
-		"containers", req.Name, "backup.yaml")
+	backupYamlPath := shared.VarPath("storage-pools", containerPoolName, "containers", req.Name, "backup.yaml")
 	backup, err := slurpBackupFile(backupYamlPath)
 	if err != nil {
 		return SmartError(err)
@@ -872,8 +871,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		snapshotMountPoint := getSnapshotMountPoint(backup.Pool.Name,
 			snap.Name)
 		sourceName, _, _ := containerGetParentAndSnapshotName(snap.Name)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools",
-			backup.Pool.Name, "snapshots", sourceName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", backup.Pool.Name, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 		err = createSnapshotMountpoint(snapshotMountPoint,
 			snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
diff --git a/lxd/backup.go b/lxd/backup.go
index d17b256a64..af39640867 100644
--- a/lxd/backup.go
+++ b/lxd/backup.go
@@ -279,7 +279,7 @@ func backupFixStoragePool(c *db.Cluster, b backupInfo) error {
 	}
 
 	for _, snap := range b.Snapshots {
-		err = f(shared.VarPath("storage-pools", pool.Name, "snapshots", b.Name, snap,
+		err = f(shared.VarPath("storage-pools", pool.Name, "containers-snapshots", b.Name, snap,
 			"backup.yaml"))
 		if err != nil {
 			return err
diff --git a/lxd/container_post.go b/lxd/container_post.go
index d0f9717e51..fbca1d77dd 100644
--- a/lxd/container_post.go
+++ b/lxd/container_post.go
@@ -532,8 +532,7 @@ func containerPostCreateContainerMountPoint(d *Daemon, containerName string) err
 
 	for _, snapshotName := range snapshotNames {
 		mntPoint := getSnapshotMountPoint(poolName, snapshotName)
-		snapshotsSymlinkTarget := shared.VarPath("storage-pools",
-			poolName, "snapshots", containerName)
+		snapshotsSymlinkTarget := shared.VarPath("storage-pools", poolName, "containers-snapshots", containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 		err := createSnapshotMountpoint(mntPoint, snapshotsSymlinkTarget, snapshotMntPointSymlink)
 		if err != nil {
diff --git a/lxd/storage.go b/lxd/storage.go
index 6d6b98baac..f3ec69e26e 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -582,7 +582,7 @@ func getContainerMountPoint(poolName string, containerName string) string {
 
 // ${LXD_DIR}/storage-pools/<pool>/snapshots/<snapshot_name>
 func getSnapshotMountPoint(poolName string, snapshotName string) string {
-	return shared.VarPath("storage-pools", poolName, "snapshots", snapshotName)
+	return shared.VarPath("storage-pools", poolName, "containers-snapshots", snapshotName)
 }
 
 // ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index a39b4cb21f..73a16aaa17 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -51,7 +51,7 @@ func (s *storageBtrfs) getContainerSubvolumePath(poolName string) string {
 
 // ${LXD_DIR}/storage-pools/<pool>/snapshots
 func getSnapshotSubvolumePath(poolName string, containerName string) string {
-	return shared.VarPath("storage-pools", poolName, "snapshots", containerName)
+	return shared.VarPath("storage-pools", poolName, "containers-snapshots", containerName)
 }
 
 // ${LXD_DIR}/storage-pools/<pool>/images
@@ -947,7 +947,7 @@ func (s *storageBtrfs) copySnapshot(target container, source container) error {
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
 	containersPath := getSnapshotMountPoint(s.pool.Name, targetParentName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", targetParentName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", targetParentName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", targetParentName)
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	if err != nil {
@@ -1281,7 +1281,7 @@ func (s *storageBtrfs) doContainerSnapshotCreate(targetName string, sourceName s
 		}
 	}
 
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", s.volume.Name)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", s.volume.Name)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 	if !shared.PathExists(snapshotMntPointSymlink) {
 		if !shared.PathExists(snapshotMntPointSymlinkTarget) {
@@ -1469,7 +1469,7 @@ func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container)
 		return err
 	}
 
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", sourceName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 	if !shared.PathExists(snapshotMntPointSymlink) {
 		err := createContainerMountpoint(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink, snapshotContainer.IsPrivileged())
@@ -1532,6 +1532,7 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
 			// Figure out previous and current subvolumes
 			prev := ""
 			if i > 0 {
+				// /var/lib/lxd/storage-pools/<pool>/containers-snapshots/<container>/<snapshot>
 				prev = getSnapshotMountPoint(s.pool.Name, snapshots[i-1].Name())
 			}
 			cur := getSnapshotMountPoint(s.pool.Name, snap.Name())
@@ -1739,7 +1740,7 @@ func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.R
 
 		// create mountpoint
 		snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, containerName)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", containerName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 		err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 		if err != nil {
@@ -2578,7 +2579,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 			return err
 		}
 
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", containerPool, "snapshots", containerName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", containerPool, "containers-snapshots", containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -2625,7 +2626,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 				return err
 			}
 
-			snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", containerName)
+			snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", containerName)
 			snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 			err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 2dd3ccd0af..106a2283af 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -1249,20 +1249,9 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 				s.pool.Name,
 				newTargetName)
 
-			snapshotMntPointSymlinkTarget := shared.VarPath(
-				"storage-pools",
-				s.pool.Name,
-				"snapshots",
-				targetContainerName)
-
-			snapshotMntPointSymlink := shared.VarPath(
-				"snapshots",
-				targetContainerName)
-
-			err := createSnapshotMountpoint(
-				containersPath,
-				snapshotMntPointSymlinkTarget,
-				snapshotMntPointSymlink)
+			snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", targetContainerName)
+			snapshotMntPointSymlink := shared.VarPath("snapshots", targetContainerName)
+			err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
 				logger.Errorf(`Failed to create mountpoint "%s", snapshot symlink target "%s", snapshot mountpoint symlink"%s" for RBD storage volume "%s" on storage pool "%s": %s`, containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink, s.volume.Name, s.pool.Name, err)
 				return err
@@ -1664,8 +1653,7 @@ func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer container) error
 		logger.Debugf(`Deleted snapshot directory  "%s" of RBD snapshot "%s" of container "%s" on storage pool "%s"`, snapshotContainerPath, sourceContainerSnapOnlyName, sourceContainerName, s.OSDPoolName)
 
 		// remove the snapshot symlink if possible
-		snapshotSymlink := shared.VarPath("snapshots",
-			sourceContainerName)
+		snapshotSymlink := shared.VarPath("snapshots", sourceContainerName)
 		if shared.PathExists(snapshotSymlink) {
 			err := os.Remove(snapshotSymlink)
 			if err != nil {
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index dfab3dafe7..f88fda821b 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -260,16 +260,8 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	}
 
 	if len(snapshots) > 0 {
-		snapshotMntPointSymlinkTarget := shared.VarPath(
-			"storage-pools",
-			s.pool.Name,
-			"snapshots",
-			containerName)
-
-		snapshotMntPointSymlink := shared.VarPath(
-			"snapshots",
-			containerName)
-
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", containerName)
+		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(
 				snapshotMntPointSymlinkTarget,
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 9a75f2b4e2..a0cb65de77 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -1882,7 +1882,7 @@ func (s *storageCeph) doContainerSnapshotCreate(targetName string, sourceName st
 
 	targetContainerMntPoint := getSnapshotMountPoint(s.pool.Name, targetName)
 	sourceOnlyName, _, _ := containerGetParentAndSnapshotName(sourceName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", sourceOnlyName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceOnlyName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", sourceOnlyName)
 	err = createSnapshotMountpoint(targetContainerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	if err != nil {
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index ba63a7597d..64413d4993 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -634,7 +634,7 @@ func (s *storageDir) copySnapshot(target container, targetPool string, source co
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
 	containersPath := getSnapshotMountPoint(targetPool, targetParentName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", targetPool, "snapshots", targetParentName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", targetPool, "containers-snapshots", targetParentName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", targetParentName)
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	if err != nil {
@@ -936,8 +936,7 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 	targetContainerMntPoint = getSnapshotMountPoint(s.pool.Name,
 		targetContainerName)
 	sourceName, _, _ := containerGetParentAndSnapshotName(targetContainerName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools",
-		s.pool.Name, "snapshots", sourceName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 	err = createSnapshotMountpoint(targetContainerMntPoint,
 		snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1151,8 +1150,7 @@ func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker) er
 	if len(info.Snapshots) > 0 {
 		// Create mountpoints
 		snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, info.Name)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name,
-			"snapshots", info.Name)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", info.Name)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", info.Name)
 		err := createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget,
 			snapshotMntPointSymlink)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 036761210e..ce9a103dbb 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -899,7 +899,7 @@ func (s *storageLvm) ContainerCreate(container container) error {
 	if container.IsSnapshot() {
 		containerMntPoint := getSnapshotMountPoint(s.pool.Name, containerName)
 		sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", sourceName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 		err := os.MkdirAll(containerMntPoint, 0711)
 		if err != nil {
@@ -1045,7 +1045,7 @@ func lvmContainerDeleteInternal(poolName string, ctName string, isSnapshot bool,
 	var err error
 	if isSnapshot {
 		sourceName, _, _ := containerGetParentAndSnapshotName(ctName)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", poolName, "snapshots", sourceName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", poolName, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 		err = deleteSnapshotMountpoint(containerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	} else {
@@ -1779,8 +1779,7 @@ func (s *storageLvm) doContainerBackupLoad(containerName string, privileged bool
 	if snapshot {
 		cname, _, _ := containerGetParentAndSnapshotName(containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", cname)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots",
-			cname)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", cname)
 		err = createSnapshotMountpoint(containerMntPoint, snapshotMntPointSymlinkTarget,
 			snapshotMntPointSymlink)
 	} else {
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index f685279521..3a6036a0d2 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -269,7 +269,7 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 	if targetIsSnapshot {
 		targetContainerMntPoint = getSnapshotMountPoint(s.pool.Name, targetContainerName)
 		sourceName, _, _ := containerGetParentAndSnapshotName(sourceContainerName)
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", sourceName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
 		err = createSnapshotMountpoint(targetContainerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	} else {
@@ -332,7 +332,7 @@ func (s *storageLvm) copySnapshot(target container, source container) error {
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
 	containersPath := getSnapshotMountPoint(s.pool.Name, targetParentName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", targetParentName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", targetParentName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", targetParentName)
 	err = createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	if err != nil {
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index d96eaae42e..5515ce0b7c 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -323,7 +323,7 @@ func (s *storageZfs) zfsPoolCreate() error {
 		return err
 	}
 
-	fixperms = shared.VarPath("storage-pools", s.pool.Name, "snapshots")
+	fixperms = shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots")
 	err = os.MkdirAll(fixperms, snapshotsDirMode)
 	if err != nil && !os.IsNotExist(err) {
 		return err
@@ -1089,7 +1089,7 @@ func (s *storageZfs) copyWithSnapshots(target container, source container, paren
 	sourceName := source.Name()
 	targetParentName, targetSnapOnlyName, _ := containerGetParentAndSnapshotName(target.Name())
 	containersPath := getSnapshotMountPoint(s.pool.Name, targetParentName)
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", targetParentName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", targetParentName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", targetParentName)
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	if err != nil {
@@ -1532,7 +1532,7 @@ func (s *storageZfs) doContainerSnapshotCreate(targetName string, sourceName str
 		}
 	}
 
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", sourceName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", sourceName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", sourceContainerName)
 	if !shared.PathExists(snapshotMntPointSymlink) {
 		err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1703,7 +1703,7 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 		}
 	}
 
-	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", oldcName)
+	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", oldcName)
 	snapshotMntPointSymlink := shared.VarPath("snapshots", oldcName)
 	if !shared.PathExists(snapshotMntPointSymlink) {
 		err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -2106,7 +2106,7 @@ func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.Rea
 
 		// create mountpoint
 		snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, fmt.Sprintf("%s/%s", containerName, snapshotOnlyName))
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", containerName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
 		err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 		if err != nil {
@@ -2639,7 +2639,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 	}
 
 	if len(snapshots) > 0 {
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "snapshots", s.volume.Name)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", s.volume.Name)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", container.Name())
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)

From e55d01cf6780be66023be385c4261cc4a239e3a3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 23:08:39 +0200
Subject: [PATCH 05/81] test: s/snapshots/containers-snapshots/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/api_internal.go   |  3 +--
 lxd/storage_dir.go    | 12 ++++--------
 test/suites/backup.sh | 16 ++++++++--------
 3 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 6c399a22c3..a9c914fc32 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -873,8 +873,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		sourceName, _, _ := containerGetParentAndSnapshotName(snap.Name)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", backup.Pool.Name, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
-		err = createSnapshotMountpoint(snapshotMountPoint,
-			snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
+		err = createSnapshotMountpoint(snapshotMountPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 		if err != nil {
 			return InternalError(err)
 		}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 64413d4993..bcbacbf0dd 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1133,16 +1133,14 @@ func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker) er
 
 	// Create mountpoints
 	containerMntPoint := getContainerMountPoint(s.pool.Name, info.Name)
-	err = createContainerMountpoint(containerMntPoint, containerPath(info.Name, false),
-		info.Privileged)
+	err = createContainerMountpoint(containerMntPoint, containerPath(info.Name, false), info.Privileged)
 	if err != nil {
 		return err
 	}
 
 	// Extract container
 	data.Seek(0, 0)
-	err = shared.RunCommandWithFds(data, nil, "tar", "-xJf",
-		"-", "--strip-components=2", "--xattrs-include=*", "-C", containerMntPoint, "backup/container")
+	err = shared.RunCommandWithFds(data, nil, "tar", "-xJf", "-", "--strip-components=2", "--xattrs-include=*", "-C", containerMntPoint, "backup/container")
 	if err != nil {
 		return err
 	}
@@ -1152,16 +1150,14 @@ func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker) er
 		snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, info.Name)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", info.Name)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", info.Name)
-		err := createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget,
-			snapshotMntPointSymlink)
+		err := createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 		if err != nil {
 			return err
 		}
 
 		// Extract snapshots
 		data.Seek(0, 0)
-		err = shared.RunCommandWithFds(data, nil, "tar", "-xJf", "-",
-			"--strip-components=2", "--xattrs-include=*", "-C", snapshotMntPoint, "backup/snapshots")
+		err = shared.RunCommandWithFds(data, nil, "tar", "-xJf", "-", "--strip-components=2", "--xattrs-include=*", "-C", snapshotMntPoint, "backup/snapshots")
 		if err != nil {
 			return err
 		}
diff --git a/test/suites/backup.sh b/test/suites/backup.sh
index d11b90fdc6..042b5948c9 100644
--- a/test/suites/backup.sh
+++ b/test/suites/backup.sh
@@ -104,7 +104,7 @@ test_container_import() {
     lxc start ctImport
     rm "${LXD_DIR}/containers/ctImport"
     if [ "$lxd_backend" != "dir" ] && [ "$lxd_backend" != "btrfs" ]; then
-      rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
+      rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
     fi
     pid=$(lxc info ctImport | grep ^Pid | awk '{print $2}')
     kill_lxc "${pid}"
@@ -116,7 +116,7 @@ test_container_import() {
     lxc info ctImport | grep snap0
     [ -L "${LXD_DIR}/containers/ctImport" ] && [ -d "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers/ctImport" ]
     if [ "$lxd_backend" != "dir" ] && [ "$lxd_backend" != "btrfs" ]; then
-      [ -L "${LXD_DIR}/snapshots/ctImport" ] && [ -d "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0" ]
+      [ -L "${LXD_DIR}/snapshots/ctImport" ] && [ -d "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0" ]
     fi
     lxc start ctImport
     lxc delete --force ctImport
@@ -126,8 +126,8 @@ test_container_import() {
     lxc start ctImport
     case "$lxd_backend" in
       btrfs)
-        btrfs subvolume delete "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
-        rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
+        btrfs subvolume delete "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
+        rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
         ;;
       ceph)
         rbd unmap "lxdtest-$(basename "${LXD_DIR}")/container_ctImport at snapshot_snap0" || true
@@ -135,7 +135,7 @@ test_container_import() {
         rbd snap rm "lxdtest-$(basename "${LXD_DIR}")/container_ctImport at snapshot_snap0"
         ;;
       dir)
-        rm -r "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
+        rm -r "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
         ;;
       lvm)
         lvremove -f "lxdtest-$(basename "${LXD_DIR}")/containers_ctImport-snap0"
@@ -158,8 +158,8 @@ test_container_import() {
     lxc start ctImport
     case "$lxd_backend" in
       btrfs)
-        btrfs subvolume delete "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
-        rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
+        btrfs subvolume delete "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
+        rm -rf "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
         ;;
       ceph)
         rbd unmap "lxdtest-$(basename "${LXD_DIR}")/container_ctImport at snapshot_snap0" || true
@@ -167,7 +167,7 @@ test_container_import() {
         rbd snap rm "lxdtest-$(basename "${LXD_DIR}")/container_ctImport at snapshot_snap0"
         ;;
       dir)
-        rm -r "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/snapshots/ctImport/snap0"
+        rm -r "${LXD_DIR}/storage-pools/lxdtest-$(basename "${LXD_DIR}")/containers-snapshots/ctImport/snap0"
         ;;
       lvm)
         lvremove -f "lxdtest-$(basename "${LXD_DIR}")/containers_ctImport-snap0"

From 8538196f3686e6863f594603acbe0b669c4b3161 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 16:00:40 +0200
Subject: [PATCH 06/81] storage: add getStoragePoolVolumeSnapshotMountPoint()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 5 +++++
 lxd/storage_btrfs.go | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index f3ec69e26e..996cabf285 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -595,6 +595,11 @@ func getStoragePoolVolumeMountPoint(poolName string, volumeName string) string {
 	return shared.VarPath("storage-pools", poolName, "custom", volumeName)
 }
 
+// ${LXD_DIR}/storage-pools/<pool>/custom-snapshots/<custom volume name>/<snapshot name>
+func getStoragePoolVolumeSnapshotMountPoint(poolName string, snapshotName string) string {
+	return shared.VarPath("storage-pools", poolName, "custom-snapshots", snapshotName)
+}
+
 func createContainerMountpoint(mountPoint string, mountPointSymlink string, privileged bool) error {
 	var mode os.FileMode
 	if privileged {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 73a16aaa17..95cef13e19 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -49,7 +49,7 @@ func (s *storageBtrfs) getContainerSubvolumePath(poolName string) string {
 	return shared.VarPath("storage-pools", poolName, "containers")
 }
 
-// ${LXD_DIR}/storage-pools/<pool>/snapshots
+// ${LXD_DIR}/storage-pools/<pool>/containers-snapshots
 func getSnapshotSubvolumePath(poolName string, containerName string) string {
 	return shared.VarPath("storage-pools", poolName, "containers-snapshots", containerName)
 }

From 2540f8227fc4de80063017c696cc465d4d52a0cf Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 16:26:24 +0200
Subject: [PATCH 07/81] btrfs: create new "custom-snapshots" subvolume

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 95cef13e19..ab7c478676 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -262,6 +262,12 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
+	dummyDir = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, "")
+	err = btrfsSubVolumeCreate(dummyDir)
+	if err != nil {
+		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
+	}
+
 	err = s.StoragePoolCheck()
 	if err != nil {
 		return err

From 727f508fe8e9faec57858aa5805c24623a6bb8f8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 16:34:05 +0200
Subject: [PATCH 08/81] btrfs: add getCustomSnapshotSubvolumePath()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index ab7c478676..b375f1abf9 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -64,6 +64,11 @@ func (s *storageBtrfs) getCustomSubvolumePath(poolName string) string {
 	return shared.VarPath("storage-pools", poolName, "custom")
 }
 
+// ${LXD_DIR}/storage-pools/<pool>/custom-snapshots
+func (s *storageBtrfs) getCustomSnapshotSubvolumePath(poolName string) string {
+	return shared.VarPath("storage-pools", poolName, "custom-snapshots")
+}
+
 func (s *storageBtrfs) StorageCoreInit() error {
 	s.sType = storageTypeBtrfs
 	typeName, err := storageTypeToString(s.sType)

From 0d500c88e8fa9b251f9326f8aecfe561c53f9454 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 16:26:44 +0200
Subject: [PATCH 09/81] zfs: create new "custom-snapshots" dataset

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_zfs.go | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 5515ce0b7c..5be293fde6 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -333,6 +333,23 @@ func (s *storageZfs) zfsPoolCreate() error {
 		logger.Warnf("Failed to chmod \"%s\" to \"0%s\": %s", fixperms, strconv.FormatInt(int64(snapshotsDirMode), 8), err)
 	}
 
+	dataset = fmt.Sprintf("%s/custom-snapshots", poolName)
+	msg, err = zfsPoolVolumeCreate(dataset, "mountpoint=none")
+	if err != nil {
+		logger.Errorf("Failed to create snapshots dataset: %s", msg)
+		return err
+	}
+
+	fixperms = shared.VarPath("storage-pools", s.pool.Name, "custom-snapshots")
+	err = os.MkdirAll(fixperms, snapshotsDirMode)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+	err = os.Chmod(fixperms, snapshotsDirMode)
+	if err != nil {
+		logger.Warnf("Failed to chmod \"%s\" to \"0%s\": %s", fixperms, strconv.FormatInt(int64(snapshotsDirMode), 8), err)
+	}
+
 	return nil
 }
 

From 34a59656fc260eb64ac3994ed115a5f5697acddf Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Jul 2018 14:08:32 +0200
Subject: [PATCH 10/81] storage: add new custom volume snapshot API entpoints

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 39 +++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 lxd/storage_volumes_snapshot.go

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
new file mode 100644
index 0000000000..bf22cd9529
--- /dev/null
+++ b/lxd/storage_volumes_snapshot.go
@@ -0,0 +1,39 @@
+package main
+
+import (
+	"fmt"
+	"net/http"
+)
+
+var storagePoolVolumeSnapshotsTypeCmd = Command{
+	name: "storage-pools/{pool}/volumes/{type}/{name}/snapshots",
+	post: storagePoolVolumeSnapshotsTypePost,
+	get:  storagePoolVolumeSnapshotsTypeGet,
+}
+
+var storagePoolVolumeSnapshotTypeCmd = Command{
+	name:   "storage-pools/{pool}/volumes/{type}/{name}/snapshots/{snapshotName}",
+	post:   storagePoolVolumeSnapshotTypePost,
+	get:    storagePoolVolumeSnapshotTypeGet,
+	delete: storagePoolVolumeSnapshotTypeDelete,
+}
+
+func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Creating storage pool volume snapshots is not implemented"))
+}
+
+func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Retrieving storage pool volume snapshots is not implemented"))
+}
+
+func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Updating storage pool volume snapshots is not implemented"))
+}
+
+func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Retrieving a storage pool volume snapshot is not implemented"))
+}
+
+func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Deleting storage pool volume snapshots is not implemented"))
+}

From 9c8d2e75860a14f4a44160719ab1ace9054d32f8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Jul 2018 14:18:52 +0200
Subject: [PATCH 11/81] api: add StorageVolumeSnapshot struct

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 shared/api/storage_pool_volume_snapshot.go

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
new file mode 100644
index 0000000000..06f61e9e2d
--- /dev/null
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -0,0 +1,12 @@
+package api
+
+import ()
+
+// StorageVolumeSnapshot represents a LXD storage volume snapshot
+//
+// API extension: storage_api_volume_snapshots
+type StorageVolumeSnapshot struct {
+	Name        string            `json:"name" yaml:"name"`
+	Config      map[string]string `json:"config" yaml:"config"`
+	Description string            `json:"description" yaml:"description"`
+}

From aaf0b5c69447b93ff3217e34ba5d606701731c3e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Jul 2018 14:19:11 +0200
Subject: [PATCH 12/81] api: add StorageVolumeSnapshotPost struct

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
index 06f61e9e2d..f366a85000 100644
--- a/shared/api/storage_pool_volume_snapshot.go
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -2,6 +2,13 @@ package api
 
 import ()
 
+// StorageVolumeSnapshotPost represents the fields required to rename/move a LXD storage volume snapshot
+//
+// API extension: storage_api_volume_snapshots
+type StorageVolumeSnapshotPost struct {
+	Name string `json:"name" yaml:"name"`
+}
+
 // StorageVolumeSnapshot represents a LXD storage volume snapshot
 //
 // API extension: storage_api_volume_snapshots

From 45cf24d2e4b02aac8b4ad49442e544e05190b789 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Jul 2018 14:19:28 +0200
Subject: [PATCH 13/81] api: add StorageVolumeSnapshotsPost struct

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
index f366a85000..0a557e4412 100644
--- a/shared/api/storage_pool_volume_snapshot.go
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -2,6 +2,13 @@ package api
 
 import ()
 
+// StorageVolumeSnapshotsPost represents the fields available for a new LXD storage volume snapshot
+//
+// API extension: storage_api_volume_snapshots
+type StorageVolumeSnapshotsPost struct {
+	Name string `json:"name" yaml:"name"`
+}
+
 // StorageVolumeSnapshotPost represents the fields required to rename/move a LXD storage volume snapshot
 //
 // API extension: storage_api_volume_snapshots

From 2fffc31c94c9a92a63db2878feccaa1e7756afd4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 13:18:32 +0200
Subject: [PATCH 14/81] api: add StorageVolumeSnapshotPut struct

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
index 0a557e4412..8ae0956494 100644
--- a/shared/api/storage_pool_volume_snapshot.go
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -24,3 +24,10 @@ type StorageVolumeSnapshot struct {
 	Config      map[string]string `json:"config" yaml:"config"`
 	Description string            `json:"description" yaml:"description"`
 }
+
+// StorageVolumeSnapshotPut represents the modifiable fields of a LXD storage volume
+//
+// API extension: storage_api_volume_snapshots
+type StorageVolumeSnapshotPut struct {
+	Description string `json:"description" yaml:"description"`
+}

From 18a0d905ba49b008fd8fa0298d0b3ff0acf1bda8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Jul 2018 14:45:21 +0200
Subject: [PATCH 15/81] client: add CreateStoragePoolVolumeSnapshot()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  3 +++
 client/lxd_storage_volumes.go | 23 +++++++++++++++++++++++
 lxd/api_1.0.go                |  2 ++
 3 files changed, 28 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index 5995055fcb..a73a092f6d 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -198,6 +198,9 @@ type ContainerServer interface {
 	MoveStoragePoolVolume(pool string, source ContainerServer, sourcePool string, volume api.StorageVolume, args *StoragePoolVolumeMoveArgs) (op RemoteOperation, err error)
 	MigrateStoragePoolVolume(pool string, volume api.StorageVolumePost) (op Operation, err error)
 
+	// Storage volume snapshot functions ("storage_api_volume_snapshots" API extension)
+	CreateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshot api.StorageVolumeSnapshotsPost) (op Operation, err error)
+
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
 	UpdateCluster(cluster api.ClusterPut, ETag string) (op Operation, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 4d7a91af5f..51262a08b7 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -85,6 +85,29 @@ func (r *ProtocolLXD) CreateStoragePoolVolume(pool string, volume api.StorageVol
 	return nil
 }
 
+// CreateStoragePoolVolumeSnapshot defines a new storage volume
+func (r *ProtocolLXD) CreateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshot api.StorageVolumeSnapshotsPost) (Operation, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	// Send the request
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots",
+		url.QueryEscape(pool),
+		url.QueryEscape(volumeType),
+		url.QueryEscape(volumeName))
+	fmt.Println(path)
+	if r.clusterTarget != "" {
+		path += fmt.Sprintf("?target=%s", r.clusterTarget)
+	}
+	op, _, err := r.queryOperation("POST", path, snapshot, "")
+	if err != nil {
+		return nil, err
+	}
+
+	return op, nil
+}
+
 // MigrateStoragePoolVolume requests that LXD prepares for a storage volume migration
 func (r *ProtocolLXD) MigrateStoragePoolVolume(pool string, volume api.StorageVolumePost) (Operation, error) {
 	if !r.HasExtension("storage_api_remote_volume_handling") {
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index c3a250d8c5..e5739d1f1e 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -76,6 +76,8 @@ var api10 = []Command{
 	storagePoolVolumesCmd,
 	storagePoolVolumesTypeCmd,
 	storagePoolVolumeTypeCmd,
+	storagePoolVolumeSnapshotsTypeCmd,
+	storagePoolVolumeSnapshotTypeCmd,
 }
 
 func api10Get(d *Daemon, r *http.Request) Response {

From 88f97a98aff418a35606f47d3c6ffd49de9ea4b8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 19 Jul 2018 13:27:31 +0200
Subject: [PATCH 16/81] lxc: add snapshot subcommand to lxc storage

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 77 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 872be04b2d..98eeee48d8 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -92,6 +92,10 @@ Unless specified through a prefix, all volume operations affect "custom" (user c
 	storageVolumeShowCmd := cmdStorageVolumeShow{global: c.global, storage: c.storage, storageVolume: c}
 	cmd.AddCommand(storageVolumeShowCmd.Command())
 
+	// Snapshot
+	storageVolumeSnapshotCmd := cmdStorageVolumeSnapshot{global: c.global, storage: c.storage, storageVolume: c}
+	cmd.AddCommand(storageVolumeSnapshotCmd.Command())
+
 	// Unset
 	storageVolumeUnsetCmd := cmdStorageVolumeUnset{global: c.global, storage: c.storage, storageVolume: c, storageVolumeSet: &storageVolumeSetCmd}
 	cmd.AddCommand(storageVolumeUnsetCmd.Command())
@@ -1243,3 +1247,76 @@ func (c *cmdStorageVolumeUnset) Run(cmd *cobra.Command, args []string) error {
 	args = append(args, "")
 	return c.storageVolumeSet.Run(cmd, args)
 }
+
+// Snapshot
+type cmdStorageVolumeSnapshot struct {
+	global        *cmdGlobal
+	storage       *cmdStorage
+	storageVolume *cmdStorageVolume
+
+	flagMode string
+}
+
+func (c *cmdStorageVolumeSnapshot) Command() *cobra.Command {
+	cmd := &cobra.Command{}
+	cmd.Use = i18n.G("snapshot [<remote>:]<pool> <volume> [<snapshot name>]")
+	cmd.Short = i18n.G("Snapshot storage volumes")
+	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
+		`Snapshot storage volumes`))
+
+	cmd.RunE = c.Run
+
+	return cmd
+}
+
+func (c *cmdStorageVolumeSnapshot) Run(cmd *cobra.Command, args []string) error {
+	// Sanity checks
+	exit, err := c.global.CheckArgs(cmd, args, 2, 3)
+	if exit {
+		return err
+	}
+
+	// Parse remote
+	resources, err := c.global.ParseServers(args[0])
+	if err != nil {
+		return err
+	}
+
+	resource := resources[0]
+	if resource.name == "" {
+		return fmt.Errorf(i18n.G("Missing pool name"))
+	}
+
+	client := resource.server
+
+	// Parse the input
+	volName, volType := c.storageVolume.parseVolume("custom", args[1])
+	if volType != "custom" {
+		return fmt.Errorf(i18n.G("Only \"custom\" volumes can be snapshotted"))
+	}
+
+	// Check if the requested storage volume actually exists
+	_, _, err = resource.server.GetStoragePoolVolume(resource.name, volType, volName)
+	if err != nil {
+		return err
+	}
+
+	var snapname string
+	if len(args) < 3 {
+		snapname = ""
+	} else {
+		snapname = args[2]
+	}
+
+	req := api.StorageVolumeSnapshotsPost{
+		Name: snapname,
+	}
+
+	op, err := client.CreateStoragePoolVolumeSnapshot(resource.name, volType, volName, req)
+	if err != nil {
+		return err
+	}
+
+	return op.Wait()
+
+}

From e2d2554db779af417b5257173450a4621f257f5f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 19 Jul 2018 13:33:10 +0200
Subject: [PATCH 17/81] api: add "storage_api_volume_snapshots"

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/version/api.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/shared/version/api.go b/shared/version/api.go
index a81f75099e..a20c4d02dc 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -121,6 +121,7 @@ var APIExtensions = []string{
 	"network_nat_order",
 	"container_full",
 	"candid_authentication",
+	"storage_api_volume_snapshots",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 03197433b83b5e7b4f778442699bfbb4fa60ab5e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 20 Jul 2018 15:11:18 +0200
Subject: [PATCH 18/81] storage: storagePoolVolumeSnapshotsTypePost()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 83 ++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 1 deletion(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index bf22cd9529..ef572b97dc 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -1,8 +1,15 @@
 package main
 
 import (
+	"encoding/json"
 	"fmt"
 	"net/http"
+	"strings"
+
+	"github.com/gorilla/mux"
+
+	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/api"
 )
 
 var storagePoolVolumeSnapshotsTypeCmd = Command{
@@ -19,7 +26,81 @@ var storagePoolVolumeSnapshotTypeCmd = Command{
 }
 
 func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Creating storage pool volume snapshots is not implemented"))
+	// Get the name of the pool.
+	poolName := mux.Vars(r)["pool"]
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the volume.
+	volumeName := mux.Vars(r)["name"]
+
+	// Parse the request.
+	req := api.StorageVolumeSnapshotsPost{}
+	err := json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Get a snapshot name.
+	if req.Name == "" {
+		// i := d.cluster.ContainerNextSnapshot(volumeName)
+		i := 0
+		req.Name = fmt.Sprintf("snap%d", i)
+	}
+
+	// Validate the name
+	if strings.Contains(req.Name, "/") {
+		return BadRequest(fmt.Errorf("Snapshot names may not contain slashes"))
+	}
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Check that the storage volume type is valid.
+	if !shared.IntInSlice(volumeType, supportedVolumeTypes) {
+		return BadRequest(fmt.Errorf("invalid storage volume type \"%d\"", volumeType))
+	}
+
+	// Retrieve ID of the storage pool (and check if the storage pool
+	// exists).
+	poolID, err := d.cluster.StoragePoolGetID(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	response := ForwardedResponseIfTargetIsRemote(d, r)
+	if response != nil {
+		return response
+	}
+
+	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
+	if response != nil {
+		return response
+	}
+
+	// Ensure that the storage volume exists.
+	storage, err := storagePoolVolumeInit(d.State(), poolName, volumeName, volumeType)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	// Start the storage.
+	ourMount, err := storage.StoragePoolVolumeMount()
+	if err != nil {
+		return SmartError(err)
+	}
+	if ourMount {
+		defer storage.StoragePoolVolumeUmount()
+	}
+
+	// // Create new snapshot name.
+	// fullName := fmt.Sprintf("%s%s%s", name, shared.SnapshotDelimiter, req.Name)
+
+	return EmptySyncResponse
 }
 
 func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {

From 61cc66948a8d15295edb3f48150d873a2dac3de0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 11:40:52 +0200
Subject: [PATCH 19/81] db: add kind argument to StoragePoolVolumeCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/container_lxc.go         |  2 +-
 lxd/db/containers_test.go    |  2 +-
 lxd/db/storage_pools.go      | 11 ++++++++---
 lxd/db/storage_pools_test.go |  2 +-
 lxd/patches.go               | 24 ++++++++++++------------
 lxd/storage_shared.go        |  3 ++-
 lxd/storage_volumes_utils.go |  2 +-
 7 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 0beed0e234..a360a34370 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -363,7 +363,7 @@ func containerLXCCreate(s *state.State, args db.ContainerArgs) (container, error
 	}
 
 	// Create a new database entry for the container's storage volume
-	_, err = s.Cluster.StoragePoolVolumeCreate(args.Name, "", storagePoolVolumeTypeContainer, poolID, volumeConfig)
+	_, err = s.Cluster.StoragePoolVolumeCreate(args.Name, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, volumeConfig)
 	if err != nil {
 		c.Delete()
 		return nil, err
diff --git a/lxd/db/containers_test.go b/lxd/db/containers_test.go
index 5f6e84dcb5..11e50ffe12 100644
--- a/lxd/db/containers_test.go
+++ b/lxd/db/containers_test.go
@@ -69,7 +69,7 @@ func TestContainerPool(t *testing.T) {
 
 	poolID, err := cluster.StoragePoolCreate("default", "", "dir", nil)
 	require.NoError(t, err)
-	_, err = cluster.StoragePoolVolumeCreate("c1", "", db.StoragePoolVolumeTypeContainer, poolID, nil)
+	_, err = cluster.StoragePoolVolumeCreate("c1", "", db.StoragePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, nil)
 	require.NoError(t, err)
 
 	args := db.ContainerArgs{
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 4a4f507250..2a14acf410 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -905,8 +905,13 @@ func storagePoolVolumeReplicateIfCeph(tx *sql.Tx, volumeID int64, volumeName str
 
 // StoragePoolVolumeCreate creates a new storage volume attached to a given
 // storage pool.
-func (c *Cluster) StoragePoolVolumeCreate(volumeName, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string) (int64, error) {
+func (c *Cluster) StoragePoolVolumeCreate(volumeName, volumeDescription string, volumeType int, volumeKind StorageVolumeKind, poolID int64, volumeConfig map[string]string) (int64, error) {
 	var thisVolumeID int64
+
+	if volumeKind < StorageVolumeKindValid {
+		return -1, fmt.Errorf("Invalid storage volume kind %d specified", volumeKind)
+	}
+
 	err := c.Transaction(func(tx *ClusterTx) error {
 		nodeIDs := []int{int(c.nodeID)}
 		driver, err := storagePoolDriverGet(tx.tx, poolID)
@@ -923,9 +928,9 @@ func (c *Cluster) StoragePoolVolumeCreate(volumeName, volumeDescription string,
 
 		for _, nodeID := range nodeIDs {
 			result, err := tx.tx.Exec(`
-INSERT INTO storage_volumes (storage_pool_id, node_id, type, name, description) VALUES (?, ?, ?, ?, ?)
+INSERT INTO storage_volumes (storage_pool_id, node_id, type, kind, name, description) VALUES (?, ?, ?, ?, ?, ?)
 `,
-				poolID, nodeID, volumeType, volumeName, volumeDescription)
+				poolID, nodeID, volumeType, volumeKind, volumeName, volumeDescription)
 			if err != nil {
 				return err
 			}
diff --git a/lxd/db/storage_pools_test.go b/lxd/db/storage_pools_test.go
index 47914acefb..1d13750167 100644
--- a/lxd/db/storage_pools_test.go
+++ b/lxd/db/storage_pools_test.go
@@ -165,7 +165,7 @@ func TestStoragePoolVolume_Ceph(t *testing.T) {
 	require.NoError(t, err)
 
 	config := map[string]string{"k": "v"}
-	volumeID, err := cluster.StoragePoolVolumeCreate("v1", "", 1, poolID, config)
+	volumeID, err := cluster.StoragePoolVolumeCreate("v1", "", 1, db.StorageVolumeKindRegular, poolID, config)
 	require.NoError(t, err)
 
 	// The returned volume ID is the one of the volume created on the local
diff --git a/lxd/patches.go b/lxd/patches.go
index 5f8a340617..987142a218 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -409,7 +409,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
 				return err
@@ -497,7 +497,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 				}
 			} else if err == db.ErrNoSuchObject {
 				// Insert storage volumes for containers into the database.
-				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
 					return err
@@ -578,7 +578,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, db.StorageVolumeKindRegular, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
 				return err
@@ -696,7 +696,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
 				return err
@@ -813,7 +813,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, snapshotPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
 				return err
@@ -843,7 +843,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, db.StorageVolumeKindRegular, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
 				return err
@@ -1005,7 +1005,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
 				return err
@@ -1160,7 +1160,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				}
 			} else if err == db.ErrNoSuchObject {
 				// Insert storage volumes for containers into the database.
-				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
 					return err
@@ -1331,7 +1331,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, db.StorageVolumeKindRegular, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
 				return err
@@ -1523,7 +1523,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(ct, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
 				return err
@@ -1609,7 +1609,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 				}
 			} else if err == db.ErrNoSuchObject {
 				// Insert storage volumes for containers into the database.
-				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := d.cluster.StoragePoolVolumeCreate(cs, "", storagePoolVolumeTypeContainer, db.StorageVolumeKindRegular, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
 					return err
@@ -1665,7 +1665,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			}
 		} else if err == db.ErrNoSuchObject {
 			// Insert storage volumes for containers into the database.
-			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := d.cluster.StoragePoolVolumeCreate(img, "", storagePoolVolumeTypeImage, db.StorageVolumeKindRegular, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
 				return err
diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
index eae478414b..7fa22b53d5 100644
--- a/lxd/storage_shared.go
+++ b/lxd/storage_shared.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"os"
 
+	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -108,7 +109,7 @@ func (s *storageShared) createImageDbPoolVolume(fingerprint string) error {
 	}
 
 	// Create a db entry for the storage volume of the image.
-	_, err = s.s.Cluster.StoragePoolVolumeCreate(fingerprint, "", storagePoolVolumeTypeImage, s.poolID, volumeConfig)
+	_, err = s.s.Cluster.StoragePoolVolumeCreate(fingerprint, "", storagePoolVolumeTypeImage, db.StorageVolumeKindRegular, s.poolID, volumeConfig)
 	if err != nil {
 		// Try to delete the db entry on error.
 		s.deleteImageDbPoolVolume(fingerprint)
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 931b49a8b6..1c65b7f511 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -495,7 +495,7 @@ func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volu
 	}
 
 	// Create the database entry for the storage volume.
-	_, err = s.Cluster.StoragePoolVolumeCreate(volumeName, volumeDescription, volumeType, poolID, volumeConfig)
+	_, err = s.Cluster.StoragePoolVolumeCreate(volumeName, volumeDescription, volumeType, db.StorageVolumeKindRegular, poolID, volumeConfig)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
 	}

From 58207f78d0c706401ea559113e02d2a9db66a486 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 15:47:13 +0200
Subject: [PATCH 20/81] storage: check volume names do not contain /

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_utils.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lxd/storage_utils.go b/lxd/storage_utils.go
index 1067ab72f1..4bb24c03ab 100644
--- a/lxd/storage_utils.go
+++ b/lxd/storage_utils.go
@@ -119,6 +119,10 @@ func tryUnmount(path string, flags int) error {
 }
 
 func storageValidName(value string) error {
+	if strings.Contains(value, "/") {
+		return fmt.Errorf("Invalid storage volume name \"%s\". Storage volumes cannot contain \"/\" in their name", value)
+	}
+
 	return nil
 }
 

From d0d440f2fcbf97b91d1c4d0ba3257149113bac3f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 16:22:52 +0200
Subject: [PATCH 21/81] storage: add kind arg to storagePoolVolumeDBCreate

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_utils.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 1c65b7f511..3489a27805 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -451,7 +451,7 @@ func profilesUsingPoolVolumeGetNames(db *db.Cluster, volumeName string, volumeTy
 	return usedBy, nil
 }
 
-func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
+func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeKind db.StorageVolumeKind, volumeConfig map[string]string) error {
 	// Check that the name of the new storage volume is valid. (For example.
 	// zfs pools cannot contain "/" in their names.)
 	err := storageValidName(volumeName)
@@ -495,7 +495,7 @@ func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volu
 	}
 
 	// Create the database entry for the storage volume.
-	_, err = s.Cluster.StoragePoolVolumeCreate(volumeName, volumeDescription, volumeType, db.StorageVolumeKindRegular, poolID, volumeConfig)
+	_, err = s.Cluster.StoragePoolVolumeCreate(volumeName, volumeDescription, volumeType, volumeKind, poolID, volumeConfig)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
 	}
@@ -528,7 +528,7 @@ func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol
 	}
 
 	// Create database entry for new storage volume.
-	err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, volumeConfig)
+	err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, db.StorageVolumeKindRegular, volumeConfig)
 	if err != nil {
 		return nil, err
 	}

From 3e689ef8c0ac86843b3a2ef2a9083eaeeabf900f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 24 Jul 2018 16:28:58 +0200
Subject: [PATCH 22/81] storage: use storageValidName() to check snap name

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index ef572b97dc..09835bb96e 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"net/http"
-	"strings"
 
 	"github.com/gorilla/mux"
 
@@ -50,8 +49,9 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Validate the name
-	if strings.Contains(req.Name, "/") {
-		return BadRequest(fmt.Errorf("Snapshot names may not contain slashes"))
+	err = storageValidName(req.Name)
+	if err != nil {
+		return BadRequest(err)
 	}
 
 	// Convert the volume type name to our internal integer representation.

From 60f95e02a05bb6fc8df034a9a820f69c2b899bec Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 25 Jul 2018 12:09:44 +0200
Subject: [PATCH 23/81] api: remove empty import

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
index 8ae0956494..4ba21da05d 100644
--- a/shared/api/storage_pool_volume_snapshot.go
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -1,7 +1,5 @@
 package api
 
-import ()
-
 // StorageVolumeSnapshotsPost represents the fields available for a new LXD storage volume snapshot
 //
 // API extension: storage_api_volume_snapshots

From f463f109b65e432c076fe3fdb7c408857cddde7f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 25 Jul 2018 12:10:04 +0200
Subject: [PATCH 24/81] storage: add
 storagePoolVolumeSnapshotDBCreateInternal()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_utils.go | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 3489a27805..2fdfb20260 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -452,13 +452,6 @@ func profilesUsingPoolVolumeGetNames(db *db.Cluster, volumeName string, volumeTy
 }
 
 func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeKind db.StorageVolumeKind, volumeConfig map[string]string) error {
-	// Check that the name of the new storage volume is valid. (For example.
-	// zfs pools cannot contain "/" in their names.)
-	err := storageValidName(volumeName)
-	if err != nil {
-		return err
-	}
-
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -577,3 +570,32 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
 
 	return nil
 }
+
+func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.StorageVolumeArgs) (storage, error) {
+	// Create database entry for new storage volume.
+	err := storagePoolVolumeDBCreate(state, dbArgs.PoolName, dbArgs.Name, dbArgs.Description, dbArgs.TypeName, db.StorageVolumeKindSnapshot, dbArgs.Config)
+	if err != nil {
+		return nil, err
+	}
+
+	// Convert the volume type name to our internal integer representation.
+	poolID, err := state.Cluster.StoragePoolGetID(dbArgs.PoolName)
+	if err != nil {
+		return nil, err
+	}
+
+	volumeType, err := storagePoolVolumeTypeNameToType(dbArgs.TypeName)
+	if err != nil {
+		state.Cluster.StoragePoolVolumeDelete(dbArgs.Name, volumeType, poolID)
+		return nil, err
+	}
+
+	// Initialize new storage volume on the target storage pool.
+	s, err := storagePoolVolumeInit(state, dbArgs.PoolName, dbArgs.Name, volumeType)
+	if err != nil {
+		state.Cluster.StoragePoolVolumeDelete(dbArgs.Name, volumeType, poolID)
+		return nil, err
+	}
+
+	return s, nil
+}

From d229583ef85998db9850abbbc1b14ebcd2f53a14 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 25 Jul 2018 12:10:50 +0200
Subject: [PATCH 25/81] storage: use
 storagePoolVolumeSnapshotDBCreateInternal() in
 storagePoolVolumeSnapshotsTypePost()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/operations.go            |  3 +++
 lxd/storage_volumes_snapshot.go | 32 +++++++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/lxd/db/operations.go b/lxd/db/operations.go
index 3d9225e8cd..e9ba56db40 100644
--- a/lxd/db/operations.go
+++ b/lxd/db/operations.go
@@ -50,6 +50,7 @@ const (
 	OperationVolumeCreate
 	OperationVolumeMigrate
 	OperationVolumeMove
+	OperationVolumeSnapshotCreate
 )
 
 // Description return a human-readable description of the operation type.
@@ -121,6 +122,8 @@ func (t OperationType) Description() string {
 		return "Migrating storage volume"
 	case OperationVolumeMove:
 		return "Moving storage volume"
+	case OperationVolumeSnapshotCreate:
+		return "Creating storage volume snapshot"
 	default:
 		return "Executing operation"
 
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 09835bb96e..ea4b50416c 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
@@ -97,10 +98,35 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
 		defer storage.StoragePoolVolumeUmount()
 	}
 
-	// // Create new snapshot name.
-	// fullName := fmt.Sprintf("%s%s%s", name, shared.SnapshotDelimiter, req.Name)
+	volWritable := storage.GetStoragePoolVolumeWritable()
+	fullSnapName := fmt.Sprintf("%s%s%s", volumeName, shared.SnapshotDelimiter, req.Name)
+	req.Name = fullSnapName
+	snapshot := func(op *operation) error {
+		dbArgs := &db.StorageVolumeArgs{
+			Name:        fullSnapName,
+			PoolName:    poolName,
+			TypeName:    volumeTypeName,
+			Kind:        db.StorageVolumeKindSnapshot,
+			Config:      volWritable.Config,
+			Description: volWritable.Description,
+		}
+
+		_, err = storagePoolVolumeSnapshotDBCreateInternal(d.State(), dbArgs)
+		if err != nil {
+			return err
+		}
+		return nil
+	}
+
+	resources := map[string][]string{}
+	resources["storage_volumes"] = []string{volumeName}
+
+	op, err := operationCreate(d.cluster, operationClassTask, db.OperationVolumeSnapshotCreate, resources, nil, snapshot, nil, nil)
+	if err != nil {
+		return InternalError(err)
+	}
 
-	return EmptySyncResponse
+	return OperationResponse(op)
 }
 
 func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {

From fa2677366abcaae3b4b0753cf82622b56b986300 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 14:22:28 +0200
Subject: [PATCH 26/81] storage: add StoragePoolVolumeSnapshotCreate()

This adds StoragePoolVolumeSnapshotCreate() to the storage interface. All
functions are not implemented.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 3 +++
 lxd/storage_btrfs.go | 6 ++++++
 lxd/storage_ceph.go  | 6 ++++++
 lxd/storage_dir.go   | 6 ++++++
 lxd/storage_lvm.go   | 6 ++++++
 lxd/storage_mock.go  | 6 ++++++
 lxd/storage_zfs.go   | 6 ++++++
 7 files changed, 39 insertions(+)

diff --git a/lxd/storage.go b/lxd/storage.go
index 996cabf285..23e621cbd7 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -164,6 +164,9 @@ type storage interface {
 	SetStoragePoolVolumeWritable(writable *api.StorageVolumePut)
 	GetStoragePoolVolume() *api.StorageVolume
 
+	// Functions dealing with custom storage volume snapshots.
+	StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error
+
 	// Functions dealing with container storage volumes.
 	// ContainerCreate creates an empty container (no rootfs/metadata.yaml)
 	ContainerCreate(container container) error
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index b375f1abf9..a953e93bf8 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2867,3 +2867,9 @@ func (s *storageBtrfs) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageBtrfs) GetState() *state.State {
 	return s.s
 }
+
+func (s *storageBtrfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 106a2283af..424bc6af49 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2621,3 +2621,9 @@ func (s *storageCeph) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageCeph) GetState() *state.State {
 	return s.s
 }
+
+func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index bcbacbf0dd..14756efead 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1279,3 +1279,9 @@ func (s *storageDir) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageDir) GetState() *state.State {
 	return s.s
 }
+
+func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index ce9a103dbb..2e491fdbe9 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2183,3 +2183,9 @@ func (s *storageLvm) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageLvm) GetState() *state.State {
 	return s.s
 }
+
+func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 201ea1d065..0027869970 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -261,3 +261,9 @@ func (s *storageMock) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageMock) GetState() *state.State {
 	return nil
 }
+
+func (s *storageMock) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 5be293fde6..6037add7ba 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2965,3 +2965,9 @@ func (s *storageZfs) GetStoragePoolVolume() *api.StorageVolume {
 func (s *storageZfs) GetState() *state.State {
 	return s.s
 }
+
+func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}

From d531b003b2fd23cd9bb8c969d1ae426f58625ee5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 15:27:04 +0200
Subject: [PATCH 27/81] storage: use StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index ea4b50416c..f91d3dfec4 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -111,6 +111,11 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
 			Description: volWritable.Description,
 		}
 
+		err = storage.StoragePoolVolumeSnapshotCreate(&req)
+		if err != nil {
+			return err
+		}
+
 		_, err = storagePoolVolumeSnapshotDBCreateInternal(d.State(), dbArgs)
 		if err != nil {
 			return err

From df7df172b3f14be1f5c3d7bb34c91ae658797868 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 14:24:05 +0200
Subject: [PATCH 28/81] dir: implement StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_dir.go | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 14756efead..758849598c 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1281,7 +1281,36 @@ func (s *storageDir) GetState() *state.State {
 }
 
 func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Creating DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	_, err := s.StoragePoolMount()
+	if err != nil {
+		return err
+	}
+
+	source := s.pool.Config["source"]
+	if source == "" {
+		return fmt.Errorf("no \"source\" property found for the storage pool")
+	}
+
+	sourceName, _, ok := containerGetParentAndSnapshotName(target.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	err = os.MkdirAll(targetPath, 0711)
+	if err != nil {
+		return err
+	}
+
+	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
+	bwlimit := s.pool.Config["rsync.bwlimit"]
+	msg, err := rsyncLocalCopy(sourcePath, targetPath, bwlimit)
+	if err != nil {
+		return fmt.Errorf("Failed to rsync: %s: %s", string(msg), err)
+	}
+
+	logger.Infof("Created DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 76ddff7e44a02d81586404d0afd04024da27886a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 16:50:36 +0200
Subject: [PATCH 29/81] btrfs: implement StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index a953e93bf8..784bb65bb3 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2869,7 +2869,33 @@ func (s *storageBtrfs) GetState() *state.State {
 }
 
 func (s *storageBtrfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Creating BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	// Create subvolume path on the storage pool.
+	customSubvolumePath := s.getCustomSubvolumePath(s.pool.Name)
+	err := os.MkdirAll(customSubvolumePath, 0700)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	_, _, ok := containerGetParentAndSnapshotName(target.Name)
+	if !ok {
+		return err
+	}
+
+	customSnapshotSubvolumeName := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	err = os.MkdirAll(customSnapshotSubvolumeName, snapshotsDirMode)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	err = s.btrfsPoolVolumesSnapshot(sourcePath, targetPath, true, true)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Created BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 748cdabbe987426cc33c4c9c47df069462587be9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 17:06:22 +0200
Subject: [PATCH 30/81] [UNTESTED] ceph: implement
 StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_ceph.go | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 424bc6af49..f5158bf484 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2623,7 +2623,35 @@ func (s *storageCeph) GetState() *state.State {
 }
 
 func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Debugf("Creating RBD storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	// This is costly but we need to ensure that all cached data has
+	// been committed to disk. If we don't then the rbd snapshot of
+	// the underlying filesystem can be inconsistent or - worst case
+	// - empty.
+	syscall.Sync()
+	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--freeze", sourcePath)
+	logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
+	if fsFreezeErr == nil {
+		defer shared.TryRunCommand("fsfreeze", "--unfreeze", sourcePath)
+	}
+
+	sourceOnlyName, snapshotOnlyName, _ := containerGetParentAndSnapshotName(target.Name)
+	snapshotName := fmt.Sprintf("snapshot_%s", snapshotOnlyName)
+	err := cephRBDSnapshotCreate(s.ClusterName, s.OSDPoolName, sourceOnlyName, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
+	if err != nil {
+		logger.Errorf("Failed to create snapshot for RBD storage volume for image \"%s\" on storage pool \"%s\": %s", sourceOnlyName, s.pool.Name, err)
+		return err
+	}
+
+	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	err = os.MkdirAll(targetPath, snapshotsDirMode)
+	if err != nil {
+		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
+		return err
+	}
+
+	logger.Debugf("Created RBD storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 3fc848baabd54646904343e5121f7ce4b8f1472f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 17:07:07 +0200
Subject: [PATCH 31/81] mock: implement StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_mock.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 0027869970..ba575f3427 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -263,7 +263,5 @@ func (s *storageMock) GetState() *state.State {
 }
 
 func (s *storageMock) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	return nil
 }

From bbb150f5e6c7890a0b0e9d2ec255544842478bc3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 17:14:12 +0200
Subject: [PATCH 32/81] lvm: implement StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_lvm.go | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 2e491fdbe9..20b11900cf 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2185,7 +2185,27 @@ func (s *storageLvm) GetState() *state.State {
 }
 
 func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Debugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	poolName := s.getOnDiskPoolName()
+	sourceOnlyName, _, ok := containerGetParentAndSnapshotName(target.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot")
+	}
+
+	targetLvmName := containerNameToLVName(target.Name)
+	_, err := s.createSnapshotLV(poolName, sourceOnlyName, storagePoolVolumeAPIEndpointCustom, targetLvmName, storagePoolVolumeAPIEndpointCustom, true, s.useThinpool)
+	if err != nil {
+		return fmt.Errorf("Failed to create snapshot logical volume %s", err)
+	}
+
+	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	err = os.MkdirAll(targetPath, snapshotsDirMode)
+	if err != nil {
+		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
+		return err
+	}
+
+	logger.Debugf("Created LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From af2821f3ff58d35abac34fbcb793ae6a226aa4a9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 31 Jul 2018 17:53:15 +0200
Subject: [PATCH 33/81] [UNTESTED] zfs: implement
 StoragePoolVolumeSnapshotCreate()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_zfs.go | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 6037add7ba..cabd3ec829 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2967,7 +2967,29 @@ func (s *storageZfs) GetState() *state.State {
 }
 
 func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Creating ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	sourceOnlyName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(target.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	sourceDataset := fmt.Sprintf("custom/%s", sourceOnlyName)
+	poolName := s.getOnDiskPoolName()
+	dataset := fmt.Sprintf("%s/%s", poolName, sourceDataset)
+	snapName := fmt.Sprintf("snapshot-%s", snapshotOnlyName)
+	err := zfsPoolVolumeSnapshotCreate(poolName, dataset, snapName)
+	if err != nil {
+		return err
+	}
+
+	targetPath := getStoragePoolVolumeMountPoint(s.pool.Name, target.Name)
+	err = os.MkdirAll(targetPath, snapshotsDirMode)
+	if err != nil {
+		logger.Errorf("Failed to create mountpoint \"%s\" for ZFS storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
+		return err
+	}
+
+	logger.Infof("Created ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 6600f4d88093935bc4f28e3250c15b942914cf54 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 3 Aug 2018 13:20:27 +0200
Subject: [PATCH 34/81] storage: add StoragePoolVolumeSnapshotDelete()

This adds StoragePoolVolumeSnapshotDelete() to the storage interface. All
functions are not implemented.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 1 +
 lxd/storage_btrfs.go | 6 ++++++
 lxd/storage_ceph.go  | 6 ++++++
 lxd/storage_dir.go   | 6 ++++++
 lxd/storage_lvm.go   | 6 ++++++
 lxd/storage_mock.go  | 6 ++++++
 lxd/storage_zfs.go   | 6 ++++++
 7 files changed, 37 insertions(+)

diff --git a/lxd/storage.go b/lxd/storage.go
index 23e621cbd7..461431c919 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -166,6 +166,7 @@ type storage interface {
 
 	// Functions dealing with custom storage volume snapshots.
 	StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error
+	StoragePoolVolumeSnapshotDelete() error
 
 	// Functions dealing with container storage volumes.
 	// ContainerCreate creates an empty container (no rootfs/metadata.yaml)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 784bb65bb3..7c94a6d307 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2899,3 +2899,9 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolume
 	logger.Infof("Created BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index f5158bf484..73b73b3793 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2655,3 +2655,9 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 	logger.Debugf("Created RBD storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageCeph) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 758849598c..c26c2de074 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1314,3 +1314,9 @@ func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 	logger.Infof("Created DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 20b11900cf..149208410e 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2209,3 +2209,9 @@ func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 	logger.Debugf("Created LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index ba575f3427..9300b803a1 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -265,3 +265,9 @@ func (s *storageMock) GetState() *state.State {
 func (s *storageMock) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
 	return nil
 }
+
+func (s *storageMock) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index cabd3ec829..3dd6c09768 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2993,3 +2993,9 @@ func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 	logger.Infof("Created ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}

From a712fa0f11bc9aeb5a444f6714d6c793a0d493cb Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 3 Aug 2018 13:26:48 +0200
Subject: [PATCH 35/81] storage: implement
 storagePoolVolumeSnapshotTypeDelete()

This implements tha storagePoolVolumeSnapshotTypeDelete() API endpoint.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 64 ++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index f91d3dfec4..36a5472169 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -147,5 +147,67 @@ func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {
 }
 
 func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Deleting storage pool volume snapshots is not implemented"))
+	// Get the name of the storage pool the volume is supposed to be
+	// attached to.
+	poolName := mux.Vars(r)["pool"]
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the storage volume.
+	volumeName := mux.Vars(r)["name"]
+
+	// Get the name of the storage volume.
+	snapshotName := mux.Vars(r)["snapshotName"]
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Check that the storage volume type is valid.
+	if volumeType != storagePoolVolumeTypeCustom {
+		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
+	}
+
+	response := ForwardedResponseIfTargetIsRemote(d, r)
+	if response != nil {
+		return response
+	}
+
+	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
+	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	if response != nil {
+		return response
+	}
+
+	s, err := storagePoolVolumeInit(d.State(), poolName, fullSnapshotName, volumeType)
+	if err != nil {
+		return NotFound(err)
+	}
+
+	snapshotDelete := func(op *operation) error {
+		err = s.StoragePoolVolumeSnapshotDelete()
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+
+	resources := map[string][]string{}
+	resources["storage_volume_snapshots"] = []string{volumeName}
+
+	op, err := operationCreate(d.cluster, operationClassTask, db.OperationVolumeSnapshotDelete, resources, nil, snapshotDelete, nil, nil)
+	if err != nil {
+		return InternalError(err)
+	}
+
+	return OperationResponse(op)
 }

From bc44364da7c794c68b90b66bd609ad3febb26f4f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 3 Aug 2018 13:53:45 +0200
Subject: [PATCH 36/81] client: add DeleteStoragePoolVolumeSnapshot()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index a73a092f6d..3fc911e815 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -200,6 +200,7 @@ type ContainerServer interface {
 
 	// Storage volume snapshot functions ("storage_api_volume_snapshots" API extension)
 	CreateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshot api.StorageVolumeSnapshotsPost) (op Operation, err error)
+	DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (op Operation, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 51262a08b7..a1036de00f 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -108,6 +108,28 @@ func (r *ProtocolLXD) CreateStoragePoolVolumeSnapshot(pool string, volumeType st
 	return op, nil
 }
 
+// DeleteStoragePoolVolumeSnapshot deletes a storage volume snapshot
+func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (Operation, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage\" API extension")
+	}
+
+	// Send the request
+	path := fmt.Sprintf(
+		"/storage-pools/%s/volumes/%s/%s/snapshots/%s",
+		url.QueryEscape(pool), url.QueryEscape(volumeType), url.QueryEscape(volumeName), url.QueryEscape(snapshotName))
+	if r.clusterTarget != "" {
+		path += fmt.Sprintf("?target=%s", r.clusterTarget)
+	}
+
+	op, _, err := r.queryOperation("DELETE", path, nil, "")
+	if err != nil {
+		return nil, err
+	}
+
+	return op, nil
+}
+
 // MigrateStoragePoolVolume requests that LXD prepares for a storage volume migration
 func (r *ProtocolLXD) MigrateStoragePoolVolume(pool string, volume api.StorageVolumePost) (Operation, error) {
 	if !r.HasExtension("storage_api_remote_volume_handling") {

From fde6b8e424bdd3f77877be496ca05d7546175f94 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 3 Aug 2018 13:32:25 +0200
Subject: [PATCH 37/81] dir: implement StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_dir.go | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index c26c2de074..43c7fc620b 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1316,7 +1316,35 @@ func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 }
 
 func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Deleting DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	source := s.pool.Config["source"]
+	if source == "" {
+		return fmt.Errorf("no \"source\" property found for the storage pool")
+	}
+
+	storageVolumePath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	err := os.RemoveAll(storageVolumePath)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
+	if err == nil && empty {
+		os.RemoveAll(storageVolumeSnapshotPath)
+	}
+
+	err = s.s.Cluster.StoragePoolVolumeDelete(
+		s.volume.Name,
+		storagePoolVolumeTypeCustom,
+		s.poolID)
+	if err != nil {
+		logger.Errorf(`Failed to delete database entry for DIR storage volume "%s" on storage pool "%s"`,
+			s.volume.Name, s.pool.Name)
+	}
+
+	logger.Infof("Deleted DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From dcaec30d335448b066797be92b60790d3705a1d1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 6 Aug 2018 16:10:04 +0200
Subject: [PATCH 38/81] btrfs: implement StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 7c94a6d307..6de50a1f98 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2901,7 +2901,42 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolume
 }
 
 func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Deleting BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	source := s.pool.Config["source"]
+	if source == "" {
+		return fmt.Errorf("no \"source\" property found for the storage pool")
+	}
+
+	snapshotSubvolumeName := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	if shared.PathExists(snapshotSubvolumeName) && isBtrfsSubVolume(snapshotSubvolumeName) {
+		err := btrfsSubVolumesDelete(snapshotSubvolumeName)
+		if err != nil {
+			return err
+		}
+	}
+
+	err := os.RemoveAll(snapshotSubvolumeName)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
+	if err == nil && empty {
+		os.RemoveAll(storageVolumeSnapshotPath)
+	}
+
+	err = s.s.Cluster.StoragePoolVolumeDelete(
+		s.volume.Name,
+		storagePoolVolumeTypeCustom,
+		s.poolID)
+	if err != nil {
+		logger.Errorf(`Failed to delete database entry for BTRFS storage volume "%s" on storage pool "%s"`,
+			s.volume.Name, s.pool.Name)
+	}
+
+	logger.Infof("Deleted BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 285b6818ae750dbb847226c341053817fd90b285 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 3 Aug 2018 15:00:52 +0200
Subject: [PATCH 39/81] lxc: allow to delete custom volume snapshots

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 98eeee48d8..4d7d834b86 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -499,7 +499,8 @@ func (c *cmdStorageVolumeDelete) Command() *cobra.Command {
 
 func (c *cmdStorageVolumeDelete) Run(cmd *cobra.Command, args []string) error {
 	// Sanity checks
-	exit, err := c.global.CheckArgs(cmd, args, 2, 2)
+	// Sanity checks
+	exit, err := c.global.CheckArgs(cmd, args, 2, 3)
 	if exit {
 		return err
 	}
@@ -511,7 +512,6 @@ func (c *cmdStorageVolumeDelete) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	resource := resources[0]
-
 	if resource.name == "" {
 		return fmt.Errorf(i18n.G("Missing pool name"))
 	}
@@ -526,13 +526,30 @@ func (c *cmdStorageVolumeDelete) Run(cmd *cobra.Command, args []string) error {
 		client = client.UseTarget(c.storage.flagTarget)
 	}
 
-	// Delete the volume
-	err = client.DeleteStoragePoolVolume(resource.name, volType, volName)
-	if err != nil {
-		return err
+	msg := ""
+	if len(args) < 3 {
+		// Delete the volume
+		err := client.DeleteStoragePoolVolume(resource.name, volType, volName)
+		if err != nil {
+			return err
+		}
+		msg = args[1]
+	} else {
+		// Delete the snapshot
+		op, err := client.DeleteStoragePoolVolumeSnapshot(resource.name, volType, volName, args[2])
+		if err != nil {
+			return err
+		}
+
+		err = op.Wait()
+		if err != nil {
+			return err
+		}
+
+		msg = args[2]
 	}
 
-	fmt.Printf(i18n.G("Storage volume %s deleted")+"\n", args[1])
+	fmt.Printf(i18n.G("Storage volume %s deleted")+"\n", msg)
 
 	return nil
 }

From b556d66200fe775cf83243026e9fd8f07b63d436 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 6 Aug 2018 16:22:09 +0200
Subject: [PATCH 40/81] [UNTESTED] ceph: implement
 StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_ceph.go | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 73b73b3793..311dc84e4a 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2657,7 +2657,39 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 }
 
 func (s *storageCeph) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Deleting CEPH storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	sourceName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+	snapshotName := fmt.Sprintf("snapshot_%s", snapshotOnlyName)
+
+	rbdVolumeExists := cephRBDSnapshotExists(s.ClusterName, s.OSDPoolName, sourceName, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
+	if rbdVolumeExists {
+		ret := cephContainerSnapshotDelete(s.ClusterName, s.OSDPoolName, sourceName, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
+		if ret < 0 {
+			msg := fmt.Sprintf("Failed to delete RBD storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+			logger.Errorf(msg)
+			return fmt.Errorf(msg)
+		}
+	}
+
+	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
+	if err == nil && empty {
+		os.RemoveAll(storageVolumeSnapshotPath)
+	}
+
+	err = s.s.Cluster.StoragePoolVolumeDelete(
+		s.volume.Name,
+		storagePoolVolumeTypeCustom,
+		s.poolID)
+	if err != nil {
+		logger.Errorf(`Failed to delete database entry for DIR storage volume "%s" on storage pool "%s"`,
+			s.volume.Name, s.pool.Name)
+	}
+
+	logger.Infof("Deleted CEPH storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From b706a50f73ae3f6c6e2bef3ddaef0ac232134988 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 6 Aug 2018 16:31:38 +0200
Subject: [PATCH 41/81] lvm: implement StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_lvm.go | 47 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 149208410e..b062863678 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2211,7 +2211,48 @@ func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 }
 
 func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Deleting LVM storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	snapshotLVName := containerNameToLVName(s.volume.Name)
+	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	if shared.IsMountPoint(storageVolumeSnapshotPath) {
+		err := tryUnmount(storageVolumeSnapshotPath, 0)
+		if err != nil {
+			return fmt.Errorf("Failed to unmount snapshot path \"%s\": %s", storageVolumeSnapshotPath, err)
+		}
+	}
+
+	poolName := s.getOnDiskPoolName()
+	snapshotLVDevPath := getLvmDevPath(poolName, storagePoolVolumeAPIEndpointCustom, snapshotLVName)
+	lvExists, _ := storageLVExists(snapshotLVDevPath)
+	if lvExists {
+		err := removeLV(poolName, storagePoolVolumeAPIEndpointCustom, snapshotLVName)
+		if err != nil {
+			return err
+		}
+	}
+
+	err := os.Remove(storageVolumeSnapshotPath)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	storageVolumeSnapshotPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
+	if err == nil && empty {
+		os.RemoveAll(storageVolumeSnapshotPath)
+	}
+
+	err = s.s.Cluster.StoragePoolVolumeDelete(
+		s.volume.Name,
+		storagePoolVolumeTypeCustom,
+		s.poolID)
+	if err != nil {
+		logger.Errorf(`Failed to delete database entry for LVM storage volume "%s" on storage pool "%s"`,
+			s.volume.Name, s.pool.Name)
+	}
+
+	logger.Infof("Deleted LVM storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 8fef1850fcf74105a6dd11a57152e851fc029814 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 6 Aug 2018 16:32:09 +0200
Subject: [PATCH 42/81] mock: implement StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_mock.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 9300b803a1..ac75464a29 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -267,7 +267,5 @@ func (s *storageMock) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 }
 
 func (s *storageMock) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	return nil
 }

From d32805b77fd57d3124b8223eb648971e937f8c8a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 6 Aug 2018 16:38:37 +0200
Subject: [PATCH 43/81] [UNTESTED] zfs: implement
 StoragePoolVolumeSnapshotDelete()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_zfs.go | 48 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 3dd6c09768..6aaec370c8 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2995,7 +2995,49 @@ func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 }
 
 func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Deleting ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	sourceName, snapshotOnlyName, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	snapshotName := fmt.Sprintf("snapshot-%s", snapshotOnlyName)
+
+	onDiskPoolName := s.getOnDiskPoolName()
+	if zfsFilesystemEntityExists(onDiskPoolName, fmt.Sprintf("custom/%s@%s", sourceName, snapshotName)) {
+		removable, err := zfsPoolVolumeSnapshotRemovable(onDiskPoolName, fmt.Sprintf("custom/%s", sourceName), snapshotName)
+		if err != nil {
+			return err
+		}
+
+		if removable {
+			err = zfsPoolVolumeSnapshotDestroy(onDiskPoolName, fmt.Sprintf("custom/%s", sourceName), snapshotName)
+		} else {
+			err = zfsPoolVolumeSnapshotRename(onDiskPoolName, fmt.Sprintf("custom/%s", sourceName), snapshotName, fmt.Sprintf("copy-%s", uuid.NewRandom().String()))
+		}
+		if err != nil {
+			return err
+		}
+	}
+
+	storageVolumePath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	err := os.RemoveAll(storageVolumePath)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
+	if err == nil && empty {
+		os.RemoveAll(storageVolumeSnapshotPath)
+	}
+
+	err = s.s.Cluster.StoragePoolVolumeDelete(
+		s.volume.Name,
+		storagePoolVolumeTypeCustom,
+		s.poolID)
+	if err != nil {
+		logger.Errorf(`Failed to delete database entry for DIR storage volume "%s" on storage pool "%s"`,
+			s.volume.Name, s.pool.Name)
+	}
+
+	logger.Infof("Deleted ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+	return nil
 }

From 8759ffe240473765cc79683093f1bbca0bfacc6e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 13:32:53 +0200
Subject: [PATCH 44/81] client: add GetStoragePoolVolumeSnapshotNames()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index 3fc911e815..14f9418ca1 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -201,6 +201,7 @@ type ContainerServer interface {
 	// Storage volume snapshot functions ("storage_api_volume_snapshots" API extension)
 	CreateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshot api.StorageVolumeSnapshotsPost) (op Operation, err error)
 	DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (op Operation, err error)
+	GetStoragePoolVolumeSnapshotNames(pool string, volumeType string, volumeName string) (names []string, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index a1036de00f..5f7bc0f648 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -108,6 +108,35 @@ func (r *ProtocolLXD) CreateStoragePoolVolumeSnapshot(pool string, volumeType st
 	return op, nil
 }
 
+// GetStoragePoolVolumeSnapshotNames returns a list of snapshot names for the
+// storage volume
+func (r *ProtocolLXD) GetStoragePoolVolumeSnapshotNames(pool string, volumeType string, volumeName string) ([]string, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	urls := []string{}
+
+	// Send the request
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots",
+		url.QueryEscape(pool),
+		url.QueryEscape(volumeType),
+		url.QueryEscape(volumeName))
+	_, err := r.queryStruct("GET", path, nil, "", &urls)
+	if err != nil {
+		return nil, err
+	}
+
+	// Parse it
+	names := []string{}
+	for _, uri := range urls {
+		fields := strings.Split(uri, path)
+		names = append(names, fields[len(fields)-1])
+	}
+
+	return names, nil
+}
+
 // DeleteStoragePoolVolumeSnapshot deletes a storage volume snapshot
 func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (Operation, error) {
 	if !r.HasExtension("storage_api_volume_snapshots") {

From eeb214196ae3a2a67ec58d92e8f8e38f64125b26 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 13:33:13 +0200
Subject: [PATCH 45/81] client: add GetStoragePoolVolumeSnapshots()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index 14f9418ca1..8f37b6d587 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -202,6 +202,7 @@ type ContainerServer interface {
 	CreateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshot api.StorageVolumeSnapshotsPost) (op Operation, err error)
 	DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (op Operation, err error)
 	GetStoragePoolVolumeSnapshotNames(pool string, volumeType string, volumeName string) (names []string, err error)
+	GetStoragePoolVolumeSnapshots(pool string, volumeType string, volumeName string) (snapshots []api.StorageVolumeSnapshot, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 5f7bc0f648..56fd265585 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -137,6 +137,27 @@ func (r *ProtocolLXD) GetStoragePoolVolumeSnapshotNames(pool string, volumeType
 	return names, nil
 }
 
+// GetStoragePoolVolumeSnapshots returns a list of snapshots for the storage
+// volume
+func (r *ProtocolLXD) GetStoragePoolVolumeSnapshots(pool string, volumeType string, volumeName string) ([]api.StorageVolumeSnapshot, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	snapshots := []api.StorageVolumeSnapshot{}
+
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots?recursion=1",
+		url.QueryEscape(pool),
+		url.QueryEscape(volumeType),
+		url.QueryEscape(volumeName))
+	_, err := r.queryStruct("GET", path, nil, "", &snapshots)
+	if err != nil {
+		return nil, err
+	}
+
+	return snapshots, nil
+}
+
 // DeleteStoragePoolVolumeSnapshot deletes a storage volume snapshot
 func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (Operation, error) {
 	if !r.HasExtension("storage_api_volume_snapshots") {

From 794c580eef86ee40b2f33472abf7fda97d023719 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 19:25:41 +0200
Subject: [PATCH 46/81] db: add StoragePoolVolumeSnapshotsGetType()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/storage_pools.go | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 2a14acf410..51c84713e8 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -756,6 +756,29 @@ func (c *Cluster) StoragePoolVolumesGetType(volumeType int, poolID, nodeID int64
 	return response, nil
 }
 
+// StoragePoolVolumeSnapshotsGetType get all snapshots of a storage volume
+// attached to a given storage pool of a given volume type, on the given node.
+func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeType int, poolID int64) ([]string, error) {
+	result := []string{}
+	regexp := volumeName + shared.SnapshotDelimiter
+	length := len(regexp)
+
+	query := "SELECT name FROM storage_volumes WHERE storage_pool_id=? AND node_id=? AND type=? AND kind=? AND SUBSTR(name,1,?)=?"
+	inargs := []interface{}{poolID, c.nodeID, volumeType, StorageVolumeKindSnapshot, length, regexp}
+	outfmt := []interface{}{volumeName}
+
+	dbResults, err := queryScan(c.db, query, inargs, outfmt)
+	if err != nil {
+		return result, err
+	}
+
+	for _, r := range dbResults {
+		result = append(result, r[0].(string))
+	}
+
+	return result, nil
+}
+
 // StoragePoolNodeVolumesGetType returns all storage volumes attached to a
 // given storage pool of a given volume type, on the current node.
 func (c *Cluster) StoragePoolNodeVolumesGetType(volumeType int, poolID int64) ([]string, error) {

From d48fb4be1a33d396e0490e60f1fde6204b1c3f86 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 19:26:22 +0200
Subject: [PATCH 47/81] storage: add storagePoolVolumeSnapshotsTypeGet()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 74 ++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 36a5472169..be7348b6d8 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -8,8 +8,10 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/version"
 )
 
 var storagePoolVolumeSnapshotsTypeCmd = Command{
@@ -135,7 +137,77 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) Response {
 }
 
 func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Retrieving storage pool volume snapshots is not implemented"))
+	// Get the name of the pool the storage volume is supposed to be
+	// attached to.
+	poolName := mux.Vars(r)["pool"]
+
+	recursion := util.IsRecursionRequest(r)
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the volume type.
+	volumeName := mux.Vars(r)["name"]
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+	// Check that the storage volume type is valid.
+	if !shared.IntInSlice(volumeType, supportedVolumeTypes) {
+		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
+	}
+
+	// Retrieve ID of the storage pool (and check if the storage pool
+	// exists).
+	poolID, err := d.cluster.StoragePoolGetID(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	// Get the names of all storage volumes of a given volume type currently
+	// attached to the storage pool.
+	volumes, err := d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName, volumeType, poolID)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	resultString := []string{}
+	resultMap := []*api.StorageVolumeSnapshot{}
+	for _, volume := range volumes {
+		if !recursion {
+			apiEndpoint, err := storagePoolVolumeTypeToAPIEndpoint(volumeType)
+			if err != nil {
+				return InternalError(err)
+			}
+			resultString = append(resultString, fmt.Sprintf("/%s/storage-pools/%s/volumes/%s/%s/snapshots/%s", version.APIVersion, poolName, apiEndpoint, volumeName, volume))
+		} else {
+			_, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volume, volumeType, poolID)
+			if err != nil {
+				continue
+			}
+
+			volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), vol.Name, vol.Type)
+			if err != nil {
+				return SmartError(err)
+			}
+			vol.UsedBy = volumeUsedBy
+
+			tmp := &api.StorageVolumeSnapshot{}
+			tmp.Config = vol.Config
+			tmp.Description = vol.Description
+			tmp.Name = vol.Name
+
+			resultMap = append(resultMap, tmp)
+		}
+	}
+
+	if !recursion {
+		return SyncResponse(true, resultString)
+	}
+
+	return SyncResponse(true, resultMap)
 }
 
 func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) Response {

From 18530ab9dd379d2c8a49204740c2c70249bf0648 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 21:07:20 +0200
Subject: [PATCH 48/81] storage: add storagePoolVolumeSnapshotTypeGet()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 54 ++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index be7348b6d8..2a5ed6af1c 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -215,7 +215,59 @@ func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) Response {
 }
 
 func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Retrieving a storage pool volume snapshot is not implemented"))
+	// Get the name of the storage pool the volume is supposed to be
+	// attached to.
+	poolName := mux.Vars(r)["pool"]
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the storage volume.
+	volumeName := mux.Vars(r)["name"]
+
+	// Get the name of the storage volume.
+	snapshotName := mux.Vars(r)["snapshotName"]
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Check that the storage volume type is valid.
+	if volumeType != storagePoolVolumeTypeCustom {
+		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
+	}
+
+	response := ForwardedResponseIfTargetIsRemote(d, r)
+	if response != nil {
+		return response
+	}
+
+	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
+	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	if response != nil {
+		return response
+	}
+
+	_, volume, err := d.cluster.StoragePoolNodeVolumeGetType(fullSnapshotName, volumeType, poolID)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	snapshot := api.StorageVolumeSnapshot{}
+	snapshot.Config = volume.Config
+	snapshot.Description = volume.Description
+	snapshot.Name = volume.Name
+
+	etag := []interface{}{snapshot.Name, snapshot.Description, snapshot.Config}
+
+	return SyncResponseETag(true, &snapshot, etag)
 }
 
 func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) Response {

From e3f4a17bdaf333c26261fea2511073d6724168a6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 7 Aug 2018 21:18:07 +0200
Subject: [PATCH 49/81] client: add GetStoragePoolVolumeSnapshot()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/client/interfaces.go b/client/interfaces.go
index 8f37b6d587..984da882c9 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -203,6 +203,7 @@ type ContainerServer interface {
 	DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (op Operation, err error)
 	GetStoragePoolVolumeSnapshotNames(pool string, volumeType string, volumeName string) (names []string, err error)
 	GetStoragePoolVolumeSnapshots(pool string, volumeType string, volumeName string) (snapshots []api.StorageVolumeSnapshot, err error)
+	GetStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (snapshot *api.StorageVolumeSnapshot, ETag string, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 56fd265585..597ce279ab 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -158,10 +158,31 @@ func (r *ProtocolLXD) GetStoragePoolVolumeSnapshots(pool string, volumeType stri
 	return snapshots, nil
 }
 
+// GetStoragePoolVolumeSnapshot returns a snapshots for the storage volume
+func (r *ProtocolLXD) GetStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (*api.StorageVolumeSnapshot, string, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, "", fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	snapshot := api.StorageVolumeSnapshot{}
+
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots/%s",
+		url.QueryEscape(pool),
+		url.QueryEscape(volumeType),
+		url.QueryEscape(volumeName),
+		url.QueryEscape(snapshotName))
+	etag, err := r.queryStruct("GET", path, nil, "", &snapshot)
+	if err != nil {
+		return nil, "", err
+	}
+
+	return &snapshot, etag, nil
+}
+
 // DeleteStoragePoolVolumeSnapshot deletes a storage volume snapshot
 func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (Operation, error) {
 	if !r.HasExtension("storage_api_volume_snapshots") {
-		return nil, fmt.Errorf("The server is missing the required \"storage\" API extension")
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
 	}
 
 	// Send the request

From 0daeb846b2aa5aeaad9d21bf76d5a7bbb1774827 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 14:52:28 +0200
Subject: [PATCH 50/81] client: add RenameStoragePoolVolumeSnapshot()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index 984da882c9..50d86b2b63 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -204,6 +204,7 @@ type ContainerServer interface {
 	GetStoragePoolVolumeSnapshotNames(pool string, volumeType string, volumeName string) (names []string, err error)
 	GetStoragePoolVolumeSnapshots(pool string, volumeType string, volumeName string) (snapshots []api.StorageVolumeSnapshot, err error)
 	GetStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (snapshot *api.StorageVolumeSnapshot, ETag string, err error)
+	RenameStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string, snapshot api.StorageVolumeSnapshotPost) (op Operation, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 597ce279ab..ea7b5f0699 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -179,6 +179,22 @@ func (r *ProtocolLXD) GetStoragePoolVolumeSnapshot(pool string, volumeType strin
 	return &snapshot, etag, nil
 }
 
+// RenameStoragePoolVolumeSnapshot renames a storage volume snapshot
+func (r *ProtocolLXD) RenameStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string, snapshot api.StorageVolumeSnapshotPost) (Operation, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots/%s", url.QueryEscape(pool), url.QueryEscape(volumeType), url.QueryEscape(volumeName), url.QueryEscape(snapshotName))
+	// Send the request
+	op, _, err := r.queryOperation("POST", path, snapshot, "")
+	if err != nil {
+		return nil, err
+	}
+
+	return op, nil
+}
+
 // DeleteStoragePoolVolumeSnapshot deletes a storage volume snapshot
 func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (Operation, error) {
 	if !r.HasExtension("storage_api_volume_snapshots") {

From c1af4267faa432e5866b8b4a60576d1760901287 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:03:28 +0200
Subject: [PATCH 51/81] storage: add StoragePoolVolumeSnapshotRename()

This adds StoragePoolVolumeSnapshotRename() to the storage interface. All
functions are not implemented.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 1 +
 lxd/storage_btrfs.go | 6 ++++++
 lxd/storage_ceph.go  | 6 ++++++
 lxd/storage_dir.go   | 6 ++++++
 lxd/storage_lvm.go   | 6 ++++++
 lxd/storage_mock.go  | 6 ++++++
 lxd/storage_zfs.go   | 6 ++++++
 7 files changed, 37 insertions(+)

diff --git a/lxd/storage.go b/lxd/storage.go
index 461431c919..e06c5472b2 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -167,6 +167,7 @@ type storage interface {
 	// Functions dealing with custom storage volume snapshots.
 	StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error
 	StoragePoolVolumeSnapshotDelete() error
+	StoragePoolVolumeSnapshotRename(newName string) error
 
 	// Functions dealing with container storage volumes.
 	// ContainerCreate creates an empty container (no rootfs/metadata.yaml)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 6de50a1f98..9ff125f70b 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2940,3 +2940,9 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleted BTRFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageBtrfs) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 311dc84e4a..cf43c2487c 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2693,3 +2693,9 @@ func (s *storageCeph) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleted CEPH storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageCeph) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 43c7fc620b..eb8f8ba196 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1348,3 +1348,9 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleted DIR storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageDir) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index b062863678..daedd917bb 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2256,3 +2256,9 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleted LVM storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageLvm) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index ac75464a29..a56ec97d28 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -269,3 +269,9 @@ func (s *storageMock) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 func (s *storageMock) StoragePoolVolumeSnapshotDelete() error {
 	return nil
 }
+
+func (s *storageMock) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 6aaec370c8..662836112f 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -3041,3 +3041,9 @@ func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleted ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	return nil
 }
+
+func (s *storageZfs) StoragePoolVolumeSnapshotRename(newName string) error {
+	msg := fmt.Sprintf("Function not implemented")
+	logger.Errorf(msg)
+	return fmt.Errorf(msg)
+}

From 0d7abc3cc7f308a25d5348161e7d4e23d59ce257 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 14:59:59 +0200
Subject: [PATCH 52/81] storage: implement storagePoolVolumeSnapshotTypePost()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/operations.go            |  3 ++
 lxd/storage_volumes_snapshot.go | 82 ++++++++++++++++++++++++++++++++-
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/lxd/db/operations.go b/lxd/db/operations.go
index e9ba56db40..fecf7872ee 100644
--- a/lxd/db/operations.go
+++ b/lxd/db/operations.go
@@ -51,6 +51,7 @@ const (
 	OperationVolumeMigrate
 	OperationVolumeMove
 	OperationVolumeSnapshotCreate
+	OperationVolumeSnapshotDelete
 )
 
 // Description return a human-readable description of the operation type.
@@ -124,6 +125,8 @@ func (t OperationType) Description() string {
 		return "Moving storage volume"
 	case OperationVolumeSnapshotCreate:
 		return "Creating storage volume snapshot"
+	case OperationVolumeSnapshotDelete:
+		return "Deleting storage volume snapshot"
 	default:
 		return "Executing operation"
 
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 2a5ed6af1c..135102622b 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"net/http"
+	"strings"
 
 	"github.com/gorilla/mux"
 
@@ -211,7 +212,86 @@ func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {
 }
 
 func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Updating storage pool volume snapshots is not implemented"))
+	// Get the name of the storage pool the volume is supposed to be
+	// attached to.
+	poolName := mux.Vars(r)["pool"]
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the storage volume.
+	volumeName := mux.Vars(r)["name"]
+
+	// Get the name of the storage volume.
+	snapshotName := mux.Vars(r)["snapshotName"]
+
+	req := api.StorageVolumeSnapshotPost{}
+
+	// Parse the request.
+	err := json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Sanity checks.
+	if req.Name == "" {
+		return BadRequest(fmt.Errorf("No name provided"))
+	}
+
+	if strings.Contains(req.Name, "/") {
+		return BadRequest(fmt.Errorf("Storage volume names may not contain slashes"))
+	}
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Check that the storage volume type is valid.
+	if volumeType != storagePoolVolumeTypeCustom {
+		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
+	}
+
+	response := ForwardedResponseIfTargetIsRemote(d, r)
+	if response != nil {
+		return response
+	}
+
+	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
+	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	if response != nil {
+		return response
+	}
+
+	s, err := storagePoolVolumeInit(d.State(), poolName, fullSnapshotName, volumeType)
+	if err != nil {
+		return NotFound(err)
+	}
+
+	snapshotRename := func(op *operation) error {
+		err = s.StoragePoolVolumeSnapshotRename(req.Name)
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+
+	resources := map[string][]string{}
+	resources["storage_volume_snapshots"] = []string{volumeName}
+
+	op, err := operationCreate(d.cluster, operationClassTask, db.OperationVolumeSnapshotDelete, resources, nil, snapshotRename, nil, nil)
+	if err != nil {
+		return InternalError(err)
+	}
+
+	return OperationResponse(op)
 }
 
 func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {

From 86a41e7e785cd4fc8673982ec0981b719e6335fd Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:16:47 +0200
Subject: [PATCH 53/81] btrfs: implement StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 9ff125f70b..5d921dd230 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2942,7 +2942,22 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageBtrfs) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Renaming BTRFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
+	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	err := os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Renamed BTRFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, fullSnapshotName, storagePoolVolumeTypeCustom, s.poolID)
 }

From 3d1f42d357649cabf516f561878ba9d07a48c29a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:14:50 +0200
Subject: [PATCH 54/81] dir: implement StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_dir.go | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index eb8f8ba196..2710f80ef1 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1350,7 +1350,22 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageDir) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Renaming DIR storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
+	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	err := os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Renamed DIR storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, fullSnapshotName, storagePoolVolumeTypeCustom, s.poolID)
 }

From eba7ee2f5078769fc100d2938fb33bf1babba173 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:23:40 +0200
Subject: [PATCH 55/81] [UNTESTED] ceph: implement
 StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_ceph.go | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index cf43c2487c..27d40a94bc 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2695,7 +2695,37 @@ func (s *storageCeph) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageCeph) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Renaming CEPH storage volume on OSD storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	// unmap
+	err := cephRBDVolumeUnmap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName, true)
+	if err != nil {
+		logger.Errorf("Failed to unmap RBD storage volume for container \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+		return err
+	}
+	logger.Debugf("Unmapped RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
+	err = cephRBDVolumeRename(s.ClusterName, s.OSDPoolName, storagePoolVolumeTypeNameCustom, s.volume.Name, fullSnapshotName, s.UserName)
+	if err != nil {
+		logger.Errorf("Failed to rename RBD storage volume for container \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+		return err
+	}
+	logger.Debugf("Renamed RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
+
+	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Renamed CEPH storage volume on OSD storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, fullSnapshotName, storagePoolVolumeTypeCustom, s.poolID)
 }

From 24b00b88aa63330eb772df5a11221590ef5b18ab Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:23:53 +0200
Subject: [PATCH 56/81] [UNTESTED] ceph: fix StoragePoolVolumeRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_ceph.go | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 27d40a94bc..82a9fec00e 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -686,6 +686,13 @@ func (s *storageCeph) StoragePoolVolumeRename(newName string) error {
 	logger.Debugf(`Mapped RBD storage volume for container "%s" on storage pool "%s"`,
 		newName, s.pool.Name)
 
+	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
 	logger.Infof(`Renamed CEPH storage volume on OSD storage pool "%s" from "%s" to "%s`,
 		s.pool.Name, s.volume.Name, newName)
 

From a9b75a162ffc2110a275a3c67da2ae4aba3fd069 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:24:13 +0200
Subject: [PATCH 57/81] mock: implement StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_mock.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index a56ec97d28..e215461d9e 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -271,7 +271,5 @@ func (s *storageMock) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageMock) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	return nil
 }

From 6dc23661fe8c3c40e32f550caa576248d01629db Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:27:24 +0200
Subject: [PATCH 58/81] lvm: implement StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_lvm.go | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index daedd917bb..01db29f936 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2258,7 +2258,32 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageLvm) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Renaming LVM storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	_, err := s.StoragePoolVolumeUmount()
+	if err != nil {
+		return err
+	}
+
+	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
+
+	err = s.renameLVByPath(s.volume.Name, fullSnapshotName, storagePoolVolumeAPIEndpointCustom)
+	if err != nil {
+		return fmt.Errorf("Failed to rename logical volume from \"%s\" to \"%s\": %s", s.volume.Name, newName, err)
+	}
+
+	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Renamed LVM storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, newName, storagePoolVolumeTypeCustom, s.poolID)
 }

From 40af9e75dba606d30b16cae113d48bf757e045e1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:27:37 +0200
Subject: [PATCH 59/81] lvm: fix StoragePoolVolumeRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_lvm.go | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 01db29f936..7d270eb605 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -849,6 +849,18 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error {
 			s.volume.Name, newName, err)
 	}
 
+	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
+	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, fullSnapshotName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
 	logger.Infof(`Renamed ZFS storage volume on storage pool "%s" from "%s" to "%s`,
 		s.pool.Name, s.volume.Name, newName)
 

From 83f2b6ad22d9860efb8acbf8fe1e4cf5ee3a43bd Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:33:50 +0200
Subject: [PATCH 60/81] [UNTESTED] zfs: implement
 StoragePoolVolumeSnapshotRename()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_zfs.go | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 662836112f..afdaf86001 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -3043,7 +3043,21 @@ func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageZfs) StoragePoolVolumeSnapshotRename(newName string) error {
-	msg := fmt.Sprintf("Function not implemented")
-	logger.Errorf(msg)
-	return fmt.Errorf(msg)
+	logger.Infof("Renaming ZFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	sourceName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	if !ok {
+		return fmt.Errorf("Not a snapshot name")
+	}
+
+	oldZfsDatasetName := fmt.Sprintf("snapshot-%s", snapshotOnlyName)
+	newZfsDatasetName := fmt.Sprintf("snapshot-%s", newName)
+	err := zfsPoolVolumeSnapshotRename(s.getOnDiskPoolName(), fmt.Sprintf("custom/%s", sourceName), oldZfsDatasetName, newZfsDatasetName)
+	if err != nil {
+		return err
+	}
+
+	logger.Infof("Renamed ZFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+
+	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, newName, storagePoolVolumeTypeCustom, s.poolID)
 }

From da38399ce8223bacecff9479de95b179834fbade Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Aug 2018 15:43:30 +0200
Subject: [PATCH 61/81] lxc: allow storage volume snapshot rename

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 4d7d834b86..67511991e0 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -1062,6 +1062,43 @@ func (c *cmdStorageVolumeRename) Run(cmd *cobra.Command, args []string) error {
 	// Parse the input
 	volName, volType := c.storageVolume.parseVolume("custom", args[1])
 
+	isSnapshot := false
+	fields := strings.Split(volName, "/")
+	if len(fields) > 1 {
+		isSnapshot = true
+	} else if len(fields) > 2 {
+		return fmt.Errorf("Invalid snapshot name")
+	}
+
+	if isSnapshot {
+		// Create the storage volume entry
+		vol := api.StorageVolumeSnapshotPost{}
+		vol.Name = args[2]
+
+		// If a target member was specified, get the volume with the matching
+		// name on that member, if any.
+		if c.storage.flagTarget != "" {
+			client = client.UseTarget(c.storage.flagTarget)
+		}
+
+		if len(fields) != 2 {
+			return fmt.Errorf("Not a snapshot name")
+		}
+
+		op, err := client.RenameStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1], vol)
+		if err != nil {
+			return err
+		}
+
+		err = op.Wait()
+		if err != nil {
+			return err
+		}
+
+		fmt.Printf(i18n.G(`Renamed storage volume from "%s" to "%s"`)+"\n", volName, vol.Name)
+		return nil
+	}
+
 	// Create the storage volume entry
 	vol := api.StorageVolumePost{}
 	vol.Name = args[2]
@@ -1078,7 +1115,6 @@ func (c *cmdStorageVolumeRename) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	fmt.Printf(i18n.G(`Renamed storage volume from "%s" to "%s"`)+"\n", volName, vol.Name)
-
 	return nil
 }
 

From ed9e595454f3f96ede253e8d0a6457edceaa4ed0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 13:34:40 +0200
Subject: [PATCH 62/81] storage: add storagePoolVolumeSnapshotTypePut()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_volumes_snapshot.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 135102622b..4a4164c674 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -25,6 +25,7 @@ var storagePoolVolumeSnapshotTypeCmd = Command{
 	name:   "storage-pools/{pool}/volumes/{type}/{name}/snapshots/{snapshotName}",
 	post:   storagePoolVolumeSnapshotTypePost,
 	get:    storagePoolVolumeSnapshotTypeGet,
+	put:    storagePoolVolumeSnapshotTypePut,
 	delete: storagePoolVolumeSnapshotTypeDelete,
 }
 
@@ -350,6 +351,10 @@ func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {
 	return SyncResponseETag(true, &snapshot, etag)
 }
 
+func storagePoolVolumeSnapshotTypePut(d *Daemon, r *http.Request) Response {
+	return NotImplemented(fmt.Errorf("Updating storage pool volume snapshots is not implemented"))
+}
+
 func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) Response {
 	// Get the name of the storage pool the volume is supposed to be
 	// attached to.

From 3cc0e2f025a30b2fa78d16d26bd5a4a4352e5b96 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 13:16:33 +0200
Subject: [PATCH 63/81] client: add UpdateStoragePoolVolumeSnapshot()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 client/interfaces.go          |  1 +
 client/lxd_storage_volumes.go | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index 50d86b2b63..94716619e1 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -205,6 +205,7 @@ type ContainerServer interface {
 	GetStoragePoolVolumeSnapshots(pool string, volumeType string, volumeName string) (snapshots []api.StorageVolumeSnapshot, err error)
 	GetStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string) (snapshot *api.StorageVolumeSnapshot, ETag string, err error)
 	RenameStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string, snapshot api.StorageVolumeSnapshotPost) (op Operation, err error)
+	UpdateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string, volume api.StorageVolumeSnapshotPut, ETag string) (op Operation, err error)
 
 	// Cluster functions ("cluster" API extensions)
 	GetCluster() (cluster *api.Cluster, ETag string, err error)
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index ea7b5f0699..022adcd547 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -217,6 +217,22 @@ func (r *ProtocolLXD) DeleteStoragePoolVolumeSnapshot(pool string, volumeType st
 	return op, nil
 }
 
+// UpdateStoragePoolVolumeSnapshot updates the volume to match the provided StoragePoolVolume struct
+func (r *ProtocolLXD) UpdateStoragePoolVolumeSnapshot(pool string, volumeType string, volumeName string, snapshotName string, volume api.StorageVolumeSnapshotPut, ETag string) (Operation, error) {
+	if !r.HasExtension("storage_api_volume_snapshots") {
+		return nil, fmt.Errorf("The server is missing the required \"storage_api_volume_snapshots\" API extension")
+	}
+
+	// Send the request
+	path := fmt.Sprintf("/storage-pools/%s/volumes/%s/%s/snapshots/%s", url.QueryEscape(pool), url.QueryEscape(volumeType), url.QueryEscape(volumeName), url.QueryEscape(snapshotName))
+	op, _, err := r.queryOperation("PUT", path, volume, ETag)
+	if err != nil {
+		return nil, err
+	}
+
+	return op, nil
+}
+
 // MigrateStoragePoolVolume requests that LXD prepares for a storage volume migration
 func (r *ProtocolLXD) MigrateStoragePoolVolume(pool string, volume api.StorageVolumePost) (Operation, error) {
 	if !r.HasExtension("storage_api_remote_volume_handling") {

From 819686d78f0b2978bcb9d5280ea50519735001a4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 13:35:03 +0200
Subject: [PATCH 64/81] storage: implement storagePoolVolumeSnapshotTypePut()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/db/operations.go            |  3 ++
 lxd/storage_volumes_snapshot.go | 80 ++++++++++++++++++++++++++++++++-
 lxd/storage_volumes_utils.go    | 22 +++++++++
 3 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/lxd/db/operations.go b/lxd/db/operations.go
index fecf7872ee..580cce9605 100644
--- a/lxd/db/operations.go
+++ b/lxd/db/operations.go
@@ -52,6 +52,7 @@ const (
 	OperationVolumeMove
 	OperationVolumeSnapshotCreate
 	OperationVolumeSnapshotDelete
+	OperationVolumeSnapshotUpdate
 )
 
 // Description return a human-readable description of the operation type.
@@ -127,6 +128,8 @@ func (t OperationType) Description() string {
 		return "Creating storage volume snapshot"
 	case OperationVolumeSnapshotDelete:
 		return "Deleting storage volume snapshot"
+	case OperationVolumeSnapshotUpdate:
+		return "Updating storage volume snapshot"
 	default:
 		return "Executing operation"
 
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 4a4164c674..855cc2ad04 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -352,7 +352,85 @@ func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) Response {
 }
 
 func storagePoolVolumeSnapshotTypePut(d *Daemon, r *http.Request) Response {
-	return NotImplemented(fmt.Errorf("Updating storage pool volume snapshots is not implemented"))
+	// Get the name of the storage pool the volume is supposed to be
+	// attached to.
+	poolName := mux.Vars(r)["pool"]
+
+	// Get the name of the volume type.
+	volumeTypeName := mux.Vars(r)["type"]
+
+	// Get the name of the storage volume.
+	volumeName := mux.Vars(r)["name"]
+
+	// Get the name of the storage volume.
+	snapshotName := mux.Vars(r)["snapshotName"]
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	// Check that the storage volume type is valid.
+	if volumeType != storagePoolVolumeTypeCustom {
+		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
+	}
+
+	response := ForwardedResponseIfTargetIsRemote(d, r)
+	if response != nil {
+		return response
+	}
+
+	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
+	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	if response != nil {
+		return response
+	}
+
+	_, volume, err := d.cluster.StoragePoolNodeVolumeGetType(fullSnapshotName, volumeType, poolID)
+	if err != nil {
+		return SmartError(err)
+	}
+
+	// Validate the ETag
+	etag := []interface{}{volume.Name, volume.Description, volume.Config}
+	err = util.EtagCheck(r, etag)
+	if err != nil {
+		return PreconditionFailed(err)
+	}
+
+	req := api.StorageVolumeSnapshotPut{}
+	err = json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		return BadRequest(err)
+	}
+
+	var do func(*operation) error
+	var opDescription db.OperationType
+	do = func(op *operation) error {
+		err = storagePoolVolumeSnapshotUpdate(d.State(), poolName, volume.Name, volumeType, req.Description)
+		if err != nil {
+			return err
+		}
+
+		opDescription = db.OperationVolumeSnapshotDelete
+		return nil
+	}
+
+	resources := map[string][]string{}
+	resources["storage_volume_snapshots"] = []string{volumeName}
+
+	op, err := operationCreate(d.cluster, operationClassTask, opDescription, resources, nil, do, nil, nil)
+	if err != nil {
+		return InternalError(err)
+	}
+
+	return OperationResponse(op)
 }
 
 func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) Response {
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 2fdfb20260..f8965decdd 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -171,6 +171,28 @@ func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName str
 	return nil
 }
 
+func storagePoolVolumeSnapshotUpdate(state *state.State, poolName string, volumeName string, volumeType int, newDescription string) error {
+	s, err := storagePoolVolumeInit(state, poolName, volumeName, volumeType)
+	if err != nil {
+		return err
+	}
+
+	oldWritable := s.GetStoragePoolVolumeWritable()
+	oldDescription := oldWritable.Description
+
+	poolID, err := state.Cluster.StoragePoolGetID(poolName)
+	if err != nil {
+		return err
+	}
+
+	// Update the database if something changed
+	if newDescription != oldDescription {
+		return state.Cluster.StoragePoolVolumeUpdate(volumeName, volumeType, poolID, newDescription, oldWritable.Config)
+	}
+
+	return nil
+}
+
 func storagePoolVolumeUsedByContainersGet(s *state.State, volumeName string,
 	volumeTypeName string) ([]string, error) {
 	cts, err := containerLoadAll(s)

From d12a08b3668e0fa02ee0cc2160dcab4f6b8625fe Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 16:06:09 +0200
Subject: [PATCH 65/81] storage: handle conflicting API handling

Containers need to handle
storage-pools/{pool}/volumes/{type}/{name:.*}
requests to handle snapshots. At the same time custom storage volumes need to
handle
storage-pools/{pool}/volumes/{type}/{name}/snapshots/{snapshotName}. So move
the volume handling into separate commands.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/api_1.0.go         |   4 +-
 lxd/storage_volumes.go | 121 +++++++++++++++++++++++++++++++----------
 2 files changed, 95 insertions(+), 30 deletions(-)

diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index e5739d1f1e..00acf579cd 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -75,7 +75,9 @@ var api10 = []Command{
 	storagePoolsCmd,
 	storagePoolVolumesCmd,
 	storagePoolVolumesTypeCmd,
-	storagePoolVolumeTypeCmd,
+	storagePoolVolumeTypeContainerCmd,
+	storagePoolVolumeTypeCustomCmd,
+	storagePoolVolumeTypeImageCmd,
 	storagePoolVolumeSnapshotsTypeCmd,
 	storagePoolVolumeSnapshotTypeCmd,
 }
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 9ee0392fde..400705b150 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -33,13 +33,31 @@ var storagePoolVolumesTypeCmd = Command{
 	post: storagePoolVolumesTypePost,
 }
 
-var storagePoolVolumeTypeCmd = Command{
-	name:   "storage-pools/{pool}/volumes/{type}/{name:.*}",
-	post:   storagePoolVolumeTypePost,
-	get:    storagePoolVolumeTypeGet,
-	put:    storagePoolVolumeTypePut,
-	patch:  storagePoolVolumeTypePatch,
-	delete: storagePoolVolumeTypeDelete,
+var storagePoolVolumeTypeContainerCmd = Command{
+	name:   "storage-pools/{pool}/volumes/container/{name:.*}",
+	post:   storagePoolVolumeTypeContainerPost,
+	get:    storagePoolVolumeTypeContainerGet,
+	put:    storagePoolVolumeTypeContainerPut,
+	patch:  storagePoolVolumeTypeContainerPatch,
+	delete: storagePoolVolumeTypeContainerDelete,
+}
+
+var storagePoolVolumeTypeCustomCmd = Command{
+	name:   "storage-pools/{pool}/volumes/custom/{name}",
+	post:   storagePoolVolumeTypeCustomPost,
+	get:    storagePoolVolumeTypeCustomGet,
+	put:    storagePoolVolumeTypeCustomPut,
+	patch:  storagePoolVolumeTypeCustomPatch,
+	delete: storagePoolVolumeTypeCustomDelete,
+}
+
+var storagePoolVolumeTypeImageCmd = Command{
+	name:   "storage-pools/{pool}/volumes/image/{name}",
+	post:   storagePoolVolumeTypeImagePost,
+	get:    storagePoolVolumeTypeImageGet,
+	put:    storagePoolVolumeTypeImagePut,
+	patch:  storagePoolVolumeTypeImagePatch,
+	delete: storagePoolVolumeTypeImageDelete,
 }
 
 // /1.0/storage-pools/{name}/volumes
@@ -95,11 +113,11 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["name"]
 
-	recursion := util.IsRecursionRequest(r)
-
 	// Get the name of the volume type.
 	volumeTypeName := mux.Vars(r)["type"]
 
+	recursion := util.IsRecursionRequest(r)
+
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -371,7 +389,7 @@ func doVolumeMigration(d *Daemon, poolName string, req *api.StorageVolumesPost)
 
 // /1.0/storage-pools/{name}/volumes/{type}/{name}
 // Rename a storage volume of a given volume type in a given storage pool.
-func storagePoolVolumeTypePost(d *Daemon, r *http.Request) Response {
+func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string) Response {
 	// Get the name of the storage volume.
 	volumeName := mux.Vars(r)["name"]
 
@@ -379,9 +397,6 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["pool"]
 
-	// Get the name of the volume type.
-	volumeTypeName := mux.Vars(r)["type"]
-
 	req := api.StorageVolumePost{}
 
 	// Parse the request.
@@ -552,9 +567,21 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request) Response {
 	return OperationResponse(op)
 }
 
+func storagePoolVolumeTypeContainerPost(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePost(d, r, "container")
+}
+
+func storagePoolVolumeTypeCustomPost(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePost(d, r, "custom")
+}
+
+func storagePoolVolumeTypeImagePost(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePost(d, r, "image")
+}
+
 // /1.0/storage-pools/{pool}/volumes/{type}/{name}
 // Get storage volume of a given volume type on a given storage pool.
-func storagePoolVolumeTypeGet(d *Daemon, r *http.Request) Response {
+func storagePoolVolumeTypeGet(d *Daemon, r *http.Request, volumeTypeName string) Response {
 	// Get the name of the storage volume.
 	volumeName := mux.Vars(r)["name"]
 
@@ -562,9 +589,6 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["pool"]
 
-	// Get the name of the volume type.
-	volumeTypeName := mux.Vars(r)["type"]
-
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -609,8 +633,20 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request) Response {
 	return SyncResponseETag(true, volume, etag)
 }
 
+func storagePoolVolumeTypeContainerGet(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeGet(d, r, "container")
+}
+
+func storagePoolVolumeTypeCustomGet(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeGet(d, r, "custom")
+}
+
+func storagePoolVolumeTypeImageGet(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeGet(d, r, "image")
+}
+
 // /1.0/storage-pools/{pool}/volumes/{type}/{name}
-func storagePoolVolumeTypePut(d *Daemon, r *http.Request) Response {
+func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string) Response {
 	// Get the name of the storage volume.
 	volumeName := mux.Vars(r)["name"]
 
@@ -618,9 +654,6 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["pool"]
 
-	// Get the name of the volume type.
-	volumeTypeName := mux.Vars(r)["type"]
-
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -679,8 +712,20 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request) Response {
 	return EmptySyncResponse
 }
 
+func storagePoolVolumeTypeContainerPut(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePut(d, r, "container")
+}
+
+func storagePoolVolumeTypeCustomPut(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePut(d, r, "custom")
+}
+
+func storagePoolVolumeTypeImagePut(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePut(d, r, "image")
+}
+
 // /1.0/storage-pools/{pool}/volumes/{type}/{name}
-func storagePoolVolumeTypePatch(d *Daemon, r *http.Request) Response {
+func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName string) Response {
 	// Get the name of the storage volume.
 	volumeName := mux.Vars(r)["name"]
 
@@ -688,9 +733,6 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["pool"]
 
-	// Get the name of the volume type.
-	volumeTypeName := mux.Vars(r)["type"]
-
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -762,8 +804,20 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request) Response {
 	return EmptySyncResponse
 }
 
+func storagePoolVolumeTypeContainerPatch(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePatch(d, r, "container")
+}
+
+func storagePoolVolumeTypeCustomPatch(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePatch(d, r, "custom")
+}
+
+func storagePoolVolumeTypeImagePatch(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypePatch(d, r, "image")
+}
+
 // /1.0/storage-pools/{pool}/volumes/{type}/{name}
-func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request) Response {
+func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName string) Response {
 	// Get the name of the storage volume.
 	volumeName := mux.Vars(r)["name"]
 
@@ -771,9 +825,6 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request) Response {
 	// attached to.
 	poolName := mux.Vars(r)["pool"]
 
-	// Get the name of the volume type.
-	volumeTypeName := mux.Vars(r)["type"]
-
 	// Convert the volume type name to our internal integer representation.
 	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
 	if err != nil {
@@ -846,3 +897,15 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request) Response {
 
 	return EmptySyncResponse
 }
+
+func storagePoolVolumeTypeContainerDelete(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeDelete(d, r, "container")
+}
+
+func storagePoolVolumeTypeCustomDelete(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeDelete(d, r, "custom")
+}
+
+func storagePoolVolumeTypeImageDelete(d *Daemon, r *http.Request) Response {
+	return storagePoolVolumeTypeDelete(d, r, "image")
+}

From 4d1878d90d7014c0ec36b762abb10c75f4bdebe0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 14 Aug 2018 16:21:26 +0200
Subject: [PATCH 66/81] lxc: enable storage volume snapshot show

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 67511991e0..353684ca8e 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -1245,6 +1245,14 @@ func (c *cmdStorageVolumeShow) Run(cmd *cobra.Command, args []string) error {
 	// Parse the input
 	volName, volType := c.storageVolume.parseVolume("custom", args[1])
 
+	isSnapshot := false
+	fields := strings.Split(volName, "/")
+	if len(fields) > 1 {
+		isSnapshot = true
+	} else if len(fields) > 2 {
+		return fmt.Errorf("Invalid snapshot name")
+	}
+
 	// If a target member was specified, get the volume with the matching
 	// name on that member, if any.
 	if c.storage.flagTarget != "" {
@@ -1252,6 +1260,22 @@ func (c *cmdStorageVolumeShow) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Get the storage volume entry
+	if isSnapshot && volType != "container" {
+		vol, _, err := client.GetStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1])
+		if err != nil {
+			return err
+		}
+
+		data, err := yaml.Marshal(&vol)
+		if err != nil {
+			return err
+		}
+
+		fmt.Printf("%s", data)
+
+		return nil
+	}
+
 	vol, _, err := client.GetStoragePoolVolume(resource.name, volType, volName)
 	if err != nil {
 		return err

From 2dd60a1aa77add08ed345348b6044119596a8232 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 15 Aug 2018 12:37:21 +0200
Subject: [PATCH 67/81] lxc: enable storage volume snapshot edit

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 93 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 84 insertions(+), 9 deletions(-)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 353684ca8e..4d908d7d68 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -778,6 +778,14 @@ func (c *cmdStorageVolumeEdit) Run(cmd *cobra.Command, args []string) error {
 	// Parse the input
 	volName, volType := c.storageVolume.parseVolume("custom", args[1])
 
+	isSnapshot := false
+	fields := strings.Split(volName, "/")
+	if len(fields) > 1 {
+		isSnapshot = true
+	} else if len(fields) > 2 {
+		return fmt.Errorf("Invalid snapshot name")
+	}
+
 	// If stdin isn't a terminal, read text from it
 	if !termios.IsTerminal(int(syscall.Stdin)) {
 		contents, err := ioutil.ReadAll(os.Stdin)
@@ -785,6 +793,21 @@ func (c *cmdStorageVolumeEdit) Run(cmd *cobra.Command, args []string) error {
 			return err
 		}
 
+		if isSnapshot {
+			newdata := api.StorageVolumeSnapshotPut{}
+			err = yaml.Unmarshal(contents, &newdata)
+			if err != nil {
+				return err
+			}
+
+			op, err := client.UpdateStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1], newdata, "")
+			if err != nil {
+				return err
+			}
+
+			return op.Wait()
+		}
+
 		newdata := api.StorageVolumePut{}
 		err = yaml.Unmarshal(contents, &newdata)
 		if err != nil {
@@ -799,15 +822,32 @@ func (c *cmdStorageVolumeEdit) Run(cmd *cobra.Command, args []string) error {
 		client = client.UseTarget(c.storage.flagTarget)
 	}
 
-	// Extract the current value
-	vol, etag, err := client.GetStoragePoolVolume(resource.name, volType, volName)
-	if err != nil {
-		return err
-	}
+	data := []byte{}
+	var snapVol *api.StorageVolumeSnapshot
+	var vol *api.StorageVolume
+	etag := ""
+	if isSnapshot {
+		// Extract the current value
+		snapVol, etag, err = client.GetStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1])
+		if err != nil {
+			return err
+		}
 
-	data, err := yaml.Marshal(&vol)
-	if err != nil {
-		return err
+		data, err = yaml.Marshal(&snapVol)
+		if err != nil {
+			return err
+		}
+	} else {
+		// Extract the current value
+		vol, etag, err = client.GetStoragePoolVolume(resource.name, volType, volName)
+		if err != nil {
+			return err
+		}
+
+		data, err = yaml.Marshal(&vol)
+		if err != nil {
+			return err
+		}
 	}
 
 	// Spawn the editor
@@ -816,12 +856,47 @@ func (c *cmdStorageVolumeEdit) Run(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
+	if isSnapshot {
+		for {
+			var op lxd.Operation
+			// Parse the text received from the editor
+			newdata := api.StorageVolumeSnapshotPut{}
+			err = yaml.Unmarshal(content, &newdata)
+			if err == nil {
+				op, err = client.UpdateStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1], newdata, etag)
+				if err == nil {
+					err = op.Wait()
+				}
+			}
+
+			// Respawn the editor
+			if err != nil {
+				fmt.Fprintf(os.Stderr, i18n.G("Config parsing error: %s")+"\n", err)
+				fmt.Println(i18n.G("Press enter to open the editor again"))
+
+				_, err := os.Stdin.Read(make([]byte, 1))
+				if err != nil {
+					return err
+				}
+
+				content, err = shared.TextEditor("", content)
+				if err != nil {
+					return err
+				}
+				continue
+			}
+			break
+		}
+
+		return nil
+	}
+
 	for {
 		// Parse the text received from the editor
 		newdata := api.StorageVolume{}
 		err = yaml.Unmarshal(content, &newdata)
 		if err == nil {
-			err = client.UpdateStoragePoolVolume(resource.name, vol.Type, vol.Name, newdata.Writable(), etag)
+			err = client.UpdateStoragePoolVolume(resource.name, volType, vol.Name, newdata.Writable(), etag)
 		}
 
 		// Respawn the editor

From cf90e9e9f6bd5584fc3e1e71f0bef07e149152d9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 15 Aug 2018 12:50:23 +0200
Subject: [PATCH 68/81] lxc: enable storage volume snapshot get

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxc/storage_volume.go | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 4d908d7d68..0b7670ea23 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -965,11 +965,35 @@ func (c *cmdStorageVolumeGet) Run(cmd *cobra.Command, args []string) error {
 	// Parse input
 	volName, volType := c.storageVolume.parseVolume("custom", args[1])
 
+	isSnapshot := false
+	fields := strings.Split(volName, "/")
+	if len(fields) > 1 {
+		isSnapshot = true
+	} else if len(fields) > 2 {
+		return fmt.Errorf("Invalid snapshot name")
+	}
+
 	// If a target was specified, create the volume on the given member.
 	if c.storage.flagTarget != "" {
 		client = client.UseTarget(c.storage.flagTarget)
 	}
 
+	if isSnapshot && volType != "container" {
+		// Get the storage volume snapshot entry
+		resp, _, err := client.GetStoragePoolVolumeSnapshot(resource.name, volType, fields[0], fields[1])
+		if err != nil {
+			return err
+		}
+
+		for k, v := range resp.Config {
+			if k == args[2] {
+				fmt.Printf("%s\n", v)
+			}
+		}
+
+		return nil
+	}
+
 	// Get the storage volume entry
 	resp, _, err := client.GetStoragePoolVolume(resource.name, volType, volName)
 	if err != nil {

From becfefc69d67503ad34876ea7b1b479d35d555b7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 15 Aug 2018 12:51:08 +0200
Subject: [PATCH 69/81] i18n: Update translation templates

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 po/de.po      | 180 ++++++++++++++++++++++++++-----------------------
 po/el.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/es.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/fa.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/fi.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/fr.po      | 182 +++++++++++++++++++++++++++-----------------------
 po/hi.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/id.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/it.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/ja.po      | 182 +++++++++++++++++++++++++++-----------------------
 po/ko.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/lxd.pot    | 138 +++++++++++++++++++++-----------------
 po/nb_NO.po   | 179 ++++++++++++++++++++++++++-----------------------
 po/nl.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/pa.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/pl.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/pt_BR.po   | 179 ++++++++++++++++++++++++++-----------------------
 po/ru.po      | 180 ++++++++++++++++++++++++++-----------------------
 po/sr.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/sv.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/tr.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/uk.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/zh.po      | 179 ++++++++++++++++++++++++++-----------------------
 po/zh_Hans.po | 179 ++++++++++++++++++++++++++-----------------------
 24 files changed, 2291 insertions(+), 1972 deletions(-)

diff --git a/po/de.po b/po/de.po
index bc5b42027f..2de84da4da 100644
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: LXD\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-06-05 04:58+0000\n"
 "Last-Translator: Krombel <krombel at krombel.de>\n"
 "Language-Team: German <https://hosted.weblate.org/projects/linux-containers/"
@@ -54,7 +54,7 @@ msgstr ""
 "###\n"
 "### Der Name wird zwar angezeigt, lässt sich jedoch nicht ändern.\n"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -372,11 +372,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -414,7 +414,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -489,7 +489,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -536,12 +536,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -577,7 +577,7 @@ msgstr "kann nicht zum selben Container Namen kopieren"
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, fuzzy, c-format
 msgid "Config parsing error: %s"
 msgstr "YAML Analyse Fehler %v\n"
@@ -633,7 +633,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 #, fuzzy
 msgid "Copy storage volumes"
 msgstr "Anhalten des Containers fehlgeschlagen!"
@@ -648,7 +648,7 @@ msgstr "Herunterfahren des Containers erzwingen."
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, fuzzy, c-format
 msgid "Copying the storage volume: %s"
 msgstr "Anhalten des Containers fehlgeschlagen!"
@@ -692,7 +692,7 @@ msgstr "kann nicht zum selben Container Namen kopieren"
 msgid "Create new container file templates"
 msgstr "Anhalten des Containers fehlgeschlagen!"
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 #, fuzzy
 msgid "Create new custom storage volumes"
 msgstr "Anhalten des Containers fehlgeschlagen!"
@@ -736,7 +736,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr "BESCHREIBUNG"
 
@@ -786,7 +786,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 #, fuzzy
 msgid "Delete storage volumes"
 msgstr "Kein Zertifikat für diese Verbindung"
@@ -828,14 +828,15 @@ msgstr "Kein Zertifikat für diese Verbindung"
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -847,11 +848,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -934,7 +935,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1149,7 +1150,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1329,7 +1330,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1508,7 +1509,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 #, fuzzy
 msgid "List storage volumes"
 msgstr "Kein Zertifikat für diese Verbindung"
@@ -1723,13 +1724,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 #, fuzzy
 msgid "Missing pool name"
 msgstr "Profilname kann nicht geändert werden"
@@ -1743,7 +1744,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 #, fuzzy
 msgid "Missing source volume name"
 msgstr "Kein Zertifikat für diese Verbindung"
@@ -1763,8 +1764,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1778,7 +1779,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr "Herunterfahren des Containers erzwingen."
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 #, fuzzy
 msgid "Move storage volumes between pools"
 msgstr "Kein Zertifikat für diese Verbindung"
@@ -1788,7 +1789,7 @@ msgstr "Kein Zertifikat für diese Verbindung"
 msgid "Move the container without its snapshots"
 msgstr "Herunterfahren des Containers erzwingen."
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, fuzzy, c-format
 msgid "Moving the storage volume: %s"
 msgstr "Kein Zertifikat für diese Verbindung"
@@ -1803,7 +1804,7 @@ msgid "Must supply container name for: "
 msgstr "der Name des Ursprung Containers muss angegeben werden"
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1863,16 +1864,16 @@ msgstr "kann nicht zum selben Container Namen kopieren"
 msgid "No device found for this network"
 msgstr "Kein Zertifikat für diese Verbindung"
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 #, fuzzy
 msgid "No device found for this storage volume"
 msgstr "Kein Zertifikat für diese Verbindung"
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1881,10 +1882,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr "kein Wert in %q gefunden\n"
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1949,7 +1954,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -2179,12 +2184,12 @@ msgstr "Fehlerhafte Profil URL %s"
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 #, fuzzy
 msgid "Rename storage volumes"
 msgstr "Kein Zertifikat für diese Verbindung"
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2312,7 +2317,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr "Profil %s erstellt\n"
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 #, fuzzy
 msgid "Set storage volume configuration keys"
 msgstr "Profil %s erstellt\n"
@@ -2395,12 +2400,12 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 #, fuzzy
 msgid "Show storage volum configurations"
 msgstr "Profil %s erstellt\n"
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 #, fuzzy
 msgid "Show storage volume configurations"
 msgstr "Profil %s erstellt\n"
@@ -2442,6 +2447,11 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr "Größe: %.2vMB\n"
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+#, fuzzy
+msgid "Snapshot storage volumes"
+msgstr "Kein Zertifikat für diese Verbindung"
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2513,22 +2523,22 @@ msgstr "Profil %s erstellt\n"
 msgid "Storage pool name"
 msgstr "Profilname kann nicht geändert werden"
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, fuzzy, c-format
 msgid "Storage volume %s created"
 msgstr "Profil %s erstellt\n"
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, fuzzy, c-format
 msgid "Storage volume %s deleted"
 msgstr "Profil %s gelöscht\n"
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 #, fuzzy
 msgid "Storage volume copied successfully!"
 msgstr "Profil %s erstellt\n"
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 #, fuzzy
 msgid "Storage volume moved successfully!"
 msgstr "Profil %s erstellt\n"
@@ -2555,7 +2565,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2615,8 +2625,8 @@ msgstr "entfernte Instanz %s existiert nicht"
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 #, fuzzy
 msgid "The specified device doesn't exist"
 msgstr "entfernte Instanz %s existiert nicht"
@@ -2660,7 +2670,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2668,7 +2678,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2704,7 +2714,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2748,7 +2758,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 #, fuzzy
 msgid "Unset storage volume configuration keys"
 msgstr "Alternatives config Verzeichnis."
@@ -2850,11 +2860,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2877,7 +2887,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2909,7 +2919,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2968,7 +2978,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2984,11 +2994,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -3036,7 +3046,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3095,7 +3105,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -3178,7 +3188,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3374,13 +3384,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3403,7 +3413,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3557,7 +3567,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3589,7 +3599,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3637,7 +3647,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3653,6 +3663,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3722,7 +3736,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/el.po b/po/el.po
index 19e4cd4c84..0d14784a91 100644
--- a/po/el.po
+++ b/po/el.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2017-02-14 08:00+0000\n"
 "Last-Translator: Simos Xenitellis <simos.65 at gmail.com>\n"
 "Language-Team: Greek <https://hosted.weblate.org/projects/linux-containers/"
@@ -36,7 +36,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -262,11 +262,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -302,7 +302,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -372,7 +372,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -419,12 +419,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -458,7 +458,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -513,7 +513,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -526,7 +526,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -567,7 +567,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -606,7 +606,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -654,7 +654,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -695,14 +695,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -714,11 +715,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -799,7 +800,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1001,7 +1002,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1177,7 +1178,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1337,7 +1338,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1539,13 +1540,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1558,7 +1559,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1577,8 +1578,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1590,7 +1591,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1598,7 +1599,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1612,7 +1613,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1670,15 +1671,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1687,10 +1688,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1754,7 +1759,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1972,11 +1977,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2097,7 +2102,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2177,11 +2182,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2222,6 +2227,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2290,21 +2299,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2329,7 +2338,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2386,8 +2395,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2427,7 +2436,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2435,7 +2444,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2471,7 +2480,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2514,7 +2523,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2608,11 +2617,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2635,7 +2644,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2667,7 +2676,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2713,7 +2722,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2729,11 +2738,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2781,7 +2790,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2836,7 +2845,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2919,7 +2928,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3111,13 +3120,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3140,7 +3149,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3264,7 +3273,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3292,7 +3301,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3340,7 +3349,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3356,6 +3365,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3417,7 +3430,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/es.po b/po/es.po
index f2ceb33c7a..d7bc5b7f81 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-02-10 11:39+0000\n"
 "Last-Translator: Allan Esquivel Sibaja <allan.esquivel.sibaja at gmail.com>\n"
 "Language-Team: Spanish <https://hosted.weblate.org/projects/linux-containers/"
@@ -50,7 +50,7 @@ msgstr ""
 "###   source: /home/chb/mnt/lxd_test/default.img\n"
 "###   zfs.pool_name: default"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -320,11 +320,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -360,7 +360,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -429,7 +429,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr "No se puede jalar un directorio sin - recursivo"
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr "No se peude leer desde stdin: %s"
@@ -477,12 +477,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -516,7 +516,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -571,7 +571,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -584,7 +584,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -626,7 +626,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -665,7 +665,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -713,7 +713,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -754,14 +754,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -773,11 +774,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -857,7 +858,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1061,7 +1062,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1238,7 +1239,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1399,7 +1400,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1601,13 +1602,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1620,7 +1621,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1640,8 +1641,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1653,7 +1654,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1661,7 +1662,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1675,7 +1676,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1732,15 +1733,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1749,10 +1750,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1816,7 +1821,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -2034,11 +2039,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2159,7 +2164,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2239,11 +2244,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2284,6 +2289,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2352,21 +2361,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2391,7 +2400,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2448,8 +2457,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2489,7 +2498,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2497,7 +2506,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2533,7 +2542,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2576,7 +2585,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2671,11 +2680,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2698,7 +2707,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2730,7 +2739,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2776,7 +2785,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2792,11 +2801,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2844,7 +2853,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2899,7 +2908,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2982,7 +2991,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3174,13 +3183,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3203,7 +3212,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3327,7 +3336,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3355,7 +3364,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3403,7 +3412,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3419,6 +3428,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3480,7 +3493,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/fa.po b/po/fa.po
index f8ad223c42..f21a7a4fd7 100644
--- a/po/fa.po
+++ b/po/fa.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/fi.po b/po/fi.po
index 722f8d7d29..576f4b7622 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/fr.po b/po/fr.po
index cdcb8ec4ef..b5412b5515 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: LXD\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-03-06 13:50+0000\n"
 "Last-Translator: Alban Vidal <alban.vidal at zordhak.fr>\n"
 "Language-Team: French <https://hosted.weblate.org/projects/linux-containers/"
@@ -51,7 +51,7 @@ msgstr ""
 "###   source: /home/chb/mnt/lxd_test/default.img\n"
 "###   zfs.pool_name: default"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 #, fuzzy
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
@@ -362,11 +362,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -404,7 +404,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -475,7 +475,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr "impossible de récupérer un répertoire sans --recursive"
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr "Impossible de lire depuis stdin : %s"
@@ -525,12 +525,12 @@ msgstr "Afficher la version du client"
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -571,7 +571,7 @@ msgstr "Clé/valeur de configuration à appliquer au nouveau conteneur"
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr "Erreur lors de la lecture de la configuration : %s"
@@ -627,7 +627,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 #, fuzzy
 msgid "Copy storage volumes"
 msgstr "Copie de l'image : %s"
@@ -641,7 +641,7 @@ msgstr "Copiez le conteneur sans ses instantanés"
 msgid "Copying the image: %s"
 msgstr "Copie de l'image : %s"
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, fuzzy, c-format
 msgid "Copying the storage volume: %s"
 msgstr "Copie de l'image : %s"
@@ -701,7 +701,7 @@ msgstr "Création du conteneur"
 msgid "Create new container file templates"
 msgstr "L'arrêt du conteneur a échoué !"
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 #, fuzzy
 msgid "Create new custom storage volumes"
 msgstr "Copie de l'image : %s"
@@ -744,7 +744,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr "DESCRIPTION"
 
@@ -795,7 +795,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 #, fuzzy
 msgid "Delete storage volumes"
 msgstr "Copie de l'image : %s"
@@ -837,14 +837,15 @@ msgstr "Copie de l'image : %s"
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -856,11 +857,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -943,7 +944,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1165,7 +1166,7 @@ msgstr "Clé de configuration invalide"
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1352,7 +1353,7 @@ msgstr "Garder l'image à jour après la copie initiale"
 msgid "LAST USED AT"
 msgstr "DERNIÈRE UTILISATION À"
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1576,7 +1577,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 #, fuzzy
 msgid "List storage volumes"
 msgstr "Copie de l'image : %s"
@@ -1791,13 +1792,13 @@ msgid "Missing network name"
 msgstr "Nom du réseau"
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 #, fuzzy
 msgid "Missing pool name"
 msgstr "Nom de l'ensemble de stockage"
@@ -1811,7 +1812,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 #, fuzzy
 msgid "Missing source volume name"
 msgstr "Copie de l'image : %s"
@@ -1832,8 +1833,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 #, fuzzy
 msgid "More than one device matches, specify the device name"
 msgstr "Plus d'un périphérique correspond, spécifier le nom du périphérique."
@@ -1848,7 +1849,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr "Forcer le conteneur à s'arrêter"
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 #, fuzzy
 msgid "Move storage volumes between pools"
 msgstr "Copie de l'image : %s"
@@ -1858,7 +1859,7 @@ msgstr "Copie de l'image : %s"
 msgid "Move the container without its snapshots"
 msgstr "Forcer le conteneur à s'arrêter"
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, fuzzy, c-format
 msgid "Moving the storage volume: %s"
 msgstr "Copie de l'image : %s"
@@ -1872,7 +1873,7 @@ msgid "Must supply container name for: "
 msgstr "Vous devez fournir le nom d'un conteneur pour : "
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr "NOM"
 
@@ -1932,16 +1933,16 @@ msgstr "Clé/valeur de configuration à appliquer au nouveau conteneur"
 msgid "No device found for this network"
 msgstr "Aucun périphérique existant pour ce réseau"
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 #, fuzzy
 msgid "No device found for this storage volume"
 msgstr "Aucun périphérique existant pour ce réseau"
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1950,12 +1951,18 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 #, fuzzy
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 "Seuls les volumes \"personnalisés\" peuvent être attachés aux conteneurs."
 
+#: lxc/storage_volume.go:1471
+#, fuzzy
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+"Seuls les volumes \"personnalisés\" peuvent être attachés aux conteneurs."
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr "Seules les URLs https sont supportées par simplestreams"
@@ -2022,7 +2029,7 @@ msgid "Pid: %d"
 msgstr "Pid : %d"
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr "Appuyer sur Entrée pour ouvrir à nouveau l'éditeur"
 
@@ -2251,12 +2258,12 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 #, fuzzy
 msgid "Rename storage volumes"
 msgstr "Copie de l'image : %s"
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2389,7 +2396,7 @@ msgstr "Clé de configuration invalide"
 msgid "Set storage pool configuration keys"
 msgstr "Clé de configuration invalide"
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 #, fuzzy
 msgid "Set storage volume configuration keys"
 msgstr "Clé de configuration invalide"
@@ -2478,12 +2485,12 @@ msgstr "Afficher la configuration étendue"
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 #, fuzzy
 msgid "Show storage volum configurations"
 msgstr "Afficher la configuration étendue"
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 #, fuzzy
 msgid "Show storage volume configurations"
 msgstr "Afficher la configuration étendue"
@@ -2526,6 +2533,11 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr "Taille : %.2f Mo"
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+#, fuzzy
+msgid "Snapshot storage volumes"
+msgstr "Copie de l'image : %s"
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr "Instantanés :"
@@ -2596,22 +2608,22 @@ msgstr "Le réseau %s a été créé"
 msgid "Storage pool name"
 msgstr "Nom de l'ensemble de stockage"
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, fuzzy, c-format
 msgid "Storage volume %s created"
 msgstr "Profil %s créé"
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, fuzzy, c-format
 msgid "Storage volume %s deleted"
 msgstr "Profil %s supprimé"
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 #, fuzzy
 msgid "Storage volume copied successfully!"
 msgstr "Image copiée avec succès !"
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 #, fuzzy
 msgid "Storage volume moved successfully!"
 msgstr "Image copiée avec succès !"
@@ -2639,7 +2651,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr "TYPE"
 
@@ -2704,8 +2716,8 @@ msgstr "Le périphérique indiqué n'existe pas"
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr "Le périphérique indiqué n'existe pas"
 
@@ -2747,7 +2759,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2755,7 +2767,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2791,7 +2803,7 @@ msgid "URL"
 msgstr "URL"
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr "UTILISÉ PAR"
 
@@ -2840,7 +2852,7 @@ msgstr "Clé de configuration invalide"
 msgid "Unset storage pool configuration keys"
 msgstr "Clé de configuration invalide"
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 #, fuzzy
 msgid "Unset storage volume configuration keys"
 msgstr "Clé de configuration invalide"
@@ -2943,11 +2955,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2970,7 +2982,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -3002,7 +3014,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -3064,7 +3076,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3080,11 +3092,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -3132,7 +3144,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3191,7 +3203,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -3275,7 +3287,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3489,13 +3501,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3518,7 +3530,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3687,7 +3699,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3719,7 +3731,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3767,7 +3779,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3783,6 +3795,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3853,7 +3869,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/hi.po b/po/hi.po
index 7f3d51ab16..d504e4d7a0 100644
--- a/po/hi.po
+++ b/po/hi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/id.po b/po/id.po
index df0d4cd9fd..c15a0e0283 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/it.po b/po/it.po
index 4516e5d07a..50dbaed987 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2017-08-18 14:22+0000\n"
 "Last-Translator: Alberto Donato <alberto.donato at gmail.com>\n"
 "Language-Team: Italian <https://hosted.weblate.org/projects/linux-containers/"
@@ -51,7 +51,7 @@ msgstr ""
 "###   source: /home/chb/mnt/lxd_test/default.img\n"
 "###   zfs.pool_name: default"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -285,11 +285,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -325,7 +325,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -395,7 +395,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr "Impossibile effettuare il pull di una directory senza --recursive"
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr "Impossible leggere da stdin: %s"
@@ -442,12 +442,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -481,7 +481,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -536,7 +536,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -549,7 +549,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -592,7 +592,7 @@ msgstr "Creazione del container in corso"
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -631,7 +631,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr "DESCRIZIONE"
 
@@ -679,7 +679,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -720,14 +720,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -739,11 +740,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -823,7 +824,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1028,7 +1029,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1207,7 +1208,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1369,7 +1370,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1573,13 +1574,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1611,8 +1612,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1624,7 +1625,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1632,7 +1633,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1646,7 +1647,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1703,15 +1704,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1720,10 +1721,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1788,7 +1793,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -2006,11 +2011,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2132,7 +2137,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2212,11 +2217,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2257,6 +2262,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2326,21 +2335,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2366,7 +2375,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2424,8 +2433,8 @@ msgstr "il remote %s non esiste"
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2465,7 +2474,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2473,7 +2482,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2509,7 +2518,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2553,7 +2562,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2649,11 +2658,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2676,7 +2685,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2708,7 +2717,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2754,7 +2763,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2770,11 +2779,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2822,7 +2831,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2877,7 +2886,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2960,7 +2969,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3152,13 +3161,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3181,7 +3190,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3305,7 +3314,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3381,7 +3390,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3397,6 +3406,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3458,7 +3471,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/ja.po b/po/ja.po
index 024388aaa1..5f36c8fc47 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: LXD\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-07-30 09:55+0000\n"
 "Last-Translator: KATOH Yasufumi <karma at jazz.email.ne.jp>\n"
 "Language-Team: Japanese <https://hosted.weblate.org/projects/linux-"
@@ -36,7 +36,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -263,11 +263,11 @@ msgstr "プロファイルにネットワークインターフェースを追加
 msgid "Attach new network interfaces to containers"
 msgstr "新たなネットワークインターフェースをコンテナに追加します"
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr "新たにストレージボリュームをコンテナに追加します"
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr "新しいストレージボリュームをプロファイルに追加します"
 
@@ -307,7 +307,7 @@ msgid "Bad key/value pair: %s"
 msgstr "不適切なキー/値のペア: %s"
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr "不適切な キー=値 のペア: %s"
@@ -377,7 +377,7 @@ msgstr ""
 "ディレクトリを pull する場合は --recursive オプションを使用してください"
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr "標準入力から読み込めません: %s"
@@ -426,12 +426,12 @@ msgstr "クライアントバージョン: %s\n"
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr "クラスタメンバ名"
 
@@ -469,7 +469,7 @@ msgstr "移動先のコンテナに適用するキー/値の設定"
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr "設定の構文エラー: %s"
@@ -528,7 +528,7 @@ msgstr "プロファイルに継承されたデバイスをコピーし、設定
 msgid "Copy profiles"
 msgstr "プロファイルをコピーします"
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr "ストレージボリュームをコピーします"
 
@@ -541,7 +541,7 @@ msgstr "コンテナをコピーします (スナップショットはコピー
 msgid "Copying the image: %s"
 msgstr "イメージのコピー中: %s"
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr "ストレージボリュームのコピー中: %s"
@@ -586,7 +586,7 @@ msgstr "イメージからコンテナを作成します"
 msgid "Create new container file templates"
 msgstr "新たにコンテナのファイルテンプレートを作成します"
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr "新たにカスタムストレージボリュームを作成します"
 
@@ -625,7 +625,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -673,7 +673,7 @@ msgstr "プロファイルを削除します"
 msgid "Delete storage pools"
 msgstr "ストレージプールを削除します"
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr "ストレージボリュームを削除します"
 
@@ -714,14 +714,15 @@ msgstr "ストレージボリュームを削除します"
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr "説明"
 
@@ -733,11 +734,11 @@ msgstr "コンテナからネットワークインターフェースを取り外
 msgid "Detach network interfaces from profiles"
 msgstr "プロファイルからネットワークインターフェースを取り外します"
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr "コンテナからストレージボリュームを取り外します"
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr "プロファイルからストレージボリュームを取り外します"
 
@@ -817,7 +818,7 @@ msgstr "プロファイル設定をYAMLで編集します"
 msgid "Edit storage pool configurations as YAML"
 msgstr "ストレージプールの設定をYAMLで編集します"
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr "ストレージボリュームの設定をYAMLで編集します"
 
@@ -1035,7 +1036,7 @@ msgstr "プロファイルの設定値を取得します"
 msgid "Get values for storage pool configuration keys"
 msgstr "ストレージプールの設定値を取得します"
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr "ストレージボリュームの設定値を取得します"
 
@@ -1219,7 +1220,7 @@ msgstr "最初にコピーした後も常にイメージを最新の状態に保
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1458,7 +1459,7 @@ msgstr ""
 msgid "List profiles"
 msgstr "プロファイルを一覧表示します"
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr "ストレージボリュームを一覧表示します"
 
@@ -1677,13 +1678,13 @@ msgid "Missing network name"
 msgstr "ネットワーク名を指定する必要があります"
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr "ストレージプール名を指定する必要があります"
 
@@ -1696,7 +1697,7 @@ msgstr "プロファイル名を指定する必要があります"
 msgid "Missing source profile name"
 msgstr "コピー元のプロファイル名を指定する必要があります"
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr "コピー元のボリューム名を指定する必要があります"
 
@@ -1718,8 +1719,8 @@ msgstr ""
 "\n"
 "デフォルトではすべてのタイプのメッセージをモニタリングします。"
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr "複数のデバイスとマッチします。デバイス名を指定してください"
 
@@ -1733,7 +1734,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr "LXD サーバ内もしくはサーバ間でコンテナを移動します"
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr "プール間でストレージボリュームを移動します"
 
@@ -1741,7 +1742,7 @@ msgstr "プール間でストレージボリュームを移動します"
 msgid "Move the container without its snapshots"
 msgstr "コンテナを移動します (スナップショットは移動しません)"
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr "ストレージボリュームの移動中: %s"
@@ -1755,7 +1756,7 @@ msgid "Must supply container name for: "
 msgstr "コンテナ名を指定する必要があります: "
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1812,15 +1813,15 @@ msgstr "指定するデバイスに適用する新しいキー/値"
 msgid "No device found for this network"
 msgstr "このネットワークに対するデバイスがありません"
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr "このストレージボリュームに対するデバイスがありません"
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr "コピー元のボリュームに対するストレージプールが指定されていません"
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr "コピー先のボリュームに対するストレージプールが指定されていません"
 
@@ -1829,10 +1830,15 @@ msgstr "コピー先のボリュームに対するストレージプールが指
 msgid "No value found in %q"
 msgstr "%q に設定する値が指定されていません"
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr "\"カスタム\" のボリュームのみがコンテナにアタッチできます"
 
+#: lxc/storage_volume.go:1471
+#, fuzzy
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr "\"カスタム\" のボリュームのみがコンテナにアタッチできます"
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr "simplestreams は https の URL のみサポートします"
@@ -1896,7 +1902,7 @@ msgid "Pid: %d"
 msgstr "Pid: %d"
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr "再度エディタを開くためには Enter キーを押します"
 
@@ -2114,11 +2120,11 @@ msgstr "プロファイル名を変更します"
 msgid "Rename remotes"
 msgstr "リモートサーバ名を変更します"
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr "ストレージボリューム名を変更します"
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr "ストレージボリューム名 \"%s\" を \"%s\" に変更しました"
@@ -2246,7 +2252,7 @@ msgstr "プロファイルの設定項目を設定します"
 msgid "Set storage pool configuration keys"
 msgstr "ストレージプールの設定項目を設定します"
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr "ストレージボリュームの設定項目を設定します"
 
@@ -2326,11 +2332,11 @@ msgstr "プロファイルの設定を表示します"
 msgid "Show storage pool configurations and resources"
 msgstr "ストレージプールの設定とリソースを表示します"
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr "ストレージボリュームの設定を表示します"
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr "ストレージボリュームの設定を表示する"
 
@@ -2371,6 +2377,11 @@ msgstr "ストレージプールの情報を表示します"
 msgid "Size: %.2fMB"
 msgstr "サイズ: %.2fMB"
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+#, fuzzy
+msgid "Snapshot storage volumes"
+msgstr "ストレージボリュームを一覧表示します"
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr "スナップショット:"
@@ -2439,21 +2450,21 @@ msgstr "ストレージプール %s はメンバ %s 上でペンディング状
 msgid "Storage pool name"
 msgstr "ストレージプール名"
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr "ストレージボリューム %s を作成しました"
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr "ストレージボリューム %s を削除しました"
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr "ストレージボリュームのコピーが成功しました!"
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr "ストレージボリュームの移動が成功しました!"
 
@@ -2479,7 +2490,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2541,8 +2552,8 @@ msgstr "プロファイルのデバイスが存在しません"
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr "指定したデバイスが存在しません"
 
@@ -2588,7 +2599,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr "転送モード。pull, push, relay のいずれか(デフォルトはpull)"
 
@@ -2596,7 +2607,7 @@ msgstr "転送モード。pull, push, relay のいずれか(デフォルトはpu
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr "転送モード。pull, push, relay のいずれか(デフォルトはpull)"
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr "転送モード。pull, push, relay のいずれか(デフォルトはpull)。"
 
@@ -2632,7 +2643,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2675,7 +2686,7 @@ msgstr "プロファイルの設定を削除します"
 msgid "Unset storage pool configuration keys"
 msgstr "ストレージプールの設定を削除します"
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr "ストレージボリュームの設定を削除します"
 
@@ -2772,11 +2783,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2799,7 +2810,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2831,7 +2842,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2880,7 +2891,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2896,11 +2907,11 @@ msgstr "説明"
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2950,7 +2961,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3007,7 +3018,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -3090,7 +3101,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3372,7 +3383,7 @@ msgstr ""
 "lxc storage edit [<remote>:]<pool> < pool.yaml\n"
 "    pool.yaml の内容でストレージプールを更新します。"
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
@@ -3380,7 +3391,7 @@ msgstr ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    pool.yaml の内容でストレージボリュームを更新します。"
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3410,7 +3421,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3542,7 +3553,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3570,7 +3581,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3618,7 +3629,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3634,6 +3645,11 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+#, fuzzy
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr "restore [<remote>:]<container> <snapshot>"
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr "使用量"
@@ -3696,7 +3712,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/ko.po b/po/ko.po
index 64fa3b42aa..b224806ef3 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/lxd.pot b/po/lxd.pot
index f72603aca2..a231b3a266 100644
--- a/po/lxd.pot
+++ b/po/lxd.pot
@@ -7,7 +7,7 @@
 msgid   ""
 msgstr  "Project-Id-Version: lxd\n"
         "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-        "POT-Creation-Date: 2018-08-14 12:00-0400\n"
+        "POT-Creation-Date: 2018-08-15 12:51+0200\n"
         "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
         "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
         "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -32,7 +32,7 @@ msgid   "### This is a yaml representation of a storage pool.\n"
         "###   zfs.pool_name: default"
 msgstr  ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid   "### This is a yaml representation of a storage volume.\n"
         "### Any line starting with a '# will be ignored.\n"
         "###\n"
@@ -252,11 +252,11 @@ msgstr  ""
 msgid   "Attach new network interfaces to containers"
 msgstr  ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid   "Attach new storage volumes to containers"
 msgstr  ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid   "Attach new storage volumes to profiles"
 msgstr  ""
 
@@ -290,7 +290,7 @@ msgstr  ""
 msgid   "Bad key/value pair: %s"
 msgstr  ""
 
-#: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123 lxc/storage_volume.go:454
+#: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123 lxc/storage_volume.go:458
 #, c-format
 msgid   "Bad key=value pair: %s"
 msgstr  ""
@@ -358,7 +358,7 @@ msgstr  ""
 msgid   "Can't pull a directory without --recursive"
 msgstr  ""
 
-#: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617 lxc/storage_volume.go:1126
+#: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617 lxc/storage_volume.go:1282
 #, c-format
 msgid   "Can't read from stdin: %s"
 msgstr  ""
@@ -402,7 +402,7 @@ msgstr  ""
 msgid   "Client version: %s\n"
 msgstr  ""
 
-#: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259 lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098 lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576 lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287 lxc/storage_volume.go:415 lxc/storage_volume.go:490 lxc/storage_volume.go:716 lxc/storage_volume.go:842 lxc/storage_volume.go:984 lxc/storage_volume.go:1014 lxc/storage_volume.go:1078 lxc/storage_volume.go:1161 lxc/storage_volume.go:1230
+#: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259 lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098 lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576 lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291 lxc/storage_volume.go:419 lxc/storage_volume.go:494 lxc/storage_volume.go:737 lxc/storage_volume.go:938 lxc/storage_volume.go:1104 lxc/storage_volume.go:1134 lxc/storage_volume.go:1234 lxc/storage_volume.go:1317 lxc/storage_volume.go:1410
 msgid   "Cluster member name"
 msgstr  ""
 
@@ -433,7 +433,7 @@ msgstr  ""
 msgid   "Config key/value to apply to the target container"
 msgstr  ""
 
-#: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144 lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298 lxc/storage_volume.go:808
+#: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144 lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298 lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid   "Config parsing error: %s"
 msgstr  ""
@@ -487,7 +487,7 @@ msgstr  ""
 msgid   "Copy profiles"
 msgstr  ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid   "Copy storage volumes"
 msgstr  ""
 
@@ -500,7 +500,7 @@ msgstr  ""
 msgid   "Copying the image: %s"
 msgstr  ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid   "Copying the storage volume: %s"
 msgstr  ""
@@ -540,7 +540,7 @@ msgstr  ""
 msgid   "Create new container file templates"
 msgstr  ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid   "Create new custom storage volumes"
 msgstr  ""
 
@@ -578,7 +578,7 @@ msgstr  ""
 msgid   "DATABASE"
 msgstr  ""
 
-#: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856 lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856 lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid   "DESCRIPTION"
 msgstr  ""
 
@@ -626,11 +626,11 @@ msgstr  ""
 msgid   "Delete storage pools"
 msgstr  ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid   "Delete storage volumes"
 msgstr  ""
 
-#: lxc/action.go:31 lxc/action.go:50 lxc/action.go:70 lxc/action.go:91 lxc/alias.go:23 lxc/alias.go:55 lxc/alias.go:99 lxc/alias.go:147 lxc/alias.go:198 lxc/cluster.go:27 lxc/cluster.go:64 lxc/cluster.go:147 lxc/cluster.go:197 lxc/cluster.go:243 lxc/cluster.go:289 lxc/config.go:29 lxc/config.go:88 lxc/config.go:289 lxc/config.go:355 lxc/config.go:452 lxc/config.go:560 lxc/config_device.go:24 lxc/config_device.go:76 lxc/config_device.go:179 lxc/config_device.go:252 lxc/config_device.go:318 lxc/config_device.go:405 lxc/config_device.go:493 lxc/config_device.go:582 lxc/config_device.go:650 lxc/config_metadata.go:29 lxc/config_metadata.go:54 lxc/config_metadata.go:176 lxc/config_template.go:30 lxc/config_template.go:67 lxc/config_template.go:110 lxc/config_template.go:152 lxc/config_template.go:236 lxc/config_template.go:298 lxc/config_trust.go:30 lxc/config_trust.go:59 lxc/config_trust.go:115 lxc/config_trust.go:197 lxc/console.go:32 lxc/copy.go:37 lxc/delete.go:30 lxc/exec.go:39 lxc/export.go:30 lxc/file.go:42 lxc/file.go:75 lxc/file.go:124 lxc/file.go:187 lxc/file.go:376 lxc/image.go:42 lxc/image.go:131 lxc/image.go:261 lxc/image.go:312 lxc/image.go:435 lxc/image.go:571 lxc/image.go:776 lxc/image.go:890 lxc/image.go:1212 lxc/image.go:1285 lxc/image_alias.go:26 lxc/image_alias.go:59 lxc/image_alias.go:106 lxc/image_alias.go:149 lxc/image_alias.go:250 lxc/import.go:25 lxc/info.go:29 lxc/init.go:35 lxc/launch.go:22 lxc/list.go:48 lxc/main.go:47 lxc/manpage.go:19 lxc/monitor.go:31 lxc/move.go:36 lxc/network.go:34 lxc/network.go:110 lxc/network.go:183 lxc/network.go:256 lxc/network.go:326 lxc/network.go:373 lxc/network.go:458 lxc/network.go:543 lxc/network.go:666 lxc/network.go:724 lxc/network.go:794 lxc/network.go:914 lxc/network.go:979 lxc/network.go:1026 lxc/network.go:1095 lxc/network.go:1157 lxc/operation.go:25 lxc/operation.go:54 lxc/operation.go:98 lxc/operation.go:174 lxc/profile.go:30 lxc/profile.go:102 lxc/profile.go:163 lxc/profile.go:241 lxc/profile.go:297 lxc/profile.go:348 lxc/profile.go:396 lxc/profile.go:520 lxc/profile.go:568 lxc/profile.go:632 lxc/profile.go:705 lxc/profile.go:753 lxc/profile.go:812 lxc/profile.go:866 lxc/publish.go:34 lxc/query.go:30 lxc/remote.go:37 lxc/remote.go:87 lxc/remote.go:383 lxc/remote.go:419 lxc/remote.go:524 lxc/remote.go:586 lxc/remote.go:636 lxc/remote.go:674 lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33 lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328 lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645 lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122 lxc/storage_volume.go:201 lxc/storage_volume.go:283 lxc/storage_volume.go:412 lxc/storage_volume.go:487 lxc/storage_volume.go:547 lxc/storage_volume.go:629 lxc/storage_volume.go:710 lxc/storage_volume.go:839 lxc/storage_volume.go:904 lxc/storage_volume.go:980 lxc/storage_volume.go:1011 lxc/storage_volume.go:1075 lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/action.go:31 lxc/action.go:50 lxc/action.go:70 lxc/action.go:91 lxc/alias.go:23 lxc/alias.go:55 lxc/alias.go:99 lxc/alias.go:147 lxc/alias.go:198 lxc/cluster.go:27 lxc/cluster.go:64 lxc/cluster.go:147 lxc/cluster.go:197 lxc/cluster.go:243 lxc/cluster.go:289 lxc/config.go:29 lxc/config.go:88 lxc/config.go:289 lxc/config.go:355 lxc/config.go:452 lxc/config.go:560 lxc/config_device.go:24 lxc/config_device.go:76 lxc/config_device.go:179 lxc/config_device.go:252 lxc/config_device.go:318 lxc/config_device.go:405 lxc/config_device.go:493 lxc/config_device.go:582 lxc/config_device.go:650 lxc/config_metadata.go:29 lxc/config_metadata.go:54 lxc/config_metadata.go:176 lxc/config_template.go:30 lxc/config_template.go:67 lxc/config_template.go:110 lxc/config_template.go:152 lxc/config_template.go:236 lxc/config_template.go:298 lxc/config_trust.go:30 lxc/config_trust.go:59 lxc/config_trust.go:115 lxc/config_trust.go:197 lxc/console.go:32 lxc/copy.go:37 lxc/delete.go:30 lxc/exec.go:39 lxc/export.go:30 lxc/file.go:42 lxc/file.go:75 lxc/file.go:124 lxc/file.go:187 lxc/file.go:376 lxc/image.go:42 lxc/image.go:131 lxc/image.go:261 lxc/image.go:312 lxc/image.go:435 lxc/image.go:571 lxc/image.go:776 lxc/image.go:890 lxc/image.go:1212 lxc/image.go:1285 lxc/image_alias.go:26 lxc/image_alias.go:59 lxc/image_alias.go:106 lxc/image_alias.go:149 lxc/image_alias.go:250 lxc/import.go:25 lxc/info.go:29 lxc/init.go:35 lxc/launch.go:22 lxc/list.go:48 lxc/main.go:47 lxc/manpage.go:19 lxc/monitor.go:31 lxc/move.go:36 lxc/network.go:34 lxc/network.go:110 lxc/network.go:183 lxc/network.go:256 lxc/network.go:326 lxc/network.go:373 lxc/network.go:458 lxc/network.go:543 lxc/network.go:666 lxc/network.go:724 lxc/network.go:794 lxc/network.go:914 lxc/network.go:979 lxc/network.go:1026 lxc/network.go:1095 lxc/network.go:1157 lxc/operation.go:25 lxc/operation.go:54 lxc/operation.go:98 lxc/operation.go:174 lxc/profile.go:30 lxc/profile.go:102 lxc/profile.go:163 lxc/profile.go:241 lxc/profile.go:297 lxc/profile.go:348 lxc/profile.go:396 lxc/profile.go:520 lxc/profile.go:568 lxc/profile.go:632 lxc/profile.go:705 lxc/profile.go:753 lxc/profile.go:812 lxc/profile.go:866 lxc/publish.go:34 lxc/query.go:30 lxc/remote.go:37 lxc/remote.go:87 lxc/remote.go:383 lxc/remote.go:419 lxc/remote.go:524 lxc/remote.go:586 lxc/remote.go:636 lxc/remote.go:674 lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33 lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328 lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645 lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126 lxc/storage_volume.go:205 lxc/storage_volume.go:287 lxc/storage_volume.go:416 lxc/storage_volume.go:491 lxc/storage_volume.go:568 lxc/storage_volume.go:650 lxc/storage_volume.go:731 lxc/storage_volume.go:935 lxc/storage_volume.go:1024 lxc/storage_volume.go:1100 lxc/storage_volume.go:1131 lxc/storage_volume.go:1231 lxc/storage_volume.go:1308 lxc/storage_volume.go:1407 lxc/storage_volume.go:1440 lxc/version.go:22
 msgid   "Description"
 msgstr  ""
 
@@ -642,11 +642,11 @@ msgstr  ""
 msgid   "Detach network interfaces from profiles"
 msgstr  ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid   "Detach storage volumes from containers"
 msgstr  ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid   "Detach storage volumes from profiles"
 msgstr  ""
 
@@ -726,7 +726,7 @@ msgstr  ""
 msgid   "Edit storage pool configurations as YAML"
 msgstr  ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid   "Edit storage volume configurations as YAML"
 msgstr  ""
 
@@ -921,7 +921,7 @@ msgstr  ""
 msgid   "Get values for storage pool configuration keys"
 msgstr  ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid   "Get values for storage volume configuration keys"
 msgstr  ""
 
@@ -1093,7 +1093,7 @@ msgstr  ""
 msgid   "LAST USED AT"
 msgstr  ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid   "LOCATION"
 msgstr  ""
 
@@ -1247,7 +1247,7 @@ msgstr  ""
 msgid   "List profiles"
 msgstr  ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid   "List storage volumes"
 msgstr  ""
 
@@ -1436,7 +1436,7 @@ msgstr  ""
 msgid   "Missing network name"
 msgstr  ""
 
-#: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408 lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146 lxc/storage_volume.go:225 lxc/storage_volume.go:437 lxc/storage_volume.go:512 lxc/storage_volume.go:571 lxc/storage_volume.go:653 lxc/storage_volume.go:752 lxc/storage_volume.go:864 lxc/storage_volume.go:928 lxc/storage_volume.go:1036 lxc/storage_volume.go:1100 lxc/storage_volume.go:1183
+#: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408 lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150 lxc/storage_volume.go:229 lxc/storage_volume.go:441 lxc/storage_volume.go:516 lxc/storage_volume.go:592 lxc/storage_volume.go:674 lxc/storage_volume.go:773 lxc/storage_volume.go:960 lxc/storage_volume.go:1048 lxc/storage_volume.go:1156 lxc/storage_volume.go:1256 lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid   "Missing pool name"
 msgstr  ""
 
@@ -1448,7 +1448,7 @@ msgstr  ""
 msgid   "Missing source profile name"
 msgstr  ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid   "Missing source volume name"
 msgstr  ""
 
@@ -1466,7 +1466,7 @@ msgid   "Monitor a local or remote LXD server\n"
         "By default the monitor will listen to all message types."
 msgstr  ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591 lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612 lxc/storage_volume.go:693
 msgid   "More than one device matches, specify the device name"
 msgstr  ""
 
@@ -1478,7 +1478,7 @@ msgstr  ""
 msgid   "Move containers within or in between LXD instances"
 msgstr  ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid   "Move storage volumes between pools"
 msgstr  ""
 
@@ -1486,7 +1486,7 @@ msgstr  ""
 msgid   "Move the container without its snapshots"
 msgstr  ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid   "Moving the storage volume: %s"
 msgstr  ""
@@ -1499,7 +1499,7 @@ msgstr  ""
 msgid   "Must supply container name for: "
 msgstr  ""
 
-#: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613 lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613 lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid   "NAME"
 msgstr  ""
 
@@ -1556,15 +1556,15 @@ msgstr  ""
 msgid   "No device found for this network"
 msgstr  ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid   "No device found for this storage volume"
 msgstr  ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid   "No storage pool for source volume specified"
 msgstr  ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid   "No storage pool for target volume specified"
 msgstr  ""
 
@@ -1573,10 +1573,14 @@ msgstr  ""
 msgid   "No value found in %q"
 msgstr  ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid   "Only \"custom\" volumes can be attached to containers"
 msgstr  ""
 
+#: lxc/storage_volume.go:1471
+msgid   "Only \"custom\" volumes can be snapshotted"
+msgstr  ""
+
 #: lxc/remote.go:149
 msgid   "Only https URLs are supported for simplestreams"
 msgstr  ""
@@ -1639,7 +1643,7 @@ msgstr  ""
 msgid   "Pid: %d"
 msgstr  ""
 
-#: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299 lxc/storage_volume.go:809
+#: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299 lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid   "Press enter to open the editor again"
 msgstr  ""
 
@@ -1855,11 +1859,11 @@ msgstr  ""
 msgid   "Rename remotes"
 msgstr  ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid   "Rename storage volumes"
 msgstr  ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid   "Renamed storage volume from \"%s\" to \"%s\""
 msgstr  ""
@@ -1978,7 +1982,7 @@ msgstr  ""
 msgid   "Set storage pool configuration keys"
 msgstr  ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid   "Set storage volume configuration keys"
 msgstr  ""
 
@@ -2058,11 +2062,11 @@ msgstr  ""
 msgid   "Show storage pool configurations and resources"
 msgstr  ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid   "Show storage volum configurations"
 msgstr  ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid   "Show storage volume configurations"
 msgstr  ""
 
@@ -2103,6 +2107,10 @@ msgstr  ""
 msgid   "Size: %.2fMB"
 msgstr  ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid   "Snapshot storage volumes"
+msgstr  ""
+
 #: lxc/info.go:248
 msgid   "Snapshots:"
 msgstr  ""
@@ -2171,21 +2179,21 @@ msgstr  ""
 msgid   "Storage pool name"
 msgstr  ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid   "Storage volume %s created"
 msgstr  ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid   "Storage volume %s deleted"
 msgstr  ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid   "Storage volume copied successfully!"
 msgstr  ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid   "Storage volume moved successfully!"
 msgstr  ""
 
@@ -2209,7 +2217,7 @@ msgstr  ""
 msgid   "TARGET"
 msgstr  ""
 
-#: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152 lxc/storage_volume.go:951
+#: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152 lxc/storage_volume.go:1071
 msgid   "TYPE"
 msgstr  ""
 
@@ -2263,7 +2271,7 @@ msgstr  ""
 msgid   "The source LXD instance is not clustered"
 msgstr  ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605 lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626 lxc/storage_volume.go:707
 msgid   "The specified device doesn't exist"
 msgstr  ""
 
@@ -2303,7 +2311,7 @@ msgstr  ""
 msgid   "To use --target, the destination remote must be a cluster"
 msgstr  ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid   "Transfer mode, one of pull (default), push or relay"
 msgstr  ""
 
@@ -2311,7 +2319,7 @@ msgstr  ""
 msgid   "Transfer mode. One of pull (default), push or relay"
 msgstr  ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid   "Transfer mode. One of pull (default), push or relay."
 msgstr  ""
 
@@ -2346,7 +2354,7 @@ msgstr  ""
 msgid   "URL"
 msgstr  ""
 
-#: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553 lxc/storage_volume.go:954
+#: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553 lxc/storage_volume.go:1074
 msgid   "USED BY"
 msgstr  ""
 
@@ -2389,7 +2397,7 @@ msgstr  ""
 msgid   "Unset storage pool configuration keys"
 msgstr  ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid   "Unset storage volume configuration keys"
 msgstr  ""
 
@@ -2478,11 +2486,11 @@ msgstr  ""
 msgid   "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr  ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid   "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr  ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid   "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr  ""
 
@@ -2502,7 +2510,7 @@ msgstr  ""
 msgid   "console [<remote>:]<container>"
 msgstr  ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid   "copy <pool>/<volume> <pool>/<volume>"
 msgstr  ""
 
@@ -2534,7 +2542,7 @@ msgstr  ""
 msgid   "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr  ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid   "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr  ""
 
@@ -2578,7 +2586,7 @@ msgstr  ""
 msgid   "delete [<remote>:]<pool>"
 msgstr  ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid   "delete [<remote>:]<pool> <volume>"
 msgstr  ""
 
@@ -2594,11 +2602,11 @@ msgstr  ""
 msgid   "detach [<remote>:]<network> <container> [<device name>]"
 msgstr  ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid   "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr  ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid   "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr  ""
 
@@ -2646,7 +2654,7 @@ msgstr  ""
 msgid   "edit [<remote>:]<pool>"
 msgstr  ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid   "edit [<remote>:]<pool> <volume>"
 msgstr  ""
 
@@ -2699,7 +2707,7 @@ msgstr  ""
 msgid   "get [<remote>:]<pool> <key>"
 msgstr  ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid   "get [<remote>:]<pool> <volume> <key>"
 msgstr  ""
 
@@ -2779,7 +2787,7 @@ msgstr  ""
 msgid   "list [<remote>:]<container|profile>"
 msgstr  ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid   "list [<remote>:]<pool>"
 msgstr  ""
 
@@ -2942,12 +2950,12 @@ msgid   "lxc storage edit [<remote>:]<pool> < pool.yaml\n"
         "    Update a storage pool using the content of pool.yaml."
 msgstr  ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid   "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
         "    Update a storage volume using the content of pool.yaml."
 msgstr  ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid   "lxc storage volume show default data\n"
         "    Will show the properties of a custom volume called \"data\" in the \"default\" pool.\n"
         "\n"
@@ -2967,7 +2975,7 @@ msgstr  ""
 msgid   "monitor [<remote>:]"
 msgstr  ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid   "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr  ""
 
@@ -3083,7 +3091,7 @@ msgstr  ""
 msgid   "rename [<remote>:]<network> <new-name>"
 msgstr  ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid   "rename [<remote>:]<pool> <old name> <new name>"
 msgstr  ""
 
@@ -3111,7 +3119,7 @@ msgstr  ""
 msgid   "set [<remote>:]<pool> <key> <value>"
 msgstr  ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid   "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr  ""
 
@@ -3159,7 +3167,7 @@ msgstr  ""
 msgid   "show [<remote>:]<pool>"
 msgstr  ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid   "show [<remote>:]<pool> <volume>"
 msgstr  ""
 
@@ -3175,6 +3183,10 @@ msgstr  ""
 msgid   "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr  ""
 
+#: lxc/storage_volume.go:1438
+msgid   "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr  ""
+
 #: lxc/storage.go:433
 msgid   "space used"
 msgstr  ""
@@ -3236,7 +3248,7 @@ msgstr  ""
 msgid   "unset [<remote>:]<pool> <key>"
 msgstr  ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid   "unset [<remote>:]<pool> <volume> <key>"
 msgstr  ""
 
diff --git a/po/nb_NO.po b/po/nb_NO.po
index b4c6a6ebbb..19784c9ba2 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/nl.po b/po/nl.po
index e9fdaa3aa0..32ab79fede 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/pa.po b/po/pa.po
index 3b91e121a1..616eaf4876 100644
--- a/po/pa.po
+++ b/po/pa.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/pl.po b/po/pl.po
index 41589843e8..2a59ea21fc 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 47fc1906ce..78b97acd09 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-08-06 22:13+0000\n"
 "Last-Translator: Renato dos Santos <shazaum at gmail.com>\n"
 "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
@@ -50,7 +50,7 @@ msgstr ""
 "###   source: /home/chb/mnt/lxd_test/default.img\n"
 "###   zfs.pool_name: default"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -287,11 +287,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -327,7 +327,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -396,7 +396,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -443,12 +443,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -482,7 +482,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -537,7 +537,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -550,7 +550,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -591,7 +591,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -630,7 +630,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -678,7 +678,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -719,14 +719,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -738,11 +739,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -822,7 +823,7 @@ msgstr "Editar configurações de perfil como YAML"
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1024,7 +1025,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1200,7 +1201,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1360,7 +1361,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1561,13 +1562,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1580,7 +1581,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1599,8 +1600,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1612,7 +1613,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1620,7 +1621,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1634,7 +1635,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1691,15 +1692,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1708,10 +1709,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1775,7 +1780,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1993,11 +1998,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2118,7 +2123,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2198,11 +2203,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2243,6 +2248,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2311,21 +2320,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2350,7 +2359,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2407,8 +2416,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2448,7 +2457,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2456,7 +2465,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2492,7 +2501,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2535,7 +2544,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2629,11 +2638,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2656,7 +2665,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2688,7 +2697,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2734,7 +2743,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2750,11 +2759,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2802,7 +2811,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2857,7 +2866,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2940,7 +2949,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3132,13 +3141,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3161,7 +3170,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3313,7 +3322,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3361,7 +3370,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3377,6 +3386,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3438,7 +3451,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/ru.po b/po/ru.po
index f0d5ca97a0..a175cf2663 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: 2018-06-22 15:57+0000\n"
 "Last-Translator: Александр Киль <shorrey at gmail.com>\n"
 "Language-Team: Russian <https://hosted.weblate.org/projects/linux-containers/"
@@ -51,7 +51,7 @@ msgstr ""
 "###   source: /home/chb/mnt/lxd_test/default.img\n"
 "###   zfs.pool_name: default"
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -353,11 +353,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -393,7 +393,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -464,7 +464,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr "Невозможно прочитать из стандартного ввода: %s"
@@ -511,12 +511,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -550,7 +550,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -605,7 +605,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 #, fuzzy
 msgid "Copy storage volumes"
 msgstr "Копирование образа: %s"
@@ -619,7 +619,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr "Копирование образа: %s"
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, fuzzy, c-format
 msgid "Copying the storage volume: %s"
 msgstr "Копирование образа: %s"
@@ -662,7 +662,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr "Невозможно добавить имя контейнера в список"
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 #, fuzzy
 msgid "Create new custom storage volumes"
 msgstr "Копирование образа: %s"
@@ -704,7 +704,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -754,7 +754,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 #, fuzzy
 msgid "Delete storage volumes"
 msgstr "Копирование образа: %s"
@@ -796,14 +796,15 @@ msgstr "Копирование образа: %s"
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -815,11 +816,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -901,7 +902,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -1106,7 +1107,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1285,7 +1286,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1447,7 +1448,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 #, fuzzy
 msgid "List storage volumes"
 msgstr "Копирование образа: %s"
@@ -1654,13 +1655,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1673,7 +1674,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 #, fuzzy
 msgid "Missing source volume name"
 msgstr "Копирование образа: %s"
@@ -1693,8 +1694,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1706,7 +1707,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 #, fuzzy
 msgid "Move storage volumes between pools"
 msgstr "Копирование образа: %s"
@@ -1715,7 +1716,7 @@ msgstr "Копирование образа: %s"
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, fuzzy, c-format
 msgid "Moving the storage volume: %s"
 msgstr "Копирование образа: %s"
@@ -1729,7 +1730,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1787,16 +1788,16 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 #, fuzzy
 msgid "No device found for this storage volume"
 msgstr "Копирование образа: %s"
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1805,10 +1806,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1872,7 +1877,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -2093,12 +2098,12 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 #, fuzzy
 msgid "Rename storage volumes"
 msgstr "Копирование образа: %s"
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2219,7 +2224,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2301,11 +2306,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2346,6 +2351,11 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+#, fuzzy
+msgid "Snapshot storage volumes"
+msgstr "Копирование образа: %s"
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2415,21 +2425,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2455,7 +2465,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2512,8 +2522,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2553,7 +2563,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2561,7 +2571,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2597,7 +2607,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2640,7 +2650,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2735,11 +2745,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2762,7 +2772,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2794,7 +2804,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2852,7 +2862,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2868,11 +2878,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2920,7 +2930,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2979,7 +2989,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -3062,7 +3072,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3254,13 +3264,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3283,7 +3293,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3431,7 +3441,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3463,7 +3473,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3511,7 +3521,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3527,6 +3537,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3596,7 +3610,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/sr.po b/po/sr.po
index 6f4d17987a..7add5bb0b5 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/sv.po b/po/sv.po
index ca94f41ce4..962018910e 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/tr.po b/po/tr.po
index eaf10173f5..bb737e3895 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/uk.po b/po/uk.po
index 4f280de8b4..5a1cc6f956 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/zh.po b/po/zh.po
index 6e9942b883..e5669edb62 100644
--- a/po/zh.po
+++ b/po/zh.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
diff --git a/po/zh_Hans.po b/po/zh_Hans.po
index 9333d4f3aa..4a51af0532 100644
--- a/po/zh_Hans.po
+++ b/po/zh_Hans.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: lxd\n"
 "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-08-14 12:00-0400\n"
+"POT-Creation-Date: 2018-08-15 12:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -33,7 +33,7 @@ msgid ""
 "###   zfs.pool_name: default"
 msgstr ""
 
-#: lxc/storage_volume.go:723
+#: lxc/storage_volume.go:744
 msgid ""
 "### This is a yaml representation of a storage volume.\n"
 "### Any line starting with a '# will be ignored.\n"
@@ -259,11 +259,11 @@ msgstr ""
 msgid "Attach new network interfaces to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:121 lxc/storage_volume.go:122
+#: lxc/storage_volume.go:125 lxc/storage_volume.go:126
 msgid "Attach new storage volumes to containers"
 msgstr ""
 
-#: lxc/storage_volume.go:200 lxc/storage_volume.go:201
+#: lxc/storage_volume.go:204 lxc/storage_volume.go:205
 msgid "Attach new storage volumes to profiles"
 msgstr ""
 
@@ -299,7 +299,7 @@ msgid "Bad key/value pair: %s"
 msgstr ""
 
 #: lxc/copy.go:113 lxc/init.go:119 lxc/publish.go:175 lxc/storage.go:123
-#: lxc/storage_volume.go:454
+#: lxc/storage_volume.go:458
 #, c-format
 msgid "Bad key=value pair: %s"
 msgstr ""
@@ -368,7 +368,7 @@ msgid "Can't pull a directory without --recursive"
 msgstr ""
 
 #: lxc/config.go:400 lxc/network.go:1075 lxc/profile.go:787 lxc/storage.go:617
-#: lxc/storage_volume.go:1126
+#: lxc/storage_volume.go:1282
 #, c-format
 msgid "Can't read from stdin: %s"
 msgstr ""
@@ -415,12 +415,12 @@ msgstr ""
 #: lxc/copy.go:49 lxc/init.go:48 lxc/move.go:57 lxc/network.go:259
 #: lxc/network.go:669 lxc/network.go:1029 lxc/network.go:1098
 #: lxc/network.go:1160 lxc/storage.go:92 lxc/storage.go:331 lxc/storage.go:576
-#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:287
-#: lxc/storage_volume.go:415 lxc/storage_volume.go:490
-#: lxc/storage_volume.go:716 lxc/storage_volume.go:842
-#: lxc/storage_volume.go:984 lxc/storage_volume.go:1014
-#: lxc/storage_volume.go:1078 lxc/storage_volume.go:1161
-#: lxc/storage_volume.go:1230
+#: lxc/storage.go:649 lxc/storage.go:732 lxc/storage_volume.go:291
+#: lxc/storage_volume.go:419 lxc/storage_volume.go:494
+#: lxc/storage_volume.go:737 lxc/storage_volume.go:938
+#: lxc/storage_volume.go:1104 lxc/storage_volume.go:1134
+#: lxc/storage_volume.go:1234 lxc/storage_volume.go:1317
+#: lxc/storage_volume.go:1410
 msgid "Cluster member name"
 msgstr ""
 
@@ -454,7 +454,7 @@ msgstr ""
 
 #: lxc/config.go:195 lxc/config.go:259 lxc/config_metadata.go:144
 #: lxc/image.go:405 lxc/network.go:637 lxc/profile.go:490 lxc/storage.go:298
-#: lxc/storage_volume.go:808
+#: lxc/storage_volume.go:874 lxc/storage_volume.go:904
 #, c-format
 msgid "Config parsing error: %s"
 msgstr ""
@@ -509,7 +509,7 @@ msgstr ""
 msgid "Copy profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:282 lxc/storage_volume.go:283
+#: lxc/storage_volume.go:286 lxc/storage_volume.go:287
 msgid "Copy storage volumes"
 msgstr ""
 
@@ -522,7 +522,7 @@ msgstr ""
 msgid "Copying the image: %s"
 msgstr ""
 
-#: lxc/storage_volume.go:347
+#: lxc/storage_volume.go:351
 #, c-format
 msgid "Copying the storage volume: %s"
 msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
 msgid "Create new container file templates"
 msgstr ""
 
-#: lxc/storage_volume.go:411 lxc/storage_volume.go:412
+#: lxc/storage_volume.go:415 lxc/storage_volume.go:416
 msgid "Create new custom storage volumes"
 msgstr ""
 
@@ -602,7 +602,7 @@ msgid "DATABASE"
 msgstr ""
 
 #: lxc/image.go:925 lxc/image_alias.go:230 lxc/list.go:457 lxc/network.go:856
-#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:953
+#: lxc/operation.go:153 lxc/storage.go:545 lxc/storage_volume.go:1073
 msgid "DESCRIPTION"
 msgstr ""
 
@@ -650,7 +650,7 @@ msgstr ""
 msgid "Delete storage pools"
 msgstr ""
 
-#: lxc/storage_volume.go:486 lxc/storage_volume.go:487
+#: lxc/storage_volume.go:490 lxc/storage_volume.go:491
 msgid "Delete storage volumes"
 msgstr ""
 
@@ -691,14 +691,15 @@ msgstr ""
 #: lxc/rename.go:21 lxc/restore.go:24 lxc/snapshot.go:21 lxc/storage.go:33
 #: lxc/storage.go:89 lxc/storage.go:161 lxc/storage.go:208 lxc/storage.go:328
 #: lxc/storage.go:383 lxc/storage.go:491 lxc/storage.go:573 lxc/storage.go:645
-#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:122
-#: lxc/storage_volume.go:201 lxc/storage_volume.go:283
-#: lxc/storage_volume.go:412 lxc/storage_volume.go:487
-#: lxc/storage_volume.go:547 lxc/storage_volume.go:629
-#: lxc/storage_volume.go:710 lxc/storage_volume.go:839
-#: lxc/storage_volume.go:904 lxc/storage_volume.go:980
-#: lxc/storage_volume.go:1011 lxc/storage_volume.go:1075
-#: lxc/storage_volume.go:1152 lxc/storage_volume.go:1227 lxc/version.go:22
+#: lxc/storage.go:729 lxc/storage_volume.go:34 lxc/storage_volume.go:126
+#: lxc/storage_volume.go:205 lxc/storage_volume.go:287
+#: lxc/storage_volume.go:416 lxc/storage_volume.go:491
+#: lxc/storage_volume.go:568 lxc/storage_volume.go:650
+#: lxc/storage_volume.go:731 lxc/storage_volume.go:935
+#: lxc/storage_volume.go:1024 lxc/storage_volume.go:1100
+#: lxc/storage_volume.go:1131 lxc/storage_volume.go:1231
+#: lxc/storage_volume.go:1308 lxc/storage_volume.go:1407
+#: lxc/storage_volume.go:1440 lxc/version.go:22
 msgid "Description"
 msgstr ""
 
@@ -710,11 +711,11 @@ msgstr ""
 msgid "Detach network interfaces from profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:546 lxc/storage_volume.go:547
+#: lxc/storage_volume.go:567 lxc/storage_volume.go:568
 msgid "Detach storage volumes from containers"
 msgstr ""
 
-#: lxc/storage_volume.go:628 lxc/storage_volume.go:629
+#: lxc/storage_volume.go:649 lxc/storage_volume.go:650
 msgid "Detach storage volumes from profiles"
 msgstr ""
 
@@ -794,7 +795,7 @@ msgstr ""
 msgid "Edit storage pool configurations as YAML"
 msgstr ""
 
-#: lxc/storage_volume.go:709 lxc/storage_volume.go:710
+#: lxc/storage_volume.go:730 lxc/storage_volume.go:731
 msgid "Edit storage volume configurations as YAML"
 msgstr ""
 
@@ -996,7 +997,7 @@ msgstr ""
 msgid "Get values for storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:838 lxc/storage_volume.go:839
+#: lxc/storage_volume.go:934 lxc/storage_volume.go:935
 msgid "Get values for storage volume configuration keys"
 msgstr ""
 
@@ -1172,7 +1173,7 @@ msgstr ""
 msgid "LAST USED AT"
 msgstr ""
 
-#: lxc/list.go:480 lxc/storage_volume.go:957
+#: lxc/list.go:480 lxc/storage_volume.go:1077
 msgid "LOCATION"
 msgstr ""
 
@@ -1332,7 +1333,7 @@ msgstr ""
 msgid "List profiles"
 msgstr ""
 
-#: lxc/storage_volume.go:903 lxc/storage_volume.go:904
+#: lxc/storage_volume.go:1023 lxc/storage_volume.go:1024
 msgid "List storage volumes"
 msgstr ""
 
@@ -1533,13 +1534,13 @@ msgid "Missing network name"
 msgstr ""
 
 #: lxc/storage.go:185 lxc/storage.go:252 lxc/storage.go:353 lxc/storage.go:408
-#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:146
-#: lxc/storage_volume.go:225 lxc/storage_volume.go:437
-#: lxc/storage_volume.go:512 lxc/storage_volume.go:571
-#: lxc/storage_volume.go:653 lxc/storage_volume.go:752
-#: lxc/storage_volume.go:864 lxc/storage_volume.go:928
-#: lxc/storage_volume.go:1036 lxc/storage_volume.go:1100
-#: lxc/storage_volume.go:1183
+#: lxc/storage.go:603 lxc/storage.go:677 lxc/storage_volume.go:150
+#: lxc/storage_volume.go:229 lxc/storage_volume.go:441
+#: lxc/storage_volume.go:516 lxc/storage_volume.go:592
+#: lxc/storage_volume.go:674 lxc/storage_volume.go:773
+#: lxc/storage_volume.go:960 lxc/storage_volume.go:1048
+#: lxc/storage_volume.go:1156 lxc/storage_volume.go:1256
+#: lxc/storage_volume.go:1339 lxc/storage_volume.go:1463
 msgid "Missing pool name"
 msgstr ""
 
@@ -1552,7 +1553,7 @@ msgstr ""
 msgid "Missing source profile name"
 msgstr ""
 
-#: lxc/storage_volume.go:309
+#: lxc/storage_volume.go:313
 msgid "Missing source volume name"
 msgstr ""
 
@@ -1571,8 +1572,8 @@ msgid ""
 "By default the monitor will listen to all message types."
 msgstr ""
 
-#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:591
-#: lxc/storage_volume.go:672
+#: lxc/network.go:417 lxc/network.go:502 lxc/storage_volume.go:612
+#: lxc/storage_volume.go:693
 msgid "More than one device matches, specify the device name"
 msgstr ""
 
@@ -1584,7 +1585,7 @@ msgstr ""
 msgid "Move containers within or in between LXD instances"
 msgstr ""
 
-#: lxc/storage_volume.go:979 lxc/storage_volume.go:980
+#: lxc/storage_volume.go:1099 lxc/storage_volume.go:1100
 msgid "Move storage volumes between pools"
 msgstr ""
 
@@ -1592,7 +1593,7 @@ msgstr ""
 msgid "Move the container without its snapshots"
 msgstr ""
 
-#: lxc/storage_volume.go:351
+#: lxc/storage_volume.go:355
 #, c-format
 msgid "Moving the storage volume: %s"
 msgstr ""
@@ -1606,7 +1607,7 @@ msgid "Must supply container name for: "
 msgstr ""
 
 #: lxc/cluster.go:124 lxc/list.go:459 lxc/network.go:853 lxc/profile.go:613
-#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:952
+#: lxc/remote.go:465 lxc/storage.go:544 lxc/storage_volume.go:1072
 msgid "NAME"
 msgstr ""
 
@@ -1663,15 +1664,15 @@ msgstr ""
 msgid "No device found for this network"
 msgstr ""
 
-#: lxc/storage_volume.go:600 lxc/storage_volume.go:681
+#: lxc/storage_volume.go:621 lxc/storage_volume.go:702
 msgid "No device found for this storage volume"
 msgstr ""
 
-#: lxc/storage_volume.go:323
+#: lxc/storage_volume.go:327
 msgid "No storage pool for source volume specified"
 msgstr ""
 
-#: lxc/storage_volume.go:335
+#: lxc/storage_volume.go:339
 msgid "No storage pool for target volume specified"
 msgstr ""
 
@@ -1680,10 +1681,14 @@ msgstr ""
 msgid "No value found in %q"
 msgstr ""
 
-#: lxc/storage_volume.go:164 lxc/storage_volume.go:243
+#: lxc/storage_volume.go:168 lxc/storage_volume.go:247
 msgid "Only \"custom\" volumes can be attached to containers"
 msgstr ""
 
+#: lxc/storage_volume.go:1471
+msgid "Only \"custom\" volumes can be snapshotted"
+msgstr ""
+
 #: lxc/remote.go:149
 msgid "Only https URLs are supported for simplestreams"
 msgstr ""
@@ -1747,7 +1752,7 @@ msgid "Pid: %d"
 msgstr ""
 
 #: lxc/network.go:638 lxc/profile.go:491 lxc/storage.go:299
-#: lxc/storage_volume.go:809
+#: lxc/storage_volume.go:875 lxc/storage_volume.go:905
 msgid "Press enter to open the editor again"
 msgstr ""
 
@@ -1965,11 +1970,11 @@ msgstr ""
 msgid "Rename remotes"
 msgstr ""
 
-#: lxc/storage_volume.go:1010 lxc/storage_volume.go:1011
+#: lxc/storage_volume.go:1130 lxc/storage_volume.go:1131
 msgid "Rename storage volumes"
 msgstr ""
 
-#: lxc/storage_volume.go:1059
+#: lxc/storage_volume.go:1197 lxc/storage_volume.go:1216
 #, c-format
 msgid "Renamed storage volume from \"%s\" to \"%s\""
 msgstr ""
@@ -2090,7 +2095,7 @@ msgstr ""
 msgid "Set storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1074 lxc/storage_volume.go:1075
+#: lxc/storage_volume.go:1230 lxc/storage_volume.go:1231
 msgid "Set storage volume configuration keys"
 msgstr ""
 
@@ -2170,11 +2175,11 @@ msgstr ""
 msgid "Show storage pool configurations and resources"
 msgstr ""
 
-#: lxc/storage_volume.go:1151
+#: lxc/storage_volume.go:1307
 msgid "Show storage volum configurations"
 msgstr ""
 
-#: lxc/storage_volume.go:1152
+#: lxc/storage_volume.go:1308
 msgid "Show storage volume configurations"
 msgstr ""
 
@@ -2215,6 +2220,10 @@ msgstr ""
 msgid "Size: %.2fMB"
 msgstr ""
 
+#: lxc/storage_volume.go:1439 lxc/storage_volume.go:1440
+msgid "Snapshot storage volumes"
+msgstr ""
+
 #: lxc/info.go:248
 msgid "Snapshots:"
 msgstr ""
@@ -2283,21 +2292,21 @@ msgstr ""
 msgid "Storage pool name"
 msgstr ""
 
-#: lxc/storage_volume.go:470
+#: lxc/storage_volume.go:474
 #, c-format
 msgid "Storage volume %s created"
 msgstr ""
 
-#: lxc/storage_volume.go:531
+#: lxc/storage_volume.go:552
 #, c-format
 msgid "Storage volume %s deleted"
 msgstr ""
 
-#: lxc/storage_volume.go:348
+#: lxc/storage_volume.go:352
 msgid "Storage volume copied successfully!"
 msgstr ""
 
-#: lxc/storage_volume.go:352
+#: lxc/storage_volume.go:356
 msgid "Storage volume moved successfully!"
 msgstr ""
 
@@ -2322,7 +2331,7 @@ msgid "TARGET"
 msgstr ""
 
 #: lxc/list.go:465 lxc/network.go:854 lxc/network.go:960 lxc/operation.go:152
-#: lxc/storage_volume.go:951
+#: lxc/storage_volume.go:1071
 msgid "TYPE"
 msgstr ""
 
@@ -2379,8 +2388,8 @@ msgstr ""
 msgid "The source LXD instance is not clustered"
 msgstr ""
 
-#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:605
-#: lxc/storage_volume.go:686
+#: lxc/network.go:431 lxc/network.go:516 lxc/storage_volume.go:626
+#: lxc/storage_volume.go:707
 msgid "The specified device doesn't exist"
 msgstr ""
 
@@ -2420,7 +2429,7 @@ msgstr ""
 msgid "To use --target, the destination remote must be a cluster"
 msgstr ""
 
-#: lxc/storage_volume.go:983
+#: lxc/storage_volume.go:1103
 msgid "Transfer mode, one of pull (default), push or relay"
 msgstr ""
 
@@ -2428,7 +2437,7 @@ msgstr ""
 msgid "Transfer mode. One of pull (default), push or relay"
 msgstr ""
 
-#: lxc/move.go:54 lxc/storage_volume.go:286
+#: lxc/move.go:54 lxc/storage_volume.go:290
 msgid "Transfer mode. One of pull (default), push or relay."
 msgstr ""
 
@@ -2464,7 +2473,7 @@ msgid "URL"
 msgstr ""
 
 #: lxc/network.go:857 lxc/profile.go:614 lxc/storage.go:553
-#: lxc/storage_volume.go:954
+#: lxc/storage_volume.go:1074
 msgid "USED BY"
 msgstr ""
 
@@ -2507,7 +2516,7 @@ msgstr ""
 msgid "Unset storage pool configuration keys"
 msgstr ""
 
-#: lxc/storage_volume.go:1226 lxc/storage_volume.go:1227
+#: lxc/storage_volume.go:1406 lxc/storage_volume.go:1407
 msgid "Unset storage volume configuration keys"
 msgstr ""
 
@@ -2601,11 +2610,11 @@ msgid ""
 "attach [<remote>:]<network> <container> [<device name>] [<interface name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:120
+#: lxc/storage_volume.go:124
 msgid "attach [<remote>:]<pool> <volume> <container> [<device name>] <path>"
 msgstr ""
 
-#: lxc/storage_volume.go:199
+#: lxc/storage_volume.go:203
 msgid ""
 "attach-profile [<remote:>]<pool> <volume> <profile> [<device name>] <path>"
 msgstr ""
@@ -2628,7 +2637,7 @@ msgstr ""
 msgid "console [<remote>:]<container>"
 msgstr ""
 
-#: lxc/storage_volume.go:280
+#: lxc/storage_volume.go:284
 msgid "copy <pool>/<volume> <pool>/<volume>"
 msgstr ""
 
@@ -2660,7 +2669,7 @@ msgstr ""
 msgid "create [<remote>:]<pool> <driver> [key=value...]"
 msgstr ""
 
-#: lxc/storage_volume.go:410
+#: lxc/storage_volume.go:414
 msgid "create [<remote>:]<pool> <volume> [key=value...]"
 msgstr ""
 
@@ -2706,7 +2715,7 @@ msgstr ""
 msgid "delete [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:484
+#: lxc/storage_volume.go:488
 msgid "delete [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2722,11 +2731,11 @@ msgstr ""
 msgid "detach [<remote>:]<network> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:545
+#: lxc/storage_volume.go:566
 msgid "detach [<remote>:]<pool> <volume> <container> [<device name>]"
 msgstr ""
 
-#: lxc/storage_volume.go:627
+#: lxc/storage_volume.go:648
 msgid "detach-profile [<remote:>]<pool> <volume> <profile> [<device name>]"
 msgstr ""
 
@@ -2774,7 +2783,7 @@ msgstr ""
 msgid "edit [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:708
+#: lxc/storage_volume.go:729
 msgid "edit [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -2829,7 +2838,7 @@ msgstr ""
 msgid "get [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:837
+#: lxc/storage_volume.go:933
 msgid "get [<remote>:]<pool> <volume> <key>"
 msgstr ""
 
@@ -2912,7 +2921,7 @@ msgstr ""
 msgid "list [<remote>:]<container|profile>"
 msgstr ""
 
-#: lxc/storage_volume.go:901
+#: lxc/storage_volume.go:1021
 msgid "list [<remote>:]<pool>"
 msgstr ""
 
@@ -3104,13 +3113,13 @@ msgid ""
 "    Update a storage pool using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:712
+#: lxc/storage_volume.go:733
 msgid ""
 "lxc storage volume edit [<remote>:]<pool> <volume> < volume.yaml\n"
 "    Update a storage volume using the content of pool.yaml."
 msgstr ""
 
-#: lxc/storage_volume.go:1154
+#: lxc/storage_volume.go:1310
 msgid ""
 "lxc storage volume show default data\n"
 "    Will show the properties of a custom volume called \"data\" in the "
@@ -3133,7 +3142,7 @@ msgstr ""
 msgid "monitor [<remote>:]"
 msgstr ""
 
-#: lxc/storage_volume.go:977
+#: lxc/storage_volume.go:1097
 msgid "move [<pool>/]<volume> [<pool>/]<volume>"
 msgstr ""
 
@@ -3257,7 +3266,7 @@ msgstr ""
 msgid "rename [<remote>:]<network> <new-name>"
 msgstr ""
 
-#: lxc/storage_volume.go:1009
+#: lxc/storage_volume.go:1129
 msgid "rename [<remote>:]<pool> <old name> <new name>"
 msgstr ""
 
@@ -3285,7 +3294,7 @@ msgstr ""
 msgid "set [<remote>:]<pool> <key> <value>"
 msgstr ""
 
-#: lxc/storage_volume.go:1073
+#: lxc/storage_volume.go:1229
 msgid "set [<remote>:]<pool> <volume> <key> <value>"
 msgstr ""
 
@@ -3333,7 +3342,7 @@ msgstr ""
 msgid "show [<remote>:]<pool>"
 msgstr ""
 
-#: lxc/storage_volume.go:1150
+#: lxc/storage_volume.go:1306
 msgid "show [<remote>:]<pool> <volume>"
 msgstr ""
 
@@ -3349,6 +3358,10 @@ msgstr ""
 msgid "snapshot [<remote>:]<container> [<snapshot name>]"
 msgstr ""
 
+#: lxc/storage_volume.go:1438
+msgid "snapshot [<remote>:]<pool> <volume> [<snapshot name>]"
+msgstr ""
+
 #: lxc/storage.go:433
 msgid "space used"
 msgstr ""
@@ -3410,7 +3423,7 @@ msgstr ""
 msgid "unset [<remote>:]<pool> <key>"
 msgstr ""
 
-#: lxc/storage_volume.go:1225
+#: lxc/storage_volume.go:1405
 msgid "unset [<remote>:]<pool> <volume> <key>"
 msgstr ""
 

From b762a03183e3e0f603e6c788776686d249c04cfe Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 15 Aug 2018 12:55:58 +0200
Subject: [PATCH 70/81] api: add Restore field to StorageVolumeSnapshotPut
 struct

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/api/storage_pool_volume_snapshot.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/shared/api/storage_pool_volume_snapshot.go b/shared/api/storage_pool_volume_snapshot.go
index 4ba21da05d..f833675446 100644
--- a/shared/api/storage_pool_volume_snapshot.go
+++ b/shared/api/storage_pool_volume_snapshot.go
@@ -27,5 +27,7 @@ type StorageVolumeSnapshot struct {
 //
 // API extension: storage_api_volume_snapshots
 type StorageVolumeSnapshotPut struct {
+	Restore string `json:"restore,omitempty" yaml:"restore,omitempty"`
+
 	Description string `json:"description" yaml:"description"`
 }

From f54d78739d89efa3aab5cedf7b21fc5139f7fdd3 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 22 Aug 2018 22:13:18 +0200
Subject: [PATCH 71/81] storage: Delete storage volume snapshots

When deleting a storage volume, delete the volume snapshots as well.

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_volumes.go | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 400705b150..3f208d695e 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -895,6 +895,26 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
 		return SmartError(err)
 	}
 
+	// Delete storage volume snapshots
+	if volumeType == storagePoolVolumeTypeCustom {
+		snapshots, err := d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName, volumeType, poolID)
+		if err != nil {
+			return SmartError(err)
+		}
+
+		for _, snapshot := range snapshots {
+			s, err := storagePoolVolumeInit(d.State(), poolName, snapshot, volumeType)
+			if err != nil {
+				return NotFound(err)
+			}
+
+			err = s.StoragePoolVolumeSnapshotDelete()
+			if err != nil {
+				return SmartError(err)
+			}
+		}
+	}
+
 	return EmptySyncResponse
 }
 

From 842a144b39c2207f973a2e3f7c0a014615d6f1e3 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 22 Aug 2018 22:14:18 +0200
Subject: [PATCH 72/81] storage: Copy storage volume snapshots

When copying a storage volume, copy the volume snapshots as well.

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_volumes.go       | 30 +++++++++++++++++++++
 lxd/storage_volumes_utils.go | 51 ++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 3f208d695e..c5faf97a2d 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -229,6 +229,36 @@ func doVolumeCreateOrCopy(d *Daemon, poolName string, req *api.StorageVolumesPos
 		if err != nil {
 			return err
 		}
+
+		// Convert the volume type name to our internal integer representation.
+		volumeType, err := storagePoolVolumeTypeNameToType(req.Type)
+		if err != nil {
+			return err
+		}
+
+		// Get poolID of source pool
+		poolID, err := d.cluster.StoragePoolGetID(req.Source.Pool)
+		if err != nil {
+			return err
+		}
+
+		// Get volumes attached to source storage volume
+		volumes, err := d.cluster.StoragePoolVolumeSnapshotsGetType(req.Source.Name, volumeType, poolID)
+		for _, vol := range volumes {
+			_, snapshotName, _ := containerGetParentAndSnapshotName(vol)
+
+			copyReq := api.StorageVolumesPost{}
+			copyReq.Name = fmt.Sprintf("%s%s%s", req.Name, shared.SnapshotDelimiter, snapshotName)
+			copyReq.Type = "custom"
+			copyReq.Source.Name = fmt.Sprintf("%s%s%s", req.Source.Name, shared.SnapshotDelimiter, snapshotName)
+			copyReq.Source.Pool = req.Source.Pool
+
+			err = storagePoolVolumeSnapshotCreateInternal(d.State(), poolName, &copyReq)
+			if err != nil {
+				return err
+			}
+		}
+
 		return nil
 	}
 
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index f8965decdd..c54eee5fbc 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -593,6 +593,57 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
 	return nil
 }
 
+func storagePoolVolumeSnapshotCreateInternal(state *state.State, poolName string, vol *api.StorageVolumesPost) error {
+	// Get poolID of source pool
+	poolID, err := state.Cluster.StoragePoolGetID(vol.Source.Pool)
+	if err != nil {
+		return err
+	}
+
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := storagePoolVolumeTypeNameToType(vol.Type)
+	if err != nil {
+		return err
+	}
+
+	_, snapshot, err := state.Cluster.StoragePoolNodeVolumeGetType(vol.Source.Name, volumeType, poolID)
+	if err != nil {
+		return err
+	}
+
+	writable := snapshot.Writable()
+
+	dbArgs := &db.StorageVolumeArgs{
+		Name:        vol.Name,
+		PoolName:    poolName,
+		TypeName:    vol.Type,
+		Kind:        db.StorageVolumeKindSnapshot,
+		Config:      writable.Config,
+		Description: writable.Description,
+	}
+
+	s, err := storagePoolVolumeSnapshotDBCreateInternal(state, dbArgs)
+	if err != nil {
+		return err
+	}
+
+	if vol.Source.Name == "" {
+		err = s.StoragePoolVolumeCreate()
+	} else {
+		err = s.StoragePoolVolumeCopy(&vol.Source)
+	}
+	if err != nil {
+		poolID, _, _ := s.GetContainerPoolInfo()
+		volumeType, err := storagePoolVolumeTypeNameToType(vol.Type)
+		if err == nil {
+			state.Cluster.StoragePoolVolumeDelete(vol.Name, volumeType, poolID)
+		}
+		return err
+	}
+
+	return nil
+}
+
 func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.StorageVolumeArgs) (storage, error) {
 	// Create database entry for new storage volume.
 	err := storagePoolVolumeDBCreate(state, dbArgs.PoolName, dbArgs.Name, dbArgs.Description, dbArgs.TypeName, db.StorageVolumeKindSnapshot, dbArgs.Config)

From c73aab0ebfa56fba6b613f4ccf20c5230fcd9171 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 22 Aug 2018 22:15:11 +0200
Subject: [PATCH 73/81] storage/dir: Handle copying volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_dir.go | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 2710f80ef1..54274d4cc6 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -333,7 +333,16 @@ func (s *storageDir) StoragePoolVolumeCreate() error {
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
+	var storageVolumePath string
+
+	if isSnapshot {
+		storageVolumePath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		storageVolumePath = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
+
 	err = os.MkdirAll(storageVolumePath, 0711)
 	if err != nil {
 		return err
@@ -1246,8 +1255,17 @@ func (s *storageDir) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 		return err
 	}
 
-	srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	var srcMountPoint string
+	var dstMountPoint string
+
+	if strings.Contains(source.Name, "/") {
+		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		srcMountPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
+
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	_, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
 	if err != nil {

From 065621d3b816f77983bf09184789ad8ddb83f60c Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 22 Aug 2018 22:16:06 +0200
Subject: [PATCH 74/81] storage/btrfs: Handle copying volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_btrfs.go | 45 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 5d921dd230..ae131a624b 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -552,8 +552,17 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 		return err
 	}
 
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
 	// Create subvolume path on the storage pool.
-	customSubvolumePath := s.getCustomSubvolumePath(s.pool.Name)
+	var customSubvolumePath string
+
+	if isSnapshot {
+		customSubvolumePath = s.getCustomSnapshotSubvolumePath(s.pool.Name)
+	} else {
+		customSubvolumePath = s.getCustomSubvolumePath(s.pool.Name)
+	}
+
 	if !shared.PathExists(customSubvolumePath) {
 		err := os.MkdirAll(customSubvolumePath, 0700)
 		if err != nil {
@@ -562,7 +571,14 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 	}
 
 	// Create subvolume.
-	customSubvolumeName := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	var customSubvolumeName string
+
+	if isSnapshot {
+		customSubvolumeName = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		customSubvolumeName = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
+
 	err = btrfsSubVolumeCreate(customSubvolumeName)
 	if err != nil {
 		return err
@@ -2784,12 +2800,29 @@ func (s *storageBtrfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) er
 	logger.Infof("Copying BTRFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 	successMsg := fmt.Sprintf("Copied BTRFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 
-	srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	isSnapshot := strings.Contains(source.Name, "/")
+
+	var srcMountPoint string
+	var dstMountPoint string
+
+	if isSnapshot {
+		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		srcMountPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
 
 	if s.pool.Name == source.Pool {
+		var customDir string
+
 		// Ensure that the directories immediately preceding the subvolume directory exist.
-		customDir := getStoragePoolVolumeMountPoint(s.pool.Name, "")
+		if isSnapshot {
+			customDir = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, "")
+		} else {
+			customDir = getStoragePoolVolumeMountPoint(s.pool.Name, "")
+		}
+
 		if !shared.PathExists(customDir) {
 			err := os.MkdirAll(customDir, customDirMode)
 			if err != nil {
@@ -2811,7 +2844,7 @@ func (s *storageBtrfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) er
 	// setup storage for the source volume
 	srcStorage, err := storagePoolVolumeInit(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
-		logger.Errorf("Failed to initialize storage for BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+		logger.Errorf("Failed to initialize storage for BTRFS storage volume \"%s\" on storage pool \"%s\": %s", source.Name, source.Pool, err)
 		return err
 	}
 

From 8b69bd4372339ab8700e319990de15325a3928ee Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Wed, 22 Aug 2018 22:16:17 +0200
Subject: [PATCH 75/81] storage/zfs: Handle copying volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_zfs.go | 45 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index afdaf86001..9f514d425a 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -387,10 +387,25 @@ func (s *storageZfs) StoragePoolUmount() (bool, error) {
 func (s *storageZfs) StoragePoolVolumeCreate() error {
 	logger.Infof("Creating ZFS storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	fs := fmt.Sprintf("custom/%s", s.volume.Name)
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
+	var fs string
+
+	if isSnapshot {
+		fs = fmt.Sprintf("custom-snapshots/%s", s.volume.Name)
+	} else {
+		fs = fmt.Sprintf("custom/%s", s.volume.Name)
+	}
 	poolName := s.getOnDiskPoolName()
 	dataset := fmt.Sprintf("%s/%s", poolName, fs)
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+
+	var customPoolVolumeMntPoint string
+
+	if isSnapshot {
+		customPoolVolumeMntPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		customPoolVolumeMntPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
 
 	msg, err := zfsPoolVolumeCreate(dataset, "mountpoint=none", "canmount=noauto")
 	if err != nil {
@@ -2842,8 +2857,18 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 	logger.Infof("Copying ZFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 	successMsg := fmt.Sprintf("Copied ZFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 
-	srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	isSnapshot := strings.Contains(source.Name, "/")
+
+	var srcMountPoint string
+	var dstMountPoint string
+
+	if isSnapshot {
+		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		srcMountPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
 
 	if s.pool.Name == source.Pool && (s.pool.Config["zfs.clone_copy"] == "" || shared.IsTrue(s.pool.Config["zfs.clone_copy"])) {
 		poolName := s.getOnDiskPoolName()
@@ -2856,8 +2881,16 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 			return err
 		}
 
-		srcDataset := fmt.Sprintf("custom/%s", source.Name)
-		dstDataset := fmt.Sprintf("custom/%s", s.volume.Name)
+		var srcDataset string
+		var dstDataset string
+
+		if isSnapshot {
+			srcDataset = fmt.Sprintf("custom-snapshots/%s", source.Name)
+			dstDataset = fmt.Sprintf("custom-snapshots/%s", s.volume.Name)
+		} else {
+			srcDataset = fmt.Sprintf("custom/%s", source.Name)
+			dstDataset = fmt.Sprintf("custom/%s", s.volume.Name)
+		}
 
 		// clone snapshot
 		err = zfsPoolVolumeClone(poolName, srcDataset, snapUUID, dstDataset, dstMountPoint)

From 5d7c22e3f82178f5e7a302aac00c6a43c1aadaee Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 15:45:45 +0200
Subject: [PATCH 76/81] storage/ceph: Handle copying volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_ceph.go | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 82a9fec00e..2e873878d3 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2496,11 +2496,33 @@ func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) err
 	logger.Infof("Copying RBD storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 	successMsg := fmt.Sprintf("Copied RBD storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
 
-	srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
+	var srcMountPoint string
+	var dstMountPoint string
+
+	if isSnapshot {
+		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	} else {
+		srcMountPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	}
+
 	if s.pool.Name == source.Pool {
-		oldVolumeName := fmt.Sprintf("%s/custom_%s", s.OSDPoolName, source.Name)
-		newVolumeName := fmt.Sprintf("%s/custom_%s", s.OSDPoolName, s.volume.Name)
+		var oldVolumeName string
+		var newVolumeName string
+
+		if isSnapshot {
+			_, srcSnapshotOnlyName, _ := containerGetParentAndSnapshotName(source.Name)
+			_, dstSnapshotOnlyName, _ := containerGetParentAndSnapshotName(s.volume.Name)
+
+			oldVolumeName = fmt.Sprintf("%s/snapshot_%s", s.OSDPoolName, srcSnapshotOnlyName)
+			newVolumeName = fmt.Sprintf("%s/snapshot_%s", s.OSDPoolName, dstSnapshotOnlyName)
+		} else {
+			oldVolumeName = fmt.Sprintf("%s/custom_%s", s.OSDPoolName, source.Name)
+			newVolumeName = fmt.Sprintf("%s/custom_%s", s.OSDPoolName, s.volume.Name)
+		}
 
 		if s.pool.Config["ceph.rbd.clone_copy"] != "" && !shared.IsTrue(s.pool.Config["ceph.rbd.clone_copy"]) {
 			// create full copy
@@ -2549,7 +2571,13 @@ func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) err
 			return err
 		}
 
-		volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		var volumeMntPoint string
+
+		if isSnapshot {
+			volumeMntPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		} else {
+			volumeMntPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		}
 		err = os.MkdirAll(volumeMntPoint, 0711)
 		if err != nil {
 			logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)

From a9ac83fee6c5679a16935507d8eaa64f1f2bfacf Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 11:01:54 +0200
Subject: [PATCH 77/81] storage: Rename storage volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_volumes.go | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index c5faf97a2d..22a13acd72 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -556,6 +556,7 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string
 				storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
 				return err
 			}
+
 		} else {
 			moveReq := api.StorageVolumesPost{}
 			moveReq.Name = req.Name
@@ -571,6 +572,41 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string
 			if err != nil {
 				return err
 			}
+
+			// Rename volume snapshots
+			// Get volumes attached to source storage volume
+			volumes, err := d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName,
+				storagePoolVolumeTypeCustom, poolID)
+			if err != nil {
+				return err
+			}
+
+			for _, vol := range volumes {
+				// Rename volume snapshots
+				snapshot, err := storagePoolVolumeInit(d.State(), poolName,
+					vol, storagePoolVolumeTypeCustom)
+				if err != nil {
+					return err
+				}
+
+				dstVolumeName, dstSnapshotName, _ := containerGetParentAndSnapshotName(req.Name)
+
+				moveReq := api.StorageVolumesPost{}
+				moveReq.Name = fmt.Sprintf("%s%s%s", dstVolumeName, shared.SnapshotDelimiter, dstSnapshotName)
+				moveReq.Type = "custom"
+				moveReq.Source.Name = vol
+				moveReq.Source.Pool = poolName
+
+				err = storagePoolVolumeSnapshotCreateInternal(d.State(), req.Pool, &moveReq)
+				if err != nil {
+					return err
+				}
+
+				err = snapshot.StoragePoolVolumeSnapshotDelete()
+				if err != nil {
+					return err
+				}
+			}
 		}
 
 		return nil

From ab4ddc1c3782328d3e4cd8189d9a7dcc1dfbc5ac Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 11:05:40 +0200
Subject: [PATCH 78/81] storage/dir: Handle renaming volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_dir.go | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 54274d4cc6..40fa053ff9 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1369,15 +1369,30 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 
 func (s *storageDir) StoragePoolVolumeSnapshotRename(newName string) error {
 	logger.Infof("Renaming DIR storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+	var fullSnapshotName string
 
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
-	if !ok {
-		return fmt.Errorf("Not a snapshot name")
+	if strings.Contains(newName, "/") {
+		// When renaming volume snapshots, newName will contain the full snapshot name
+		fullSnapshotName = newName
+	} else {
+		sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+		if !ok {
+			return fmt.Errorf("Not a snapshot name")
+		}
+
+		fullSnapshotName = fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 	}
 
-	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+
+	if !shared.PathExists(newPath) {
+		err := os.MkdirAll(newPath, customDirMode)
+		if err != nil {
+			return err
+		}
+	}
+
 	err := os.Rename(oldPath, newPath)
 	if err != nil {
 		return err

From 47e975bd80fb7c534d23b72c61f215d0fe3bb993 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 11:01:00 +0200
Subject: [PATCH 79/81] storage/btrfs: Extend volume snapshot renaming

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_btrfs.go | 57 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index ae131a624b..6efc7b7a0a 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -720,8 +720,40 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
 	logger.Infof(`Renamed BTRFS storage volume on storage pool "%s" from "%s" to "%s`,
 		s.pool.Name, s.volume.Name, newName)
 
-	return s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, newName,
+	err = s.s.Cluster.StoragePoolVolumeRename(s.volume.Name, newName,
 		storagePoolVolumeTypeCustom, s.poolID)
+	if err != nil {
+		return err
+	}
+
+	// Rename volume snapshots
+	oldPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	// Get volumes attached to source storage volume
+	volumes, err := s.s.Cluster.StoragePoolVolumeSnapshotsGetType(s.volume.Name,
+		storagePoolVolumeTypeCustom, s.poolID)
+	if err != nil {
+		return err
+	}
+
+	for _, vol := range volumes {
+		_, snapshotName, _ := containerGetParentAndSnapshotName(vol)
+		oldVolumeName := fmt.Sprintf("%s%s%s", s.volume.Name, shared.SnapshotDelimiter, snapshotName)
+		newVolumeName := fmt.Sprintf("%s%s%s", newName, shared.SnapshotDelimiter, snapshotName)
+
+		err = s.s.Cluster.StoragePoolVolumeRename(oldVolumeName, newVolumeName,
+			storagePoolVolumeTypeCustom, s.poolID)
+		if err != nil {
+			return nil
+		}
+	}
+
+	return nil
 }
 
 func (s *storageBtrfs) GetStoragePoolVolumeWritable() api.StorageVolumePut {
@@ -2976,15 +3008,30 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 
 func (s *storageBtrfs) StoragePoolVolumeSnapshotRename(newName string) error {
 	logger.Infof("Renaming BTRFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
+	var fullSnapshotName string
 
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
-	if !ok {
-		return fmt.Errorf("Not a snapshot name")
+	if strings.Contains(newName, "/") {
+		// When renaming volume snapshots, newName will contain the full snapshot name
+		fullSnapshotName = newName
+	} else {
+		sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+		if !ok {
+			return fmt.Errorf("Not a snapshot name")
+		}
+
+		fullSnapshotName = fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 	}
 
-	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+
+	if !shared.PathExists(newPath) {
+		err := os.MkdirAll(newPath, customDirMode)
+		if err != nil {
+			return err
+		}
+	}
+
 	err := os.Rename(oldPath, newPath)
 	if err != nil {
 		return err

From 02a3fae0653bbb6004349ef44f2c056dbb34989a Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 15:35:19 +0200
Subject: [PATCH 80/81] storage/zfs: Handle renaming volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_zfs.go | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 9f514d425a..c3dcd4dc16 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -706,8 +706,18 @@ func (s *storageZfs) StoragePoolVolumeRename(newName string) error {
 			s.volume.Name, s.pool.Name)
 	}
 
-	oldPath := fmt.Sprintf("custom/%s", s.volume.Name)
-	newPath := fmt.Sprintf("custom/%s", newName)
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
+	var oldPath string
+	var newPath string
+
+	if isSnapshot {
+		oldPath = fmt.Sprintf("custom-snapshots/%s", s.volume.Name)
+		newPath = fmt.Sprintf("custom-snapshots/%s", newName)
+	} else {
+		oldPath = fmt.Sprintf("custom/%s", s.volume.Name)
+		newPath = fmt.Sprintf("custom/%s", newName)
+	}
 	poolName := s.getOnDiskPoolName()
 	err = zfsPoolVolumeRename(poolName, oldPath, newPath)
 	if err != nil {

From 9a5a45c417e3ebf446b5bdd99c066ea9ee3f4b52 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 23 Aug 2018 15:47:49 +0200
Subject: [PATCH 81/81] storage/ceph: Handle renaming volume snapshots

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/storage_ceph.go | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 2e873878d3..7ec9ab782e 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -686,8 +686,19 @@ func (s *storageCeph) StoragePoolVolumeRename(newName string) error {
 	logger.Debugf(`Mapped RBD storage volume for container "%s" on storage pool "%s"`,
 		newName, s.pool.Name)
 
-	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	isSnapshot := strings.Contains(s.volume.Name, "/")
+
+	var oldPath string
+	var newPath string
+
+	if isSnapshot {
+		oldPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		newPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newName)
+	} else {
+		oldPath = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		newPath = getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	}
+
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err


More information about the lxc-devel mailing list