[lxc-devel] [lxd/master] shared: move idmap/acl functions to a separate package

albertodonato on Github lxc-bot at linuxcontainers.org
Fri Sep 8 11:07:53 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 375 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170908/b5bc1055/attachment.bin>
-------------- next part --------------
From 662161d239e152f017fa27a9fd6c03a5f9e44432 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Fri, 8 Sep 2017 12:00:38 +0200
Subject: [PATCH] shared: move idmap/acl functions to a separate package

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 fuidshift/main.go                         |  12 +--
 lxd/container.go                          |   5 +-
 lxd/container_lxc.go                      |  33 +++---
 lxd/container_lxc_utils.go                |  12 +--
 lxd/main_activateifneeded.go              |   3 +-
 lxd/main_init.go                          |   3 +-
 lxd/migrate.go                            |  21 ++--
 lxd/storage.go                            |   9 +-
 lxd/storage_btrfs.go                      |   3 +-
 lxd/storage_ceph_migration.go             |   3 +-
 lxd/storage_dir.go                        |   3 +-
 lxd/storage_lvm.go                        |   3 +-
 lxd/storage_migration.go                  |   3 +-
 lxd/storage_mock.go                       |   4 +-
 lxd/storage_zfs.go                        |   3 +-
 lxd/sys/os.go                             |   3 +-
 lxd/util/sys.go                           |   8 +-
 shared/{ => idmap}/idmapset_linux.go      |  18 ++--
 shared/{ => idmap}/idmapset_linux_test.go |   2 +-
 shared/idmap/shift_linux.go               | 170 ++++++++++++++++++++++++++++++
 shared/util_linux.go                      | 145 +------------------------
 21 files changed, 254 insertions(+), 212 deletions(-)
 rename shared/{ => idmap}/idmapset_linux.go (97%)
 rename shared/{ => idmap}/idmapset_linux_test.go (99%)
 create mode 100644 shared/idmap/shift_linux.go

diff --git a/fuidshift/main.go b/fuidshift/main.go
index 63eb2ffb1..a9fa1382a 100644
--- a/fuidshift/main.go
+++ b/fuidshift/main.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 )
 
 func help(me string, status int) {
@@ -35,7 +35,7 @@ func run() error {
 	}
 
 	directory := os.Args[1]
-	idmap := shared.IdmapSet{}
+	idmapSet := idmap.IdmapSet{}
 	testmode := false
 	reverse := false
 
@@ -48,14 +48,14 @@ func run() error {
 			testmode = true
 		default:
 			var err error
-			idmap, err = idmap.Append(os.Args[pos])
+			idmapSet, err = idmapSet.Append(os.Args[pos])
 			if err != nil {
 				return err
 			}
 		}
 	}
 
-	if idmap.Len() == 0 {
+	if idmapSet.Len() == 0 {
 		fmt.Printf("No idmaps given\n")
 		help(os.Args[0], 1)
 	}
@@ -66,7 +66,7 @@ func run() error {
 	}
 
 	if reverse {
-		return idmap.UidshiftFromContainer(directory, testmode)
+		return idmapSet.UidshiftFromContainer(directory, testmode)
 	}
-	return idmap.UidshiftIntoContainer(directory, testmode)
+	return idmapSet.UidshiftIntoContainer(directory, testmode)
 }
diff --git a/lxd/container.go b/lxd/container.go
index 1be7f95a1..bde60418a 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -18,6 +18,7 @@ import (
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/osarch"
 )
 
@@ -494,8 +495,8 @@ type container interface {
 	StorageStart() (bool, error)
 	StorageStop() (bool, error)
 	Storage() storage
-	IdmapSet() (*shared.IdmapSet, error)
-	LastIdmapSet() (*shared.IdmapSet, error)
+	IdmapSet() (*idmap.IdmapSet, error)
+	LastIdmapSet() (*idmap.IdmapSet, error)
 	TemplateApply(trigger string) error
 	StateObject() *state.State
 }
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index d2628583c..eba02ad72 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -30,6 +30,7 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 
@@ -331,7 +332,7 @@ func containerLXCCreate(s *state.State, args db.ContainerArgs) (container, error
 	c.storage = cStorage
 
 	// Setup initial idmap config
-	var idmap *shared.IdmapSet
+	var idmap *idmap.IdmapSet
 	base := int64(0)
 	if !c.IsPrivileged() {
 		idmap, base, err = findIdmap(
@@ -457,7 +458,7 @@ type containerLXC struct {
 	// Cache
 	c        *lxc.Container
 	state    *state.State
-	idmapset *shared.IdmapSet
+	idmapset *idmap.IdmapSet
 
 	// Storage
 	storage storage
@@ -544,7 +545,7 @@ func idmapSize(state *state.State, isolatedStr string, size string) (int64, erro
 
 var idmapLock sync.Mutex
 
-func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
+func parseRawIdmap(value string) ([]idmap.IdmapEntry, error) {
 	getRange := func(r string) (int64, int64, error) {
 		entries := strings.Split(r, "-")
 		if len(entries) > 2 {
@@ -570,7 +571,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
 		return base, size, nil
 	}
 
-	ret := shared.IdmapSet{}
+	ret := idmap.IdmapSet{}
 
 	for _, line := range strings.Split(value, "\n") {
 		if line == "" {
@@ -596,7 +597,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
 			return nil, fmt.Errorf("idmap ranges of different sizes %s", line)
 		}
 
-		entry := shared.IdmapEntry{
+		entry := idmap.IdmapEntry{
 			Hostid:   outsideBase,
 			Nsid:     insideBase,
 			Maprange: insideSize,
@@ -630,7 +631,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
 	return ret.Idmap, nil
 }
 
-func findIdmap(state *state.State, cName string, isolatedStr string, configBase string, configSize string, rawIdmap string) (*shared.IdmapSet, int64, error) {
+func findIdmap(state *state.State, cName string, isolatedStr string, configBase string, configSize string, rawIdmap string) (*idmap.IdmapSet, int64, error) {
 	isolated := false
 	if shared.IsTrue(isolatedStr) {
 		isolated = true
@@ -642,7 +643,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
 	}
 
 	if !isolated {
-		newIdmapset := shared.IdmapSet{Idmap: make([]shared.IdmapEntry, len(state.OS.IdmapSet.Idmap))}
+		newIdmapset := idmap.IdmapSet{Idmap: make([]idmap.IdmapEntry, len(state.OS.IdmapSet.Idmap))}
 		copy(newIdmapset.Idmap, state.OS.IdmapSet.Idmap)
 
 		for _, ent := range rawMaps {
@@ -657,8 +658,8 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
 		return nil, 0, err
 	}
 
-	mkIdmap := func(offset int64, size int64) *shared.IdmapSet {
-		set := &shared.IdmapSet{Idmap: []shared.IdmapEntry{
+	mkIdmap := func(offset int64, size int64) *idmap.IdmapSet {
+		set := &idmap.IdmapSet{Idmap: []idmap.IdmapEntry{
 			{Isuid: true, Nsid: 0, Hostid: offset, Maprange: size},
 			{Isgid: true, Nsid: 0, Hostid: offset, Maprange: size},
 		}}
@@ -689,7 +690,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
 
 	offset := state.OS.IdmapSet.Idmap[0].Hostid + 65536
 
-	mapentries := shared.ByHostid{}
+	mapentries := idmap.ByHostid{}
 	for _, name := range cs {
 		/* Don't change our map Just Because. */
 		if name == cName {
@@ -722,7 +723,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
 			return nil, 0, err
 		}
 
-		mapentries = append(mapentries, &shared.IdmapEntry{Hostid: int64(cBase), Maprange: cSize})
+		mapentries = append(mapentries, &idmap.IdmapEntry{Hostid: int64(cBase), Maprange: cSize})
 	}
 
 	sort.Sort(mapentries)
@@ -3368,7 +3369,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 	}
 
 	if shared.StringInSlice("security.idmap.isolated", changedConfig) || shared.StringInSlice("security.idmap.base", changedConfig) || shared.StringInSlice("security.idmap.size", changedConfig) || shared.StringInSlice("raw.idmap", changedConfig) || shared.StringInSlice("security.privileged", changedConfig) {
-		var idmap *shared.IdmapSet
+		var idmap *idmap.IdmapSet
 		base := int64(0)
 		if !c.IsPrivileged() {
 			// update the idmap
@@ -6859,7 +6860,7 @@ func (c *containerLXC) Id() int {
 	return c.id
 }
 
-func (c *containerLXC) IdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) IdmapSet() (*idmap.IdmapSet, error) {
 	var err error
 
 	if c.idmapset != nil {
@@ -6896,7 +6897,7 @@ func (c *containerLXC) LocalDevices() types.Devices {
 	return c.localDevices
 }
 
-func (c *containerLXC) idmapsetFromConfig(k string) (*shared.IdmapSet, error) {
+func (c *containerLXC) idmapsetFromConfig(k string) (*idmap.IdmapSet, error) {
 	lastJsonIdmap := c.LocalConfig()[k]
 
 	if lastJsonIdmap == "" {
@@ -6906,7 +6907,7 @@ func (c *containerLXC) idmapsetFromConfig(k string) (*shared.IdmapSet, error) {
 	return idmapsetFromString(lastJsonIdmap)
 }
 
-func (c *containerLXC) NextIdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) NextIdmapSet() (*idmap.IdmapSet, error) {
 	if c.localConfig["volatile.idmap.next"] != "" {
 		return c.idmapsetFromConfig("volatile.idmap.next")
 	} else if c.IsPrivileged() {
@@ -6918,7 +6919,7 @@ func (c *containerLXC) NextIdmapSet() (*shared.IdmapSet, error) {
 	return nil, fmt.Errorf("Unable to determine the idmap")
 }
 
-func (c *containerLXC) LastIdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) LastIdmapSet() (*idmap.IdmapSet, error) {
 	return c.idmapsetFromConfig("volatile.last_state.idmap")
 }
 
diff --git a/lxd/container_lxc_utils.go b/lxd/container_lxc_utils.go
index e4c288fc2..9da660f39 100644
--- a/lxd/container_lxc_utils.go
+++ b/lxd/container_lxc_utils.go
@@ -3,12 +3,12 @@ package main
 import (
 	"encoding/json"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 )
 
-func idmapsetFromString(idmap string) (*shared.IdmapSet, error) {
-	lastIdmap := new(shared.IdmapSet)
-	err := json.Unmarshal([]byte(idmap), &lastIdmap.Idmap)
+func idmapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
+	lastIdmap := new(idmap.IdmapSet)
+	err := json.Unmarshal([]byte(idmapString), &lastIdmap.Idmap)
 	if err != nil {
 		return nil, err
 	}
@@ -20,8 +20,8 @@ func idmapsetFromString(idmap string) (*shared.IdmapSet, error) {
 	return lastIdmap, nil
 }
 
-func idmapsetToJSON(idmap *shared.IdmapSet) (string, error) {
-	idmapBytes, err := json.Marshal(idmap.Idmap)
+func idmapsetToJSON(idmapSet *idmap.IdmapSet) (string, error) {
+	idmapBytes, err := json.Marshal(idmapSet.Idmap)
 	if err != nil {
 		return "", err
 	}
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index 592e04a30..0a277b07c 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -7,6 +7,7 @@ import (
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -45,7 +46,7 @@ func cmdActivateIfNeeded(args *Args) error {
 	}
 
 	// Load the idmap for unprivileged containers
-	d.os.IdmapSet, err = shared.DefaultIdmapSet()
+	d.os.IdmapSet, err = idmap.DefaultIdmapSet()
 	if err != nil {
 		return err
 	}
diff --git a/lxd/main_init.go b/lxd/main_init.go
index 009ea41f5..b09724fae 100644
--- a/lxd/main_init.go
+++ b/lxd/main_init.go
@@ -16,6 +16,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/cmd"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -810,7 +811,7 @@ func (cmd *CmdInit) askDefaultPrivileged() int {
 	// Detect lack of uid/gid
 	defaultPrivileged := -1
 	needPrivileged := false
-	idmapset, err := shared.DefaultIdmapSet()
+	idmapset, err := idmap.DefaultIdmapSet()
 	if err != nil || len(idmapset.Idmap) == 0 || idmapset.Usable() != nil {
 		needPrivileged = true
 	}
diff --git a/lxd/migrate.go b/lxd/migrate.go
index 16bcc6fa3..59fa03faa 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -854,16 +855,16 @@ func (c *migrationSink) Do(migrateOp *operation) error {
 	restore := make(chan error)
 	go func(c *migrationSink) {
 		imagesDir := ""
-		srcIdmap := new(shared.IdmapSet)
-
-		for _, idmap := range header.Idmap {
-			e := shared.IdmapEntry{
-				Isuid:    *idmap.Isuid,
-				Isgid:    *idmap.Isgid,
-				Nsid:     int64(*idmap.Nsid),
-				Hostid:   int64(*idmap.Hostid),
-				Maprange: int64(*idmap.Maprange)}
-			srcIdmap.Idmap = shared.Extend(srcIdmap.Idmap, e)
+		srcIdmap := new(idmap.IdmapSet)
+
+		for _, idmapSet := range header.Idmap {
+			e := idmap.IdmapEntry{
+				Isuid:    *idmapSet.Isuid,
+				Isgid:    *idmapSet.Isgid,
+				Nsid:     int64(*idmapSet.Nsid),
+				Hostid:   int64(*idmapSet.Hostid),
+				Maprange: int64(*idmapSet.Maprange)}
+			srcIdmap.Idmap = idmap.Extend(srcIdmap.Idmap, e)
 		}
 
 		/* We do the fs receive in parallel so we don't have to reason
diff --git a/lxd/storage.go b/lxd/storage.go
index ddc680c20..355553261 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -15,6 +15,7 @@ import (
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -220,7 +221,7 @@ type storage interface {
 		c container,
 		objects []*Snapshot,
 		conn *websocket.Conn,
-		srcIdmap *shared.IdmapSet,
+		srcIdmap *idmap.IdmapSet,
 		op *operation,
 		containerOnly bool) error
 }
@@ -392,7 +393,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str
 	poolVolumePut := st.GetStoragePoolVolumeWritable()
 
 	// get last idmapset
-	var lastIdmap *shared.IdmapSet
+	var lastIdmap *idmap.IdmapSet
 	if poolVolumePut.Config["volatile.idmap.last"] != "" {
 		lastIdmap, err = idmapsetFromString(poolVolumePut.Config["volatile.idmap.last"])
 		if err != nil {
@@ -709,14 +710,14 @@ func deleteSnapshotMountpoint(snapshotMountpoint string, snapshotsSymlinkTarget
 
 // ShiftIfNecessary sets the volatile.last_state.idmap key to the idmap last
 // used by the container.
-func ShiftIfNecessary(container container, srcIdmap *shared.IdmapSet) error {
+func ShiftIfNecessary(container container, srcIdmap *idmap.IdmapSet) error {
 	dstIdmap, err := container.IdmapSet()
 	if err != nil {
 		return err
 	}
 
 	if dstIdmap == nil {
-		dstIdmap = new(shared.IdmapSet)
+		dstIdmap = new(idmap.IdmapSet)
 	}
 
 	if !reflect.DeepEqual(srcIdmap, dstIdmap) {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 8c46f174d..0b58dd135 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -1938,7 +1939,7 @@ func (s *storageBtrfs) MigrationSource(c container, containerOnly bool) (Migrati
 	return driver, nil
 }
 
-func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	if runningInUserns {
 		return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
 	}
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index f42b706a1..24179fd6e 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -191,7 +192,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool) (Migratio
 	return &driver, nil
 }
 
-func (s *storageCeph) MigrationSink(live bool, c container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageCeph) MigrationSink(live bool, c container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	// Check that we received a valid root disk device with a pool property
 	// set.
 	parentStoragePool := ""
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 681cbfb31..acdbca417 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -12,6 +12,7 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -910,7 +911,7 @@ func (s *storageDir) MigrationSource(container container, containerOnly bool) (M
 	return rsyncMigrationSource(container, containerOnly)
 }
 
-func (s *storageDir) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageDir) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
 }
 
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index ce0107c7b..ece80e331 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -11,6 +11,7 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -1651,7 +1652,7 @@ func (s *storageLvm) MigrationSource(container container, containerOnly bool) (M
 	return rsyncMigrationSource(container, containerOnly)
 }
 
-func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
 }
 
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 80dfb2c14..faf7c4f02 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -8,6 +8,7 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 )
 
 // MigrationStorageSourceDriver defines the functions needed to implement a
@@ -122,7 +123,7 @@ func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) db.Co
 	}
 }
 
-func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	ourStart, err := container.StorageStart()
 	if err != nil {
 		return err
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index b8b7e9656..03b390824 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -5,8 +5,8 @@ import (
 
 	"github.com/gorilla/websocket"
 
-	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -211,7 +211,7 @@ func (s *storageMock) PreservesInodes() bool {
 func (s *storageMock) MigrationSource(container container, containerOnly bool) (MigrationStorageSourceDriver, error) {
 	return nil, fmt.Errorf("not implemented")
 }
-func (s *storageMock) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageMock) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	return nil
 }
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index d2e85cb1e..594d0f2ad 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -17,6 +17,7 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 
 	"github.com/pborman/uuid"
@@ -2114,7 +2115,7 @@ func (s *storageZfs) MigrationSource(ct container, containerOnly bool) (Migratio
 	return &driver, nil
 }
 
-func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
 	poolName := s.getOnDiskPoolName()
 	zfsRecv := func(zfsName string, writeWrapper func(io.WriteCloser) io.WriteCloser) error {
 		zfsFsName := fmt.Sprintf("%s/%s", poolName, zfsName)
diff --git a/lxd/sys/os.go b/lxd/sys/os.go
index d699ad878..420b6e277 100644
--- a/lxd/sys/os.go
+++ b/lxd/sys/os.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -16,7 +17,7 @@ type OS struct {
 	Architectures []int  // Cache of detected system architectures
 	LxcPath       string // Path to the $LXD_DIR/containers directory
 	BackingFS     string // Backing filesystem of $LXD_DIR/containers
-	IdmapSet      *shared.IdmapSet
+	IdmapSet      *idmap.IdmapSet
 
 	MockMode bool // If true some APIs will be mocked (for testing)
 }
diff --git a/lxd/util/sys.go b/lxd/util/sys.go
index 005a8554a..fa46a5f2b 100644
--- a/lxd/util/sys.go
+++ b/lxd/util/sys.go
@@ -5,7 +5,7 @@ import (
 
 	log "gopkg.in/inconshreveable/log15.v2"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 )
@@ -36,14 +36,14 @@ func GetArchitectures() ([]int, error) {
 }
 
 // GetIdmapSet reads the uid/gid allocation.
-func GetIdmapSet() *shared.IdmapSet {
-	idmapSet, err := shared.DefaultIdmapSet()
+func GetIdmapSet() *idmap.IdmapSet {
+	idmapSet, err := idmap.DefaultIdmapSet()
 	if err != nil {
 		logger.Warn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
 		logger.Warnf("Only privileged containers will be able to run")
 		idmapSet = nil
 	} else {
-		kernelIdmapSet, err := shared.CurrentIdmapSet()
+		kernelIdmapSet, err := idmap.CurrentIdmapSet()
 		if err == nil {
 			logger.Infof("Kernel uid/gid map:")
 			for _, lxcmap := range kernelIdmapSet.ToLxcString() {
diff --git a/shared/idmapset_linux.go b/shared/idmap/idmapset_linux.go
similarity index 97%
rename from shared/idmapset_linux.go
rename to shared/idmap/idmapset_linux.go
index da1c59e7e..aa9241c1e 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmap/idmapset_linux.go
@@ -1,4 +1,4 @@
-package shared
+package idmap
 
 import (
 	"bufio"
@@ -11,6 +11,8 @@ import (
 	"sort"
 	"strconv"
 	"strings"
+
+	"github.com/lxc/lxd/shared"
 )
 
 type IdRange struct {
@@ -307,7 +309,7 @@ func (m IdmapSet) ValidRanges() ([]*IdRange, error) {
 
 	// Sort the map
 	idmap := IdmapSet{}
-	err := DeepCopy(&m, &idmap)
+	err := shared.DeepCopy(&m, &idmap)
 	if err != nil {
 		return nil, err
 	}
@@ -397,7 +399,7 @@ func (m IdmapSet) ToLxcString() []string {
 	var lines []string
 	for _, e := range m.Idmap {
 		for _, l := range e.ToLxcString() {
-			if !StringInSlice(l+"\n", lines) {
+			if !shared.StringInSlice(l+"\n", lines) {
 				lines = append(lines, l+"\n")
 			}
 		}
@@ -478,7 +480,7 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 			return err
 		}
 
-		intUid, intGid, _, _, _, _, err := GetFileStat(path)
+		intUid, intGid, _, _, _, _, err := shared.GetFileStat(path)
 		if err != nil {
 			return err
 		}
@@ -510,7 +512,7 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 		return nil
 	}
 
-	if !PathExists(dir) {
+	if !shared.PathExists(dir) {
 		return fmt.Errorf("No such file or directory: %q", dir)
 	}
 
@@ -650,7 +652,7 @@ func DefaultIdmapSet() (*IdmapSet, error) {
 	// Check if shadow's uidmap tools are installed
 	newuidmap, _ := exec.LookPath("newuidmap")
 	newgidmap, _ := exec.LookPath("newgidmap")
-	if newuidmap != "" && newgidmap != "" && PathExists("/etc/subuid") && PathExists("/etc/subgid") {
+	if newuidmap != "" && newgidmap != "" && shared.PathExists("/etc/subuid") && shared.PathExists("/etc/subgid") {
 		// Parse the shadow uidmap
 		entries, err := getFromShadow("/etc/subuid", "root")
 		if err != nil {
@@ -788,7 +790,7 @@ func DefaultIdmapSet() (*IdmapSet, error) {
 func CurrentIdmapSet() (*IdmapSet, error) {
 	idmapset := new(IdmapSet)
 
-	if PathExists("/proc/self/uid_map") {
+	if shared.PathExists("/proc/self/uid_map") {
 		// Parse the uidmap
 		entries, err := getFromProc("/proc/self/uid_map")
 		if err != nil {
@@ -805,7 +807,7 @@ func CurrentIdmapSet() (*IdmapSet, error) {
 		idmapset.Idmap = Extend(idmapset.Idmap, e)
 	}
 
-	if PathExists("/proc/self/gid_map") {
+	if shared.PathExists("/proc/self/gid_map") {
 		// Parse the gidmap
 		entries, err := getFromProc("/proc/self/gid_map")
 		if err != nil {
diff --git a/shared/idmapset_linux_test.go b/shared/idmap/idmapset_linux_test.go
similarity index 99%
rename from shared/idmapset_linux_test.go
rename to shared/idmap/idmapset_linux_test.go
index d8582c8d9..9fe466caa 100644
--- a/shared/idmapset_linux_test.go
+++ b/shared/idmap/idmapset_linux_test.go
@@ -1,4 +1,4 @@
-package shared
+package idmap
 
 import (
 	"fmt"
diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
new file mode 100644
index 000000000..b470da4fb
--- /dev/null
+++ b/shared/idmap/shift_linux.go
@@ -0,0 +1,170 @@
+// +build linux
+// +build cgo
+
+package idmap
+
+import (
+	"fmt"
+	"os"
+	"unsafe"
+)
+
+// #cgo LDFLAGS: -lacl
+/*
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+
+int shiftowner(char *basepath, char *path, int uid, int gid) {
+	struct stat sb;
+	int fd, r;
+	char fdpath[PATH_MAX];
+	char realpath[PATH_MAX];
+
+	fd = open(path, O_PATH|O_NOFOLLOW);
+	if (fd < 0 ) {
+		perror("Failed open");
+		return 1;
+	}
+
+	r = sprintf(fdpath, "/proc/self/fd/%d", fd);
+	if (r < 0) {
+		perror("Failed sprintf");
+		close(fd);
+		return 1;
+	}
+
+	r = readlink(fdpath, realpath, PATH_MAX);
+	if (r < 0) {
+		perror("Failed readlink");
+		close(fd);
+		return 1;
+	}
+
+	if (strlen(realpath) < strlen(basepath)) {
+		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
+		close(fd);
+		return 1;
+	}
+
+	if (strncmp(realpath, basepath, strlen(basepath))) {
+		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
+		close(fd);
+		return 1;
+	}
+
+	r = fstat(fd, &sb);
+	if (r < 0) {
+		perror("Failed fstat");
+		close(fd);
+		return 1;
+	}
+
+	r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
+	if (r < 0) {
+		perror("Failed chown");
+		close(fd);
+		return 1;
+	}
+
+	if (!S_ISLNK(sb.st_mode)) {
+		r = chmod(fdpath, sb.st_mode);
+		if (r < 0) {
+			perror("Failed chmod");
+			close(fd);
+			return 1;
+		}
+	}
+
+	close(fd);
+	return 0;
+}
+*/
+import "C"
+
+// ShiftOwner updates uid and gid for a file when entering/exiting a namespace
+func ShiftOwner(basepath string, path string, uid int, gid int) error {
+	cbasepath := C.CString(basepath)
+	defer C.free(unsafe.Pointer(cbasepath))
+
+	cpath := C.CString(path)
+	defer C.free(unsafe.Pointer(cpath))
+
+	r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
+	if r != 0 {
+		return fmt.Errorf("Failed to change ownership of: %s", path)
+	}
+	return nil
+}
+
+// ShiftACL updates uid and gid for file ACLs when entering/exiting a namespace
+func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
+	finfo, err := os.Lstat(path)
+	if err != nil {
+		return err
+	}
+	if finfo.Mode()&os.ModeSymlink != 0 {
+		return nil
+	}
+
+	cpath := C.CString(path)
+	defer C.free(unsafe.Pointer(cpath))
+
+	acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
+	if acl == nil {
+		return nil
+	}
+	defer C.acl_free(unsafe.Pointer(acl))
+
+	for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
+		var ent C.acl_entry_t
+		var tag C.acl_tag_t
+		updateACL := false
+
+		ret := C.acl_get_entry(acl, C.int(entryId), &ent)
+		if ret != 1 {
+			break
+		}
+
+		ret = C.acl_get_tag_type(ent, &tag)
+		if ret == -1 {
+			return fmt.Errorf("Failed to change ACLs on %s", path)
+		}
+
+		idp := (*C.id_t)(C.acl_get_qualifier(ent))
+		if idp == nil {
+			continue
+		}
+
+		var newId int64
+		switch tag {
+		case C.ACL_USER:
+			newId, _ = shiftIds((int64)(*idp), -1)
+			updateACL = true
+
+		case C.ACL_GROUP:
+			_, newId = shiftIds(-1, (int64)(*idp))
+			updateACL = true
+		}
+
+		if updateACL {
+			ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
+			if ret == -1 {
+				return fmt.Errorf("Failed to change ACLs on %s", path)
+			}
+			ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
+			if ret == -1 {
+				return fmt.Errorf("Failed to change ACLs on %s", path)
+			}
+		}
+	}
+	return nil
+}
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 26389c7ee..77daf1051 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -19,7 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/logger"
 )
 
-// #cgo LDFLAGS: -lutil -lpthread -lacl
+// #cgo LDFLAGS: -lutil -lpthread
 /*
 #define _GNU_SOURCE
 #include <errno.h>
@@ -36,7 +36,6 @@ import (
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/un.h>
-#include <sys/acl.h>
 
 #ifndef AT_SYMLINK_FOLLOW
 #define AT_SYMLINK_FOLLOW    0x400
@@ -129,71 +128,6 @@ void create_pipe(int *master, int *slave) {
 	*slave = pipefd[1];
 }
 
-int shiftowner(char *basepath, char *path, int uid, int gid) {
-	struct stat sb;
-	int fd, r;
-	char fdpath[PATH_MAX];
-	char realpath[PATH_MAX];
-
-	fd = open(path, O_PATH|O_NOFOLLOW);
-	if (fd < 0 ) {
-		perror("Failed open");
-		return 1;
-	}
-
-	r = sprintf(fdpath, "/proc/self/fd/%d", fd);
-	if (r < 0) {
-		perror("Failed sprintf");
-		close(fd);
-		return 1;
-	}
-
-	r = readlink(fdpath, realpath, PATH_MAX);
-	if (r < 0) {
-		perror("Failed readlink");
-		close(fd);
-		return 1;
-	}
-
-	if (strlen(realpath) < strlen(basepath)) {
-		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
-		close(fd);
-		return 1;
-	}
-
-	if (strncmp(realpath, basepath, strlen(basepath))) {
-		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
-		close(fd);
-		return 1;
-	}
-
-	r = fstat(fd, &sb);
-	if (r < 0) {
-		perror("Failed fstat");
-		close(fd);
-		return 1;
-	}
-
-	r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
-	if (r < 0) {
-		perror("Failed chown");
-		close(fd);
-		return 1;
-	}
-
-	if (!S_ISLNK(sb.st_mode)) {
-		r = chmod(fdpath, sb.st_mode);
-		if (r < 0) {
-			perror("Failed chmod");
-			close(fd);
-			return 1;
-		}
-	}
-
-	close(fd);
-	return 0;
-}
-
 int get_poll_revents(int lfd, int timeout, int flags, int *revents, int *saved_errno)
 {
 	int ret;
@@ -239,83 +173,6 @@ func GetPollRevents(fd int, timeout int, flags int) (int, int, error) {
 	return int(ret), int(revents), err
 }
 
-func ShiftOwner(basepath string, path string, uid int, gid int) error {
-	cbasepath := C.CString(basepath)
-	defer C.free(unsafe.Pointer(cbasepath))
-
-	cpath := C.CString(path)
-	defer C.free(unsafe.Pointer(cpath))
-
-	r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
-	if r != 0 {
-		return fmt.Errorf("Failed to change ownership of: %s", path)
-	}
-	return nil
-}
-
-func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
-	finfo, err := os.Lstat(path)
-	if err != nil {
-		return err
-	}
-	if finfo.Mode()&os.ModeSymlink != 0 {
-		return nil
-	}
-
-	cpath := C.CString(path)
-	defer C.free(unsafe.Pointer(cpath))
-
-	acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
-	if acl == nil {
-		return nil
-	}
-	defer C.acl_free(unsafe.Pointer(acl))
-
-	for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
-		var ent C.acl_entry_t
-		var tag C.acl_tag_t
-		updateACL := false
-
-		ret := C.acl_get_entry(acl, C.int(entryId), &ent)
-		if ret != 1 {
-			break
-		}
-
-		ret = C.acl_get_tag_type(ent, &tag)
-		if ret == -1 {
-			return fmt.Errorf("Failed to change ACLs on %s", path)
-		}
-
-		idp := (*C.id_t)(C.acl_get_qualifier(ent))
-		if idp == nil {
-			continue
-		}
-
-		var newId int64
-		switch tag {
-		case C.ACL_USER:
-			newId, _ = shiftIds((int64)(*idp), -1)
-			updateACL = true
-
-		case C.ACL_GROUP:
-			_, newId = shiftIds(-1, (int64)(*idp))
-			updateACL = true
-		}
-
-		if updateACL {
-			ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
-			if ret == -1 {
-				return fmt.Errorf("Failed to change ACLs on %s", path)
-			}
-			ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
-			if ret == -1 {
-				return fmt.Errorf("Failed to change ACLs on %s", path)
-			}
-		}
-	}
-	return nil
-}
-
 func OpenPty(uid, gid int64) (master *os.File, slave *os.File, err error) {
 	fd_master := C.int(-1)
 	fd_slave := C.int(-1)


More information about the lxc-devel mailing list