Skip to content

Commit

Permalink
Merge pull request #729 from vmarmol/watches
Browse files Browse the repository at this point in the history
Report the last cgroup destroy event.
  • Loading branch information
rjnagal committed May 21, 2015
2 parents c5bbadb + ab032ef commit a6c31d4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 27 deletions.
6 changes: 3 additions & 3 deletions container/raw/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,18 +473,18 @@ func (self *rawContainerHandler) processEvent(event *inotify.Event, events chan
}

// Only report container creation once.
if !alreadyWatched {
if alreadyWatched {
return nil
}
case eventType == container.SubcontainerDelete:
// Container was deleted, stop watching for it.
wasWatched, err := self.watcher.RemoveWatch(containerName, event.Name)
lastWatched, err := self.watcher.RemoveWatch(containerName, event.Name)
if err != nil {
return err
}

// Only report container deletion once.
if wasWatched {
if !lastWatched {
return nil
}
default:
Expand Down
55 changes: 31 additions & 24 deletions container/raw/inotify_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ type InotifyWatcher struct {
// Underlying inotify watcher.
watcher *inotify.Watcher

// Containers being watched.
containersWatched map[string]bool

// Full cgroup paths being watched.
cgroupsWatched map[string]bool
// Map of containers being watched to cgroup paths watched for that container.
containersWatched map[string]map[string]bool

// Lock for all datastructure access.
lock sync.Mutex
Expand All @@ -45,8 +42,7 @@ func NewInotifyWatcher() (*InotifyWatcher, error) {

return &InotifyWatcher{
watcher: w,
containersWatched: make(map[string]bool),
cgroupsWatched: make(map[string]bool),
containersWatched: make(map[string]map[string]bool),
}, nil
}

Expand All @@ -55,46 +51,55 @@ func (iw *InotifyWatcher) AddWatch(containerName, dir string) (bool, error) {
iw.lock.Lock()
defer iw.lock.Unlock()

alreadyWatched := iw.containersWatched[containerName]
cgroupsWatched, alreadyWatched := iw.containersWatched[containerName]

// Register an inotify notification.
if !iw.cgroupsWatched[dir] {
if !cgroupsWatched[dir] {
err := iw.watcher.AddWatch(dir, inotify.IN_CREATE|inotify.IN_DELETE|inotify.IN_MOVE)
if err != nil {
return alreadyWatched, err
}
iw.cgroupsWatched[dir] = true

if cgroupsWatched == nil {
cgroupsWatched = make(map[string]bool)
}
cgroupsWatched[dir] = true
}

// Record our watching of the container.
if !alreadyWatched {
iw.containersWatched[containerName] = true
iw.containersWatched[containerName] = cgroupsWatched
}
return alreadyWatched, nil
}

// Remove watch from the specified directory. Returns if the container was already being watched.
// Remove watch from the specified directory. Returns if this was the last watch on the specified container.
func (iw *InotifyWatcher) RemoveWatch(containerName, dir string) (bool, error) {
iw.lock.Lock()
defer iw.lock.Unlock()

alreadyWatched := iw.containersWatched[containerName]
// If we don't have a watch registed for this, just return.
cgroupsWatched, ok := iw.containersWatched[containerName]
if !ok {
return false, nil
}

// Remove the inotify watch if it exists.
if iw.cgroupsWatched[dir] {
if cgroupsWatched[dir] {
err := iw.watcher.RemoveWatch(dir)
if err != nil {
return alreadyWatched, nil
return false, nil
}
delete(iw.cgroupsWatched, dir)
delete(cgroupsWatched, dir)
}

// Record the container as no longer being watched.
if alreadyWatched {
// Remove the record if this is the last watch.
if len(cgroupsWatched) == 0 {
delete(iw.containersWatched, containerName)
return true, nil
}

return alreadyWatched, nil
return false, nil
}

// Errors are returned on this channel.
Expand All @@ -112,11 +117,13 @@ func (iw *InotifyWatcher) Close() error {
return iw.watcher.Close()
}

// Returns a list of:
// - Containers being watched.
// - Cgroup paths being watched.
func (iw *InotifyWatcher) GetWatches() ([]string, []string) {
return mapToSlice(iw.containersWatched), mapToSlice(iw.cgroupsWatched)
// Returns a map of containers to the cgroup paths being watched.
func (iw *InotifyWatcher) GetWatches() map[string][]string {
out := make(map[string][]string, len(iw.containersWatched))
for k, v := range iw.containersWatched {
out[k] = mapToSlice(v)
}
return out
}

func mapToSlice(m map[string]bool) []string {
Expand Down

0 comments on commit a6c31d4

Please sign in to comment.