diff --git a/common/go.mod b/common/go.mod index 29a260cdf2..670a0db7cd 100644 --- a/common/go.mod +++ b/common/go.mod @@ -6,7 +6,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/containers/image/v5 v5.14.0 github.com/containers/ocicrypt v1.1.2 - github.com/containers/storage v1.33.0 + github.com/containers/storage v1.33.1 github.com/disiqueira/gotree/v3 v3.0.2 github.com/docker/distribution v2.7.1+incompatible github.com/docker/docker v20.10.7+incompatible diff --git a/common/go.sum b/common/go.sum index 24a7179909..b213282830 100644 --- a/common/go.sum +++ b/common/go.sum @@ -231,8 +231,8 @@ github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0= github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw= -github.com/containers/storage v1.33.0 h1:sTk1Mfz3uSNg7cxeaDb0Ld8/UV+8pZEOQjvysjJuzX8= -github.com/containers/storage v1.33.0/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY= +github.com/containers/storage v1.33.1 h1:RHUPZ7vQxwoeOoMoKUDsVun4f9Wi8BTXmr/wQiruBYU= +github.com/containers/storage v1.33.1/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= diff --git a/common/vendor/github.com/containers/storage/VERSION b/common/vendor/github.com/containers/storage/VERSION index 7aa332e416..02261bead1 100644 --- a/common/vendor/github.com/containers/storage/VERSION +++ b/common/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.33.0 +1.33.1 diff --git a/common/vendor/github.com/containers/storage/drivers/quota/projectquota.go b/common/vendor/github.com/containers/storage/drivers/quota/projectquota.go index a435f6b820..0609f970c2 100644 --- a/common/vendor/github.com/containers/storage/drivers/quota/projectquota.go +++ b/common/vendor/github.com/containers/storage/drivers/quota/projectquota.go @@ -52,8 +52,11 @@ import "C" import ( "fmt" "io/ioutil" + "math" + "os" "path" "path/filepath" + "syscall" "unsafe" "github.com/containers/storage/pkg/directory" @@ -61,6 +64,8 @@ import ( "golang.org/x/sys/unix" ) +const projectIDsAllocatedPerQuotaHome = 10000 + // Quota limit params - currently we only control blocks hard limit and inodes type Quota struct { Size uint64 @@ -75,23 +80,48 @@ type Control struct { quotas map[string]uint32 } +// Attempt to generate a unigue projectid. Multiple directories +// per file system can have quota and they need a group of unique +// ids. This function attempts to allocate at least projectIDsAllocatedPerQuotaHome(10000) +// unique projectids, based on the inode of the basepath. +func generateUniqueProjectID(path string) (uint32, error) { + fileinfo, err := os.Stat(path) + if err != nil { + return 0, err + } + stat, ok := fileinfo.Sys().(*syscall.Stat_t) + if !ok { + return 0, fmt.Errorf("Not a syscall.Stat_t %s", path) + + } + projectID := projectIDsAllocatedPerQuotaHome + (stat.Ino*projectIDsAllocatedPerQuotaHome)%(math.MaxUint32-projectIDsAllocatedPerQuotaHome) + return uint32(projectID), nil +} + // NewControl - initialize project quota support. // Test to make sure that quota can be set on a test dir and find // the first project id to be used for the next container create. // // Returns nil (and error) if project quota is not supported. // -// First get the project id of the home directory. +// First get the project id of the basePath directory. // This test will fail if the backing fs is not xfs. // // xfs_quota tool can be used to assign a project id to the driver home directory, e.g.: -// echo 999:/var/lib/containers/storage/overlay >> /etc/projects -// echo storage:999 >> /etc/projid -// xfs_quota -x -c 'project -s storage' / +// echo 100000:/var/lib/containers/storage/overlay >> /etc/projects +// echo 200000:/var/lib/containers/storage/volumes >> /etc/projects +// echo storage:100000 >> /etc/projid +// echo volumes:200000 >> /etc/projid +// xfs_quota -x -c 'project -s storage volumes' / // -// In that case, the home directory project id will be used as a "start offset" -// and all containers will be assigned larger project ids (e.g. >= 1000). -// This is a way to prevent xfs_quota management from conflicting with containers/storage. +// In the example above, the storage directory project id will be used as a +// "start offset" and all containers will be assigned larger project ids +// (e.g. >= 100000). Then the volumes directory project id will be used as a +// "start offset" and all volumes will be assigned larger project ids +// (e.g. >= 200000). +// This is a way to prevent xfs_quota management from conflicting with +// containers/storage. + // // Then try to create a test directory with the next project id and set a quota // on it. If that works, continue to scan existing containers to map allocated @@ -105,8 +135,15 @@ func NewControl(basePath string) (*Control, error) { if err != nil { return nil, err } - minProjectID++ + if minProjectID == 0 { + // Indicates the storage was never initialized + // Generate a unique range of Projectids for this basepath + minProjectID, err = generateUniqueProjectID(basePath) + if err != nil { + return nil, err + } + } // // create backing filesystem device node // @@ -180,12 +217,12 @@ func setProjectQuota(backingFsBlockDev string, projectID uint32, quota Quota) er d.d_flags = C.FS_PROJ_QUOTA if quota.Size > 0 { - d.d_fieldmask = C.FS_DQ_BHARD | C.FS_DQ_BSOFT + d.d_fieldmask = d.d_fieldmask | C.FS_DQ_BHARD | C.FS_DQ_BSOFT d.d_blk_hardlimit = C.__u64(quota.Size / 512) d.d_blk_softlimit = d.d_blk_hardlimit } if quota.Inodes > 0 { - d.d_fieldmask = C.FS_DQ_IHARD | C.FS_DQ_ISOFT + d.d_fieldmask = d.d_fieldmask | C.FS_DQ_IHARD | C.FS_DQ_ISOFT d.d_ino_hardlimit = C.__u64(quota.Inodes) d.d_ino_softlimit = d.d_ino_hardlimit } diff --git a/common/vendor/modules.txt b/common/vendor/modules.txt index 94dccdbfb5..b3ef626a22 100644 --- a/common/vendor/modules.txt +++ b/common/vendor/modules.txt @@ -112,7 +112,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7 github.com/containers/ocicrypt/spec github.com/containers/ocicrypt/utils github.com/containers/ocicrypt/utils/keyprovider -# github.com/containers/storage v1.33.0 +# github.com/containers/storage v1.33.1 ## explicit github.com/containers/storage github.com/containers/storage/drivers