Devicemapper 源码分析和流程

Stella981
• 阅读 578

整个流程大体如下:

Devicemapper 源码分析和流程

创建 thinpool

// This is theprogrammatic example of "dmsetup create"

funccreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSizeuint32) error {

...

params := fmt.Sprintf("%s %s %d 32768 1skip_block_zeroing", metadataFile.Name(), dataFile.Name(), poolBlockSize)

if err := task.AddTarget(0, size/512,"thin-pool", params); err != nil { return fmt.Errorf("Can't addtarget %s", err)

}

...

}

相当于执行下面的操作:

dmsetup create docker-8:1-696417-pool--table ‗0 419430400 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing‘

# dmsetup table docker-8:1-696417-pool

0 419430400thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing

创建 BaseImage

实际上,thin-provisionedvolume 分两步,首先是发送一个消息给 pool,创建一个 volume。然后激活

volume。只有 activated 的 volume,才能在 dmsetup info 的输出中看到。 (1)Creating a newthinly-provisioned volume

funccreateDevice(poolName string, deviceId *int) error {

if err :=task.SetMessage(fmt.Sprintf("create_thin %d", *deviceId)); err != nil{ return fmt.Errorf("Can't set message %s", err)

}

相当于执行下面的操作:

#dmsetup message/dev/mapper/ docker-8:1-696417-pool 0 "create_thin 0"

  

# hexdump -C  /var/lib/docker/devicemapper/metadata/base

  

  

00000000

  

  

7b

  

  

22

  

  

64 65 76

  

  

69 63

  

  

65

  

  

5f 69 64 22 3a

  

  

30

  

  

2c 22

  

  

|{"device_id":0,"|

  

  

00000010

  

  

73

  

  

69

  

  

7a 65

  

  

22

  

  

3a 32 31

  

  

34 37 34 38 33 36 34 38

  

  

|size":2147483648|

  

  

00000020

  

  

30

  

  

2c 22 74 72

  

  

61

  

  

6e

  

  

73

  

  

61 63 74 69

  

  

6f 6e 5f 69

  

  

|0,"transaction_i|

  

  

00000030

  

  

64

  

  

22

  

  

3a 31

  

  

2c

  

  

22

  

  

69

  

  

6e

  

  

69 74 69 61

  

  

6c

  

  

69

  

  

7a 65

  

  

|d":1,"initialize|

  

  

00000040

  

  

64

  

  

22

  

  

3a 74

  

  

72

  

  

75 65

  

  

7d

  

  

|d":true}|

  

可以看到 base 的 device_id 为 0。

(2)activatedthinly-provisioned volumes

funcactivateDevice(poolName string, name string, deviceId int, size uint64) error {

...

params :=fmt.Sprintf("%s %d", poolName, deviceId)

if err := task.AddTarget(0, size/512,"thin", params); err != nil { return fmt.Errorf("Can't addtarget %s", err)

}

相当于执行下面的操作:

#dmsetup createdocker-8:1-696417-base --table "0 41943040 thin /dev/mapper/docker-8:1-696417-pool 0"

#dmsetup table docker-8:1-696417-base 0 41943040 thin 253:0 0

只有 activated 的 volume,才能在 dmsetup info 的输出中看到。 Devicemapper 的基本操作

Driver的基本操作

///清除 thin pool

func (d *Driver)Cleanup()

///当加载新镜像时,添加一个新 thin volume,id 为 containerid 或 imageid func (d *Driver) Create(id, parent string)

///挂载 thin volume 到/var/lib/docker/devicemapper/mnt/$id 目录下(docker start) func (d *Driver) Get(id, mountLabelstring)

///从/var/lib/docker/devicemapper/mnt/$id目录 umount thinvolume(docker stop) func (d *Driver) Put(id string)

///删除 volume(真正删除)

func (d *Driver)Remove(id string)

Thinpool 的基本操作

///在 thin pool 中创建一个新的 snapshot volume

func (devices*DeviceSet) AddDevice(hash, baseHash string)

///删除 thin volume(释放空间,删除(remove+delete)thin volume) func (devices *DeviceSet) DeleteDevice(hashstring)

/// 将 thin volume 从 /var/lib/docker/devicemapper/mnt/$id umount, deactivate(remove )thinvolume(don't delete)

func (devices*DeviceSet) UnmountDevice(hash string)

///activate thin volume ,然后 mount 到/var/lib/docker/devicemapper/mnt/$idfunc (devices *DeviceSet) MountDevice(hash, path, mountLabel string)

///thin pool 的统计信息(docker info)

func (devices*DeviceSet) Status() *Status

///thin pool 初始化

funcNewDeviceSet(root string, doInit bool, options []string)

Devmapper接口

devmapper/devmapper.go封装了 OS 层的 thin volume 的基本操作。

///dmsetup suspend

funcsuspendDevice(name string)

///dmsetup resume

funcresumeDevice(name string)

///messagecreate_thin

funccreateDevice(poolName string, deviceId *int)

///message delete

funcdeleteDevice(poolName string, deviceId int)

///dmsetup remove

funcremoveDevice(name string)

///dmsetup create

funcactivateDevice(poolName string, name string, deviceId int, size uint64)

///message'create_snap'

funccreateSnapDevice(poolName string, deviceId *int, baseName string, baseDeviceIdint)

三者之间的调用关系如下:

Devicemapper 源码分析和流程

查看 stop 的容器的文件系统

stop 的容器的 thin volume 都处于未激活(deactivate)状态,我们可以将其激活(activate),然后查 看文件系统中的内容。

我们创建一个容器,不启动:

# docker create --name="yy1" centos /bin/bash 93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9

metadata 下面新增两个目录:

# ls metadata/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e993f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9 -init

我们可以查看 thin volume 的信息

#cat metadata/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9{"device_id":5,"size":21474836480,"transaction_id":8,"initialized":false}

# catmetadata/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9 -init{"device_id":4,"size":21474836480,"transaction_id":7,"initialized":false}

我们来尝试手动挂载 thin volume,首先 activate thin volume:

dmsetup
create
93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9 -init
--table    "0
41943040 thin 253:0 4"

然后就可以挂载该 thin volume 了:

mount

/dev/mapper/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9-init mnt/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9-init

# lsmnt/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9 -init/ id lost+foundrootfs

deactivate thinvolume

# umountmnt/93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01ad89f8e9-init

# dmsetup remove93f595ea79a0420cc263d054d3e63b5ad1e4cc3da128167984a6ac01

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

关注超人学院微信二维码:Devicemapper 源码分析和流程

关注超人学院java免费学习交流群:Devicemapper 源码分析和流程

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这