This adds the following --storage-opts for the daemon:
dm.fs: The filesystem to use for the base image
dm.mkfsarg: Add an argument to the mkfs command for the base image
dm.mountopt: Add a mount option for devicemapper mount
Currently supported filesystems are xfs and ext4.
Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
| ... | ... |
@@ -71,3 +71,27 @@ Here is the list of supported options: |
| 71 | 71 |
|
| 72 | 72 |
``docker -d --storage-opt dm.loopmetadatasize=4G`` |
| 73 | 73 |
|
| 74 |
+ * `dm.fs` |
|
| 75 |
+ |
|
| 76 |
+ Specifies the filesystem type to use for the base device. The supported |
|
| 77 |
+ options are "ext4" and "xfs". The default is "ext4" |
|
| 78 |
+ |
|
| 79 |
+ Example use: |
|
| 80 |
+ |
|
| 81 |
+ ``docker -d --storage-opt dm.fs=xfs`` |
|
| 82 |
+ |
|
| 83 |
+ * `dm.mkfsarg` |
|
| 84 |
+ |
|
| 85 |
+ Specifies extra mkfs arguments to be used when creating the base device. |
|
| 86 |
+ |
|
| 87 |
+ Example use: |
|
| 88 |
+ |
|
| 89 |
+ ``docker -d --storage-opt "dm.mkfsarg=-O ^has_journal"`` |
|
| 90 |
+ |
|
| 91 |
+ * `dm.mountopt` |
|
| 92 |
+ |
|
| 93 |
+ Specifies extra mount options used when mounting the thin devices. |
|
| 94 |
+ |
|
| 95 |
+ Example use: |
|
| 96 |
+ |
|
| 97 |
+ ``docker -d --storage-opt dm.mountopt=nodiscard`` |
| ... | ... |
@@ -72,6 +72,9 @@ type DeviceSet struct {
|
| 72 | 72 |
dataLoopbackSize int64 |
| 73 | 73 |
metaDataLoopbackSize int64 |
| 74 | 74 |
baseFsSize uint64 |
| 75 |
+ filesystem string |
|
| 76 |
+ mountOptions string |
|
| 77 |
+ mkfsArgs []string |
|
| 75 | 78 |
} |
| 76 | 79 |
|
| 77 | 80 |
type DiskUsage struct {
|
| ... | ... |
@@ -281,14 +284,30 @@ func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error {
|
| 281 | 281 |
func (devices *DeviceSet) createFilesystem(info *DevInfo) error {
|
| 282 | 282 |
devname := info.DevName() |
| 283 | 283 |
|
| 284 |
- err := exec.Command("mkfs.ext4", "-E", "nodiscard,lazy_itable_init=0,lazy_journal_init=0", devname).Run()
|
|
| 285 |
- if err != nil {
|
|
| 286 |
- err = exec.Command("mkfs.ext4", "-E", "nodiscard,lazy_itable_init=0", devname).Run()
|
|
| 284 |
+ args := []string{}
|
|
| 285 |
+ for _, arg := range devices.mkfsArgs {
|
|
| 286 |
+ args = append(args, arg) |
|
| 287 |
+ } |
|
| 288 |
+ |
|
| 289 |
+ args = append(args, devname) |
|
| 290 |
+ |
|
| 291 |
+ var err error |
|
| 292 |
+ switch devices.filesystem {
|
|
| 293 |
+ case "xfs": |
|
| 294 |
+ err = exec.Command("mkfs.xfs", args...).Run()
|
|
| 295 |
+ case "ext4": |
|
| 296 |
+ err = exec.Command("mkfs.ext4", append([]string{"-E", "nodiscard,lazy_itable_init=0,lazy_journal_init=0"}, args...)...).Run()
|
|
| 297 |
+ if err != nil {
|
|
| 298 |
+ err = exec.Command("mkfs.ext4", append([]string{"-E", "nodiscard,lazy_itable_init=0"}, args...)...).Run()
|
|
| 299 |
+ } |
|
| 300 |
+ default: |
|
| 301 |
+ err = fmt.Errorf("Unsupported filesystem type %s", devices.filesystem)
|
|
| 287 | 302 |
} |
| 288 | 303 |
if err != nil {
|
| 289 | 304 |
utils.Debugf("\n--->Err: %s\n", err)
|
| 290 | 305 |
return err |
| 291 | 306 |
} |
| 307 |
+ |
|
| 292 | 308 |
return nil |
| 293 | 309 |
} |
| 294 | 310 |
|
| ... | ... |
@@ -926,11 +945,19 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
|
| 926 | 926 |
return err |
| 927 | 927 |
} |
| 928 | 928 |
|
| 929 |
- mountOptions := label.FormatMountLabel("discard", mountLabel)
|
|
| 930 |
- err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions) |
|
| 929 |
+ options := "" |
|
| 930 |
+ |
|
| 931 |
+ if fstype == "xfs" {
|
|
| 932 |
+ // XFS needs nouuid or it can't mount filesystems with the same fs |
|
| 933 |
+ options = joinMountOptions(options, "nouuid") |
|
| 934 |
+ } |
|
| 935 |
+ |
|
| 936 |
+ options = joinMountOptions(options, devices.mountOptions) |
|
| 937 |
+ options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
|
|
| 938 |
+ |
|
| 939 |
+ err = syscall.Mount(info.DevName(), path, fstype, flags, joinMountOptions("discard", options))
|
|
| 931 | 940 |
if err != nil && err == syscall.EINVAL {
|
| 932 |
- mountOptions = label.FormatMountLabel("", mountLabel)
|
|
| 933 |
- err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions) |
|
| 941 |
+ err = syscall.Mount(info.DevName(), path, fstype, flags, options) |
|
| 934 | 942 |
} |
| 935 | 943 |
if err != nil {
|
| 936 | 944 |
return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), path, err)
|
| ... | ... |
@@ -1112,6 +1139,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error |
| 1112 | 1112 |
dataLoopbackSize: DefaultDataLoopbackSize, |
| 1113 | 1113 |
metaDataLoopbackSize: DefaultMetaDataLoopbackSize, |
| 1114 | 1114 |
baseFsSize: DefaultBaseFsSize, |
| 1115 |
+ filesystem: "ext4", |
|
| 1115 | 1116 |
} |
| 1116 | 1117 |
|
| 1117 | 1118 |
for _, option := range options {
|
| ... | ... |
@@ -1139,6 +1167,15 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error |
| 1139 | 1139 |
return nil, err |
| 1140 | 1140 |
} |
| 1141 | 1141 |
devices.metaDataLoopbackSize = size |
| 1142 |
+ case "dm.fs": |
|
| 1143 |
+ if val != "ext4" && val != "xfs" {
|
|
| 1144 |
+ return nil, fmt.Errorf("Unsupported filesystem %s\n", val)
|
|
| 1145 |
+ } |
|
| 1146 |
+ devices.filesystem = val |
|
| 1147 |
+ case "dm.mkfsarg": |
|
| 1148 |
+ devices.mkfsArgs = append(devices.mkfsArgs, val) |
|
| 1149 |
+ case "dm.mountopt": |
|
| 1150 |
+ devices.mountOptions = joinMountOptions(devices.mountOptions, val) |
|
| 1142 | 1151 |
default: |
| 1143 | 1152 |
return nil, fmt.Errorf("Unknown option %s\n", key)
|
| 1144 | 1153 |
} |
| ... | ... |
@@ -74,3 +74,13 @@ func ProbeFsType(device string) (string, error) {
|
| 74 | 74 |
|
| 75 | 75 |
return "", fmt.Errorf("Unknown filesystem type on %s", device)
|
| 76 | 76 |
} |
| 77 |
+ |
|
| 78 |
+func joinMountOptions(a, b string) string {
|
|
| 79 |
+ if a == "" {
|
|
| 80 |
+ return b |
|
| 81 |
+ } |
|
| 82 |
+ if b == "" {
|
|
| 83 |
+ return a |
|
| 84 |
+ } |
|
| 85 |
+ return a + "," + b |
|
| 86 |
+} |