[lxc-devel] [lxd/master] Bugfixes
stgraber on Github
lxc-bot at linuxcontainers.org
Mon Jan 30 22:40:24 UTC 2017
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/20170130/442c833c/attachment.bin>
-------------- next part --------------
From 4b86598132caf1991bedae40f20add1f396b4307 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 30 Jan 2017 16:34:41 -0500
Subject: [PATCH 1/2] simplestreams: Always prefer squashfs when available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Makes things less random for users and is usually a bit faster to unpack.
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
shared/simplestreams/simplestreams.go | 76 ++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 37 deletions(-)
diff --git a/shared/simplestreams/simplestreams.go b/shared/simplestreams/simplestreams.go
index 490cc4f..6ca7666 100644
--- a/shared/simplestreams/simplestreams.go
+++ b/shared/simplestreams/simplestreams.go
@@ -107,58 +107,60 @@ func (s *SimpleStreamsManifest) ToLXD() ([]api.Image, map[string][][]string) {
continue
}
- size := int64(0)
- filename := ""
- fingerprint := ""
+ var meta SimpleStreamsManifestProductVersionItem
+ var rootTar SimpleStreamsManifestProductVersionItem
+ var rootSquash SimpleStreamsManifestProductVersionItem
- metaPath := ""
- metaHash := ""
- rootfsPath := ""
- rootfsHash := ""
-
- found := 0
for _, item := range version.Items {
// Skip the files we don't care about
if !shared.StringInSlice(item.FileType, []string{"root.tar.xz", "lxd.tar.xz", "squashfs"}) {
continue
}
- found += 1
-
- if fingerprint == "" {
- if item.LXDHashSha256SquashFs != "" {
- fingerprint = item.LXDHashSha256SquashFs
- } else if item.LXDHashSha256RootXz != "" {
- fingerprint = item.LXDHashSha256RootXz
- } else if item.LXDHashSha256 != "" {
- fingerprint = item.LXDHashSha256
- }
- }
if item.FileType == "lxd.tar.xz" {
- fields := strings.Split(item.Path, "/")
- filename = fields[len(fields)-1]
- metaPath = item.Path
- metaHash = item.HashSha256
-
- size += item.Size
+ meta = item
+ } else if item.FileType == "squashfs" {
+ rootSquash = item
+ } else if item.FileType == "root.tar.xz" {
+ rootTar = item
}
+ }
- if rootfsPath == "" || rootfsHash == "" {
- if item.FileType == "squashfs" {
- rootfsPath = item.Path
- rootfsHash = item.HashSha256
- }
+ if meta.FileType == "" || (rootTar.FileType == "" && rootSquash.FileType == "") {
+ // Invalid image
+ continue
+ }
- if item.FileType == "root.tar.xz" {
- rootfsPath = item.Path
- rootfsHash = item.HashSha256
- }
+ metaPath := meta.Path
+ metaHash := meta.HashSha256
+ rootfsPath := ""
+ rootfsHash := ""
+ fields := strings.Split(meta.Path, "/")
+ filename := fields[len(fields)-1]
+ size := meta.Size
+ fingerprint := ""
- size += item.Size
+ if rootSquash.FileType != "" {
+ if meta.LXDHashSha256SquashFs != "" {
+ fingerprint = meta.LXDHashSha256SquashFs
+ } else {
+ fingerprint = meta.LXDHashSha256
+ }
+ size += rootSquash.Size
+ rootfsPath = rootSquash.Path
+ rootfsHash = rootSquash.HashSha256
+ } else {
+ if meta.LXDHashSha256RootXz != "" {
+ fingerprint = meta.LXDHashSha256RootXz
+ } else {
+ fingerprint = meta.LXDHashSha256
}
+ size += rootTar.Size
+ rootfsPath = rootTar.Path
+ rootfsHash = rootTar.HashSha256
}
- if found < 2 || size == 0 || filename == "" || fingerprint == "" {
+ if size == 0 || filename == "" || fingerprint == "" {
// Invalid image
continue
}
From 44da2259ed4d790ebeba7a33953cb3c470805781 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 30 Jan 2017 17:38:34 -0500
Subject: [PATCH 2/2] btrfs: Fix recursive subvol deletion
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Always iterate through the filesystem to find the subvolumes as there
doesn't seem to be a good way to get a long tree of nested subvolumes
out of btrfs subvolume list.
- To improve performance of above, change isSubvolume to do a single
syscall and not fork btrfs.
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage_btrfs.go | 129 ++++++++++++---------------------------------------
1 file changed, 30 insertions(+), 99 deletions(-)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index cf70b21..2b9f2ab 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -8,6 +8,7 @@ import (
"os/exec"
"path"
"path/filepath"
+ "sort"
"strconv"
"strings"
"syscall"
@@ -694,38 +695,14 @@ func (s *storageBtrfs) subvolsSnapshot(
* else false.
*/
func (s *storageBtrfs) isSubvolume(subvolPath string) bool {
- if runningInUserns {
- // subvolume show is restricted to real root, use a workaround
-
- fs := syscall.Statfs_t{}
- err := syscall.Statfs(subvolPath, &fs)
- if err != nil {
- return false
- }
-
- if fs.Type != filesystemSuperMagicBtrfs {
- return false
- }
-
- parentFs := syscall.Statfs_t{}
- err = syscall.Statfs(path.Dir(subvolPath), &parentFs)
- if err != nil {
- return false
- }
-
- if fs.Fsid == parentFs.Fsid {
- return false
- }
-
- return true
+ fs := syscall.Stat_t{}
+ err := syscall.Lstat(subvolPath, &fs)
+ if err != nil {
+ return false
}
- output, err := exec.Command(
- "btrfs",
- "subvolume",
- "show",
- subvolPath).CombinedOutput()
- if err != nil || strings.HasPrefix(string(output), "ERROR: ") {
+ // Check if BTRFS_FIRST_FREE_OBJECTID
+ if fs.Ino != 256 {
return false
}
@@ -736,82 +713,36 @@ func (s *storageBtrfs) isSubvolume(subvolPath string) bool {
func (s *storageBtrfs) getSubVolumes(path string) ([]string, error) {
result := []string{}
- if runningInUserns {
- if !strings.HasSuffix(path, "/") {
- path = path + "/"
- }
-
- // Unprivileged users can't get to fs internals
- filepath.Walk(path, func(fpath string, fi os.FileInfo, err error) error {
- if strings.TrimRight(fpath, "/") == strings.TrimRight(path, "/") {
- return nil
- }
-
- if err != nil {
- return nil
- }
-
- if !fi.IsDir() {
- return nil
- }
-
- if s.isSubvolume(fpath) {
- result = append(result, strings.TrimPrefix(fpath, path))
- }
- return nil
- })
-
- return result, nil
+ if !strings.HasSuffix(path, "/") {
+ path = path + "/"
}
- out, err := exec.Command(
- "btrfs",
- "inspect-internal",
- "rootid",
- path).CombinedOutput()
- if err != nil {
- return result, fmt.Errorf(
- "Unable to get btrfs rootid, path='%s', err='%s'",
- path,
- err)
- }
- rootid := strings.TrimRight(string(out), "\n")
+ // Unprivileged users can't get to fs internals
+ filepath.Walk(path, func(fpath string, fi os.FileInfo, err error) error {
+ // Skip walk errors
+ if err != nil {
+ return nil
+ }
- out, err = exec.Command(
- "btrfs",
- "inspect-internal",
- "subvolid-resolve",
- rootid, path).CombinedOutput()
- if err != nil {
- return result, fmt.Errorf(
- "Unable to resolve btrfs rootid, path='%s', err='%s'",
- path,
- err)
- }
- basePath := strings.TrimRight(string(out), "\n")
+ // Ignore the base path
+ if strings.TrimRight(fpath, "/") == strings.TrimRight(path, "/") {
+ return nil
+ }
- out, err = exec.Command(
- "btrfs",
- "subvolume",
- "list",
- "-o",
- path).CombinedOutput()
- if err != nil {
- return result, fmt.Errorf(
- "Unable to list subvolumes, path='%s', err='%s'",
- path,
- err)
- }
+ // Subvolumes can only be directories
+ if !fi.IsDir() {
+ return nil
+ }
- lines := strings.Split(string(out), "\n")
- for _, line := range lines {
- if line == "" {
- continue
+ // Check if a btrfs subvolume
+ if s.isSubvolume(fpath) {
+ result = append(result, strings.TrimPrefix(fpath, path))
}
- cols := strings.Fields(line)
- result = append(result, cols[8][len(basePath):])
- }
+ return nil
+ })
+
+ sort.Sort(sort.Reverse(sort.StringSlice(result)))
return result, nil
}
More information about the lxc-devel
mailing list