graph driver-device mapper-driver初始化

來源:互聯網
上載者:User

標籤:docker   devicemapper   

// 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/devicemapperroot             string//建立thin device名字使用的首碼,預設使用`docker-${major}:${minor}-${inode}-XXX-pool`devicePrefix     stringTransactionId    uint64NewTransactionId uint64nextDeviceId     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         stringmkfsArgs             []string//格式化base image檔案系統時的選項dataDevice           string//指定使用哪個裝置作為data device,eg,/dev/sdametadataDevice       string//指定使用哪個裝置作為metadata device,eg,/dev/sdadoBlkDiscard         boolthinpBlockSize       uint32//thin pool block size}// devmapper的driver資料結構type Driver struct {*DeviceSethome string //home預設為/var/lib/docker/devicemapper}


docker使用device mapper的架構方式:
                                                     


//初始化devicemapper driver//home=/var/lib/docker/devicemapper//options=device mapper的選項//調用路徑:newdevice->initfunc1.1 func Init(home string, options []string) (graphdriver.Driver, error) {//初始化devicesetdeviceSet, 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->NewDeviceSet1.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->initDevmapper1.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目錄所在裝置的 inodest, 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-pooldevices.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 poolif info.Exists == 0 {utils.Debugf("Pool doesn't exist. Creating it.")var (dataFile     *os.FilemetadataFile *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 loopdeviceif !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...//沒有建立新loopback device,則從目錄/var/lib/docker/devicemapper/metadata/$ids//載入舊的metadataif !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/baseoldInfo, _ := devices.lookupDevice("")//之前已經建立,並完成了初始化,則直接成功返回if oldInfo != nil && oldInfo.Initialized {return nil}//已建立,但未完成初始化,刪除base deviceif oldInfo != nil && !oldInfo.Initialized {utils.Debugf("Removing uninitialized base image")if err := devices.deleteDevice(oldInfo); err != nil {return err}}//下一個可用的deviceidid := devices.nextDeviceId//建立base deviceif err := createDevice(devices.getPoolDevName(), &id); err != nil {return err}devices.nextDeviceId = (id + 1) & 0xffffff//向thin pool註冊base deviceutils.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 deviceif 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 = trueif err = devices.saveMetadata(info); err != nil {info.Initialized = falsereturn err}return nil}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.