graph driver-device mapper-01driver初始化
- // thin device数据结构
- type DevInfo struct {
- Hash string `json:"-"`
- DeviceId int `json:"device_id"`
- Size uint64 `json:"size"`
- TransactionId uint64 `json:"transaction_id"`
- Initialized bool `json:"initialized"`
- devices *DeviceSet `json:"-"`
- mountCount int `json:"-"`
- mountPath string `json:"-"`
- lock sync.Mutex `json:"-"`
- }
- // thin pool数据结构
- type DeviceSet struct {
- MetaData
- //根文件夹,默觉得/var/lib/docker/devicemapper
- root string
- //创建thin device名字使用的前缀,`docker-${major}:${minor}-${inode}`
- devicePrefix string
- TransactionId uint64
- NewTransactionId uint64
- nextDeviceId int
- //选项
- dataLoopbackSize int64 ///var/lib/docker /devicemapper/devicemapper/data稀疏文件大小
- metaDataLoopbackSize int64 ///var/lib/docker/devicemapper/devicemapper/metadata稀疏文件大小
- baseFsSize uint64 //base image之上格式化的文件系统大小
- filesystem string //base image之上格式化的文件系统类型
- mountOptions string
- mkfsArgs []string //格式化base image文件系统时的选项
- dataDevice string //指定使用哪个设备作为data device,eg。/dev/sda
- metadataDevice string //指定使用哪个设备作为metadata device,eg。/dev/sda
- doBlkDiscard bool
- thinpBlockSize uint32 //thin pool block size
- }
- // devmapper的driver数据结构
- type Driver struct {
- *DeviceSet
- home string //home默觉得/var/lib/docker/devicemapper
- }
- docker使用device mapper的架构方式:
- //初始化devicemapper driver
- // home=/var/lib/docker/devicemapper
- // options=device mapper的选项
- // 调用路径:newdevice->initfunc
- 1.1 func Init(home string, options []string) (graphdriver.Driver, error) {
- //初始化deviceset
- deviceSet, err := NewDeviceSet(home, true, options)
- if err != nil {
- return nil, err
- }
- ...
- d := &Driver{
- DeviceSet: deviceSet,
- home: home,
- }
- return d, nil
- }
- //初始化deviceset
- // device set root=/var/lib/docker/devicemapper
- // 调用路径:Init->NewDeviceSet
- 1.2 func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error) {
- SetDevDir("/dev")
- devices := &DeviceSet{
- root: root,
- //metaData通过deviceID存放thin device的配置信息
- MetaData: MetaData{Devices: make(map[string]*DevInfo)},
- dataLoopbackSize: DefaultDataLoopbackSize,
- metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
- baseFsSize: DefaultBaseFsSize,
- filesystem: "ext4",
- doBlkDiscard: true,
- thinpBlockSize: DefaultThinpBlockSize,
- }
- //初始化deviceset选项參数
- for _, option := range options {
- key, val, err := utils.ParseKeyValueOpt(option)
- if err != nil {
- return nil, err
- }
- key = strings.ToLower(key)
- switch key {
- case "dm.basesize":
- size, err := units.RAMInBytes(val)
- if err != nil {
- return nil, err
- }
- devices.baseFsSize = uint64(size)
- ...
- default:
- return nil, fmt.Errorf("Unknown option %s\n", key)
- }
- }
- //由deviceset继续完毕初始化
- if err := devices.initDevmapper(doInit); err != nil {
- return nil, err
- }
- return devices, nil
- }
- // 初始化thin pool
- // 调用路径:NewDeviceSet->initDevmapper
- 1.3 func (devices *DeviceSet) initDevmapper(doInit bool) error {
- logInit(devices)
- //创建/var/lib/docker/devicemapper/metadata文件夹
- if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) {
- return err
- }
- //获取/var/lib/docker文件夹所在设备的 inode
- st, err := os.Stat(devices.root)
- if err != nil {
- return fmt.Errorf("Error looking up dir %s: %s", devices.root, err)
- }
- sysSt := st.Sys().(*syscall.Stat_t)
- //thin device取名规则docker-$major:$minor-$inode-$imageid/$containerid
- //thin poll取名为docker-$major:$minor-$inode-pool
- devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(sysSt.Dev), minor(sysSt.Dev), sysSt.Ino)
- //假设thin pool device存在,获取device的信息
- utils.Debugf("Checking for existence of the pool '%s'", devices.getPoolName())
- info, err := getInfo(devices.getPoolName())
- if info == nil {
- utils.Debugf("Error device getInfo: %s", err)
- return err
- }
- setCloseOnExec("/dev/mapper/control")
- createdLoopback := false
- //创建thin pool
- if info.Exists == 0 {
- utils.Debugf("Pool doesn't exist. Creating it.")
- var (
- dataFile *os.File
- metadataFile *os.File
- )
- //没有指定datadevice设备
- if devices.dataDevice == "" {
- //检查/var/lib/docker/devicemapper/devicemapper/data文件是否存在
- hasData := devices.hasImage("data")
- //既不要求初始化新的devicemapper,又没有旧的data文件
- if !doInit && !hasData {
- //返回错误
- return errors.New("Loopback data file not found")
- }
- //创建data loopdevice
- if !hasData {
- createdLoopback = true
- }
- //创建/var/lib/docker/devicemapper/devicemapper/data 稀疏文件
- data, err := devices.ensureImage("data", devices.dataLoopbackSize)
- if err != nil {
- utils.Debugf("Error device ensureImage (data): %s\n", err)
- return err
- }
- //data文件与loopback device关联
- dataFile, err = attachLoopDevice(data)
- if err != nil {
- return err
- }
- } else {
- //假设指定了data device,则打开
- dataFile, err = os.OpenFile(devices.dataDevice, os.O_RDWR, 0600)
- if err != nil {
- return err
- }
- }
- defer dataFile.Close()
- //通过相同的办法初始化metadata device
- ...
- //创建thin pool
- if err := createPool(devices.getPoolName(), dataFile, metadataFile, devices.thinpBlockSize); err != nil {
- return err
- }
- //没有创建新loopback device,则从文件夹/var/lib/docker/devicemapper/metadata/$ids
- //载入旧的metadata
- if !createdLoopback {
- if err = devices.initMetaData(); err != nil {
- return err
- }
- }
- //初始化一个新的空镜像文件,作为全部镜像的祖先镜像
- if doInit {
- if err := devices.setupBaseImage(); err != nil {
- utils.Debugf("Error device setupBaseImage: %s\n", err)
- return err
- }
- }
- return nil
- }
- // 创建祖先镜像
- 1.4 func (devices *DeviceSet) setupBaseImage() error {
- //祖先镜像的描写叙述信息存放在/var/lib/docker/devicemapper/metadata/base
- oldInfo, _ := devices.lookupDevice("")
- //之前已经创建。并完毕了初始化。则直接成功返回
- if oldInfo != nil && oldInfo.Initialized {
- return nil
- }
- //已创建。但未完毕初始化,删除base device
- if oldInfo != nil && !oldInfo.Initialized {
- utils.Debugf("Removing uninitialized base image")
- if err := devices.deleteDevice(oldInfo); err != nil {
- return err
- }
- }
- //下一个可用的deviceid
- id := devices.nextDeviceId
- //创建base device
- if err := createDevice(devices.getPoolDevName(), &id); err != nil {
- return err
- }
- devices.nextDeviceId = (id + 1) & 0xffffff
- //向thin pool注冊base device
- utils.Debugf("Registering base device (id %v) with FS size %v", id, devices.baseFsSize)
- info, err := devices.registerDevice(id, "", devices.baseFsSize)
- if err != nil {
- _ = deleteDevice(devices.getPoolDevName(), id)
- return err
- }
- //激活base device
- if err = devices.activateDeviceIfNeeded(info); err != nil {
- return err
- }
- //在base device之上格式化新文件系统
- if err := devices.createFilesystem(info); err != nil {
- return err
- }
- //完毕初始化,保存metadata到/var/lib/docker/devicemapper/metadata/base中
- info.Initialized = true
- if err = devices.saveMetadata(info); err != nil {
- info.Initialized = false
- return err
- }
- return nil
- }
graph driver-device mapper-01driver初始化的更多相关文章
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- [转] Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- Linux kernel device mapper
Device Mapper 是 Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构,如图 1. 图1 Device Mappe ...
- Docker存储驱动之Device Mapper简介
Device Mapper是一个基于kernel的框架,它增强了很多Linux上的高级卷管理技术.Docker的devicemapper驱动在镜像和容器管理上,利用了该框架的超配和快照功能.为了区别, ...
- Docker Device Mapper 使用 direct-lvm
一.Device Mapper: loop-lvm 默认 CentOS7 下 Docker 使用的 Device Mapper 设备默认使用 loopback 设备,后端为自动生成的稀疏文件,如下 ...
- flashcache中应用device mapper机制
Device Mapper(DM)是Linux 2.6全面引入的块设备新构架,通过DM可以灵活地管理系统中所有的真实或虚拟的块设备. DM以块设备的形式注册到Linux内核中,凡是挂载(或者说“映射” ...
- Device Mapper 代码分析
Device Mapper(DM)是Linux 2.6全面引入的块设备新构架,通过DM可以灵活地管理系统中所有的真实或虚拟的块设备. DM以块设备的形式注册到Linux内核中,凡是挂载(或者说&quo ...
- Linux系统中的Device Mapper学习
在linux系统中你使用一些命令时(例如nmon.iostat 如下截图所示),有可能会看到一些名字为dm-xx的设备,那么这些设备到底是什么设备呢,跟磁盘有什么关系呢?以前不了解的时候,我也很纳闷. ...
- 使用 Device Mapper来改变Docker容器的大小
作者:Jérôme Petazzoni ( Docker 布道师) 译者:Mark Shao ( EMC 中国高级工程师) 如果在 CentOS . REHL . Fedor 或者其他默认没有 AUF ...
- Device Mapper Multipath(DM-Multipath)
Device Mapper Multipath(DM-Multipath)能够将server节点和存储阵列之间的多条I/O链路配置为一个单独的设备.这些I/O链路是由不同的线缆.交换机.控制器组成的S ...
随机推荐
- SAP自带的创建报表工具
SAP自带的工具有quickview和query两个主要的工具,当然还有其他的 quickview和query的区别主要是query支持系统之间的传输,quickview只能是用户的客户端创建使用,不 ...
- AngularJs 父子级Controller传递数据
<div ng-controller="MyAccountCtrl"> <div ng-controller="TransferCtrl"&g ...
- LA - 4043 - Ants
题意:n只蚂蚁,n棵树,每只蚂蚁要连一棵树,连线(直线)不能相交,给出n只蚂蚁和n棵树的坐标,输出n只蚂蚁所配对的树的编号(1 <= n <= 100, -10000 <= 坐标x, ...
- uva 1415 - Gauss Prime(高斯素数)
题目链接:uva 1415 - Gauss Prime 题目大意:给出一个a,b,表示高斯数a+bi(i=−2‾‾‾√,推断该数是否为高斯素数. 解题思路: a = 0 时.肯定不是高斯素数 a != ...
- 浅析Delphi Container库(有开源的DCLX)
与Java和C++相比,Delphi对容器的支持实在少得可怜.Java有强大的集合框架,C++更有STL,Delphi有什么呢,不就是TList几个小巧的列表类,而TCollection系列的类更多只 ...
- Allegro CL Express Edition Downloads
Allegro CL Express Edition Downloads Allegro CL Express Edition Downloads
- hdu 1530 Maximum Clique
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1530 题目分类:最大团问题 DP + DFS 代码: #include<bits/stdc++. ...
- js动态添加Div
利用JavaScript动态添加Div的方式有很多,在这次开发中有用到,就搜集了一下比较常用的. 一.在一个Div前添加Div <html> <body> <div id ...
- 怎样处理iOS 5与iOS 6的 low-memory
移动设备终端的内存极为有限,应用程序必须做好low-memory处理工作,才能避免程序因内存使用过大而崩溃. low-memory 处理思路 通常一个应用程序会包含多个view controllers ...
- Android周报
Android周报 原文 http://www.race604.com/android-weekly-25/ 文章/教程 使用 Kotlin 开发 Android 应用系列 看起来用 Kotli ...