mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-04 04:31:28 +00:00
devicemapper: Unmount inactive devices
This implements the new Put() operation such that Get()/Put() maintains a refcount for each ID, mounting only on first Get() and unmounting on the last Get(). This means we avoid littering the system with lots of mounts and active devicemapper devices and free resources related to them. Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson) asdfljk
This commit is contained in:
@@ -5,8 +5,10 @@ package devmapper
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/graphdriver"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -20,7 +22,9 @@ func init() {
|
||||
|
||||
type Driver struct {
|
||||
*DeviceSet
|
||||
home string
|
||||
home string
|
||||
sync.Mutex // Protects concurrent modification to active
|
||||
active map[string]int
|
||||
}
|
||||
|
||||
var Init = func(home string) (graphdriver.Driver, error) {
|
||||
@@ -31,6 +35,7 @@ var Init = func(home string) (graphdriver.Driver, error) {
|
||||
d := &Driver{
|
||||
DeviceSet: deviceSet,
|
||||
home: home,
|
||||
active: make(map[string]int),
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
@@ -82,6 +87,14 @@ func (d *Driver) Create(id, parent string) error {
|
||||
}
|
||||
|
||||
func (d *Driver) Remove(id string) error {
|
||||
// Protect the d.active from concurrent access
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
if d.active[id] != 0 {
|
||||
utils.Errorf("Warning: removing active id %s\n", id)
|
||||
}
|
||||
|
||||
mp := path.Join(d.home, "mnt", id)
|
||||
if err := d.unmount(id, mp); err != nil {
|
||||
return err
|
||||
@@ -90,14 +103,36 @@ func (d *Driver) Remove(id string) error {
|
||||
}
|
||||
|
||||
func (d *Driver) Get(id string) (string, error) {
|
||||
// Protect the d.active from concurrent access
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
count := d.active[id]
|
||||
|
||||
mp := path.Join(d.home, "mnt", id)
|
||||
if err := d.mount(id, mp); err != nil {
|
||||
return "", err
|
||||
if count == 0 {
|
||||
if err := d.mount(id, mp); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
d.active[id] = count + 1
|
||||
|
||||
return path.Join(mp, "rootfs"), nil
|
||||
}
|
||||
|
||||
func (d *Driver) Put(id string) {
|
||||
// Protect the d.active from concurrent access
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
if count := d.active[id]; count > 1 {
|
||||
d.active[id] = count - 1
|
||||
} else {
|
||||
mp := path.Join(d.home, "mnt", id)
|
||||
d.unmount(id, mp)
|
||||
delete(d.active, id)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Driver) mount(id, mountPoint string) error {
|
||||
|
||||
Reference in New Issue
Block a user