Browse code

add vfs quota for daemon storage-opts

Signed-off-by: fanjiyun <fan.jiyun@zte.com.cn>

fanjiyun authored on 2019/01/15 20:49:23
Showing 3 changed files
... ...
@@ -7,11 +7,14 @@ import (
7 7
 
8 8
 	"github.com/docker/docker/daemon/graphdriver"
9 9
 	"github.com/docker/docker/daemon/graphdriver/quota"
10
+	"github.com/docker/docker/errdefs"
10 11
 	"github.com/docker/docker/pkg/containerfs"
11 12
 	"github.com/docker/docker/pkg/idtools"
13
+	"github.com/docker/docker/pkg/parsers"
12 14
 	"github.com/docker/docker/pkg/system"
13 15
 	"github.com/docker/go-units"
14 16
 	"github.com/opencontainers/selinux/go-selinux/label"
17
+	"github.com/pkg/errors"
15 18
 )
16 19
 
17 20
 var (
... ...
@@ -30,6 +33,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
30 30
 		home:      home,
31 31
 		idMapping: idtools.NewIDMappingsFromMaps(uidMaps, gidMaps),
32 32
 	}
33
+
34
+	if err := d.parseOptions(options); err != nil {
35
+		return nil, err
36
+	}
37
+
33 38
 	rootIDs := d.idMapping.RootPair()
34 39
 	if err := idtools.MkdirAllAndChown(home, 0700, rootIDs); err != nil {
35 40
 		return nil, err
... ...
@@ -37,6 +45,10 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
37 37
 
38 38
 	setupDriverQuota(d)
39 39
 
40
+	if size := d.getQuotaOpt(); !d.quotaSupported() && size > 0 {
41
+		return nil, quota.ErrQuotaNotSupported
42
+	}
43
+
40 44
 	return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
41 45
 }
42 46
 
... ...
@@ -69,11 +81,32 @@ func (d *Driver) Cleanup() error {
69 69
 	return nil
70 70
 }
71 71
 
72
+func (d *Driver) parseOptions(options []string) error {
73
+	for _, option := range options {
74
+		key, val, err := parsers.ParseKeyValueOpt(option)
75
+		if err != nil {
76
+			return errdefs.InvalidParameter(err)
77
+		}
78
+		switch key {
79
+		case "size":
80
+			size, err := units.RAMInBytes(val)
81
+			if err != nil {
82
+				return errdefs.InvalidParameter(err)
83
+			}
84
+			if err = d.setQuotaOpt(uint64(size)); err != nil {
85
+				return errdefs.InvalidParameter(errors.Wrap(err, "failed to set option size for vfs"))
86
+			}
87
+		default:
88
+			return errdefs.InvalidParameter(errors.Errorf("unknown option %s for vfs", key))
89
+		}
90
+	}
91
+	return nil
92
+}
93
+
72 94
 // CreateReadWrite creates a layer that is writable for use as a container
73 95
 // file system.
74 96
 func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
75
-	var err error
76
-	var size int64
97
+	quotaSize := d.getQuotaOpt()
77 98
 
78 99
 	if opts != nil {
79 100
 		for key, val := range opts.StorageOpt {
... ...
@@ -82,16 +115,18 @@ func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts
82 82
 				if !d.quotaSupported() {
83 83
 					return quota.ErrQuotaNotSupported
84 84
 				}
85
-				if size, err = units.RAMInBytes(val); err != nil {
86
-					return err
85
+				size, err := units.RAMInBytes(val)
86
+				if err != nil {
87
+					return errdefs.InvalidParameter(err)
87 88
 				}
89
+				quotaSize = uint64(size)
88 90
 			default:
89
-				return fmt.Errorf("Storage opt %s not supported", key)
91
+				return errdefs.InvalidParameter(errors.Errorf("Storage opt %s not supported", key))
90 92
 			}
91 93
 		}
92 94
 	}
93 95
 
94
-	return d.create(id, parent, uint64(size))
96
+	return d.create(id, parent, quotaSize)
95 97
 }
96 98
 
97 99
 // Create prepares the filesystem for the VFS driver and copies the directory for the given id under the parent.
... ...
@@ -7,6 +7,7 @@ import (
7 7
 
8 8
 type driverQuota struct {
9 9
 	quotaCtl *quota.Control
10
+	quotaOpt quota.Quota
10 11
 }
11 12
 
12 13
 func setupDriverQuota(driver *Driver) {
... ...
@@ -17,6 +18,15 @@ func setupDriverQuota(driver *Driver) {
17 17
 	}
18 18
 }
19 19
 
20
+func (d *Driver) setQuotaOpt(size uint64) error {
21
+	d.quotaOpt.Size = size
22
+	return nil
23
+}
24
+
25
+func (d *Driver) getQuotaOpt() uint64 {
26
+	return d.quotaOpt.Size
27
+}
28
+
20 29
 func (d *Driver) setupQuota(dir string, size uint64) error {
21 30
 	return d.quotaCtl.SetQuota(dir, quota.Quota{Size: size})
22 31
 }
... ...
@@ -11,6 +11,14 @@ func setupDriverQuota(driver *Driver) error {
11 11
 	return nil
12 12
 }
13 13
 
14
+func (d *Driver) setQuotaOpt(size uint64) error {
15
+	return quota.ErrQuotaNotSupported
16
+}
17
+
18
+func (d *Driver) getQuotaOpt() uint64 {
19
+	return 0
20
+}
21
+
14 22
 func (d *Driver) setupQuota(dir string, size uint64) error {
15 23
 	return quota.ErrQuotaNotSupported
16 24
 }