1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05: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:
Alexander Larsson 2013-12-05 22:22:55 +01:00
parent 191aa17d16
commit 886f650d9b

View file

@ -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 {