dm.fs

参数 dm.fs 可以指定容器的 rootfs 的文件系统,但只支持 ext4/xfs,源码如下 funcNewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error) {

...

case"dm.fs":

if val !="ext4" && val != "xfs" {

return nil,fmt.Errorf("Unsupported filesystem %s\n", val)

}

devices.filesystem =va

参考: http://blogs.gnome.org/alexl/2013/10/15/adventures-in-docker-land/

一句话,因为 ext4/xfs 支持 DISCARD。这样,如果容器中删除了文件,空间就会马上还给 Thin pool,

因为 Thin provisioning 是支持 DISCARD 操作的。但是,默认情况下 Thin pool 是底层是稀疏文件 /var/lib/docker/devicemapper/devicemapper/data,所以,只有 Host 的文件系统支持 DISCARD,才

能保证稀疏文件空间释放。

Host  ext3

  

# docker p_w_picpaths

  



  

REPOSITORY

  
  

TAG

  
  

IMAGE ID

  
  

CREATED

  
  

VIRTUAL SIZE

  
  

dbyin/tlinux1.2

  
  

latest

  
  

8297f05d459f

  
  

41 hours ago

  
  

399.6 MB

  
  

dbyin/httpd

  
  

latest

  
  

93e711fab1c1

  
  

7 weeks ago

  
  

412.7 MB

  
  

centos

  
  

latest

  
  

61038e6e3195

  
  

3 months ago

  
  

236.4 MB

  

我们可以查看稀疏文件的真正大小:

# ls -lsh/var/lib/docker/devicemapper/devicemapper/data

1.6G -rw------- 1root root 200G Nov 12 11:52 /var/lib/docker/devicemapper/devicemapper/data

# dmsetup status

yy_pool: 0 409600 thin-pool 0 13/65536 0/3200 - rw no_discard_passdowndocker-8:1-696417-base: 0 41943040 thin 928768 41943039

docker-8:1-696417-pool:0 419430400 thin-pool 73 633/524288 26115/3276800 - rw no_discard_passdown

我们删除一个 p_w_picpath

# docker rmidbyin/httpd

可以看到稀疏文件并没有变小:

# ls -lsh/var/lib/docker/devicemapper/devicemapper/data

1.6G -rw------- 1root root 200G Nov 12 11:52 /var/lib/docker/devicemapper/devicemapper/data

# dmsetup status

docker-8:1-696417-base:0 41943040 thin 928768 41943039

docker-8:1-696417-pool:0 419430400 thin-pool 73 490/524288 18758/3276800 - rw no_discard_passdown

no_discard_passdown 表示 dm层不会将 DISCARD传给底层的设备(loopback device),只删除映 射关系。



file:///C:/Users/WANGLI~1/AppData/Local/Temp/msohtmlclip1/01/clip_p_w_picpath002.gif

Host  ext4

# dmsetup status

docker-253:1-8790943-pool:0 209715200 thin-pool 339 876/524288 32432/1638400 - rw discard_passdownqueue_if_no_space

可以看到这里为

discard_passdown,表示 dm会将 DISCARD传给底层设备(loopback device) queue_if_no_space 表示如果 thin pool没有空闲空间后,IO请求会被排队 error_if_no_space 表示如果 thin pool没有空闲空间后,直接报错。

# ls -slh/var/lib/docker/devicemapper/devicemapper/data

2.5G -rw-------. 1root root 100G Nov 12 06:14 /var/lib/docker/devicemapper/devicemapper/data

# docker rmi dbyin/httpd

# ls -slh/var/lib/docker/devicemapper/devicemapper/data

2.0G -rw-------. 1root root 100G Nov 12 06:15 /var/lib/docker/devicemapper/devicemapper/data

可以看到删除 p_w_picpath 前后,稀疏文件大小的变化。

dm.blkdiscard

docker 还提供这个参数,默认值为 true,即删除 p_w_picpath 后,会调用 DISCARD,真正释放 HOST 上空

间。

func (devices *DeviceSet) deleteDevice(info*DevInfo) error { if devices.doBlkDiscard {

// This is a workaround for the kernel notdiscarding block so

// on the thin pool when we remove a thinpdevice, so we do it

// manually

iferr := devices.activateDeviceIfNeeded(info); err == nil {

if err := BlockDeviceDiscard(info.DevName()); err!= nil { log.Debugf("Error discarding block on device: %s(ignoring)", err)

}

}

}

...

}

funcBlockDeviceDiscard(path string) error {

...

if err := ioctlBlkDiscard(file.Fd(), 0, size); err!= nil { return err

}

...

}

func ioctlBlkDiscard(fd uintptr, offset, lengthuint64) error { var r [2]uint64

r[0]= offset r[1] = length

if_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, BlkDiscard,uintptr(unsafe.Pointer(&r[0]))); err != 0 {

return err

}

return nil

}

更多精彩内容请关注:http://bbs.superwu.cn 

关注超人学院微信二维码:

关注超人学院java免费学习交流群: