The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2831
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From 4b86598132caf1991bedae40f20add1f396b4307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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 }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel