mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
73d9ede12c
We used to mount in Create() to be able to create a few files that needs to be in each device. However, this mount is problematic for selinux, as we need to set the mount label at mount-time, and it is not known at the time of Create(). This change just moves the file creation to first Get() call and drops the mount from Create(). Additionally, this lets us remove some complexities we had to avoid an extra unmount+mount cycle. Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
132 lines
3 KiB
Go
132 lines
3 KiB
Go
// +build linux,amd64
|
|
|
|
package devmapper
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/dotcloud/docker/daemon/graphdriver"
|
|
"github.com/dotcloud/docker/utils"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
)
|
|
|
|
func init() {
|
|
graphdriver.Register("devicemapper", Init)
|
|
}
|
|
|
|
// Placeholder interfaces, to be replaced
|
|
// at integration.
|
|
|
|
// End of placeholder interfaces.
|
|
|
|
type Driver struct {
|
|
*DeviceSet
|
|
home string
|
|
}
|
|
|
|
var Init = func(home string) (graphdriver.Driver, error) {
|
|
deviceSet, err := NewDeviceSet(home, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d := &Driver{
|
|
DeviceSet: deviceSet,
|
|
home: home,
|
|
}
|
|
return d, nil
|
|
}
|
|
|
|
func (d *Driver) String() string {
|
|
return "devicemapper"
|
|
}
|
|
|
|
func (d *Driver) Status() [][2]string {
|
|
s := d.DeviceSet.Status()
|
|
|
|
status := [][2]string{
|
|
{"Pool Name", s.PoolName},
|
|
{"Data file", s.DataLoopback},
|
|
{"Metadata file", s.MetadataLoopback},
|
|
{"Data Space Used", fmt.Sprintf("%.1f Mb", float64(s.Data.Used)/(1024*1024))},
|
|
{"Data Space Total", fmt.Sprintf("%.1f Mb", float64(s.Data.Total)/(1024*1024))},
|
|
{"Metadata Space Used", fmt.Sprintf("%.1f Mb", float64(s.Metadata.Used)/(1024*1024))},
|
|
{"Metadata Space Total", fmt.Sprintf("%.1f Mb", float64(s.Metadata.Total)/(1024*1024))},
|
|
}
|
|
return status
|
|
}
|
|
|
|
func (d *Driver) Cleanup() error {
|
|
return d.DeviceSet.Shutdown()
|
|
}
|
|
|
|
func (d *Driver) Create(id, parent string, mountLabel string) error {
|
|
if err := d.DeviceSet.AddDevice(id, parent); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *Driver) Remove(id string) error {
|
|
if !d.DeviceSet.HasDevice(id) {
|
|
// Consider removing a non-existing device a no-op
|
|
// This is useful to be able to progress on container removal
|
|
// if the underlying device has gone away due to earlier errors
|
|
return nil
|
|
}
|
|
|
|
// This assumes the device has been properly Get/Put:ed and thus is unmounted
|
|
if err := d.DeviceSet.DeleteDevice(id); err != nil {
|
|
return err
|
|
}
|
|
|
|
mp := path.Join(d.home, "mnt", id)
|
|
if err := os.RemoveAll(mp); err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *Driver) Get(id string) (string, error) {
|
|
mp := path.Join(d.home, "mnt", id)
|
|
|
|
// Create the target directories if they don't exist
|
|
if err := osMkdirAll(mp, 0755); err != nil && !osIsExist(err) {
|
|
return "", err
|
|
}
|
|
|
|
// Mount the device
|
|
if err := d.DeviceSet.MountDevice(id, mp, ""); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
rootFs := path.Join(mp, "rootfs")
|
|
if err := osMkdirAll(rootFs, 0755); err != nil && !osIsExist(err) {
|
|
d.DeviceSet.UnmountDevice(id)
|
|
return "", err
|
|
}
|
|
|
|
idFile := path.Join(mp, "id")
|
|
if _, err := osStat(idFile); err != nil && osIsNotExist(err) {
|
|
// Create an "id" file with the container/image id in it to help reconscruct this in case
|
|
// of later problems
|
|
if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil {
|
|
d.DeviceSet.UnmountDevice(id)
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
return rootFs, nil
|
|
}
|
|
|
|
func (d *Driver) Put(id string) {
|
|
if err := d.DeviceSet.UnmountDevice(id); err != nil {
|
|
utils.Errorf("Warning: error unmounting device %s: %s\n", id, err)
|
|
}
|
|
}
|
|
|
|
func (d *Driver) Exists(id string) bool {
|
|
return d.DeviceSet.HasDevice(id)
|
|
}
|