Skip to content

Commit

Permalink
Cleanup old networks and lock files after detecting reboot (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashvindeodhar authored and Yongli Chen committed Jan 8, 2019
1 parent b7f6742 commit e98936c
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 15 deletions.
37 changes: 28 additions & 9 deletions cni/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ func NewPlugin(name, version string) (*Plugin, error) {
return nil, err
}

// Initialize logging.
log.SetName(plugin.Name)
log.SetLevel(log.LevelInfo)
err = log.SetTarget(log.TargetLogfile)
if err != nil {
log.Printf("[cni] Failed to configure logging, err:%v.\n", err)
return &Plugin{
Plugin: plugin,
version: version,
}, err
}

return &Plugin{
Plugin: plugin,
version: version,
Expand All @@ -45,14 +57,6 @@ func (plugin *Plugin) Initialize(config *common.PluginConfig) error {
// Initialize the base plugin.
plugin.Plugin.Initialize(config)

// Initialize logging.
log.SetName(plugin.Name)
log.SetLevel(log.LevelInfo)
err := log.SetTarget(log.TargetLogfile)
if err != nil {
log.Printf("[cni] Failed to configure logging, err:%v.\n", err)
return err
}
return nil
}

Expand Down Expand Up @@ -164,6 +168,21 @@ func (plugin *Plugin) InitializeKeyValueStore(config *common.PluginConfig) error
log.Printf("[cni] Failed to create store: %v.", err)
return err
}

// Force unlock the json store if the lock file is left on the node after reboot
if lockFileModTime, err := plugin.Store.GetLockFileModificationTime(); err == nil {
rebootTime, err := platform.GetLastRebootTime()
log.Printf("[cni] reboot time %v storeLockFile mod time %v", rebootTime, lockFileModTime)
if err == nil && rebootTime.After(lockFileModTime) {
log.Printf("[cni] Detected Reboot")

if err := plugin.Store.Unlock(true); err != nil {
log.Printf("[cni] Failed to force unlock store due to error %v", err)
} else {
log.Printf("[cni] Force unlocked the store successfully")
}
}
}
}

// Acquire store lock.
Expand All @@ -180,7 +199,7 @@ func (plugin *Plugin) InitializeKeyValueStore(config *common.PluginConfig) error
// Uninitialize key-value store
func (plugin *Plugin) UninitializeKeyValueStore() error {
if plugin.Store != nil {
err := plugin.Store.Unlock()
err := plugin.Store.Unlock(false)
if err != nil {
log.Printf("[cni] Failed to unlock store: %v.", err)
return err
Expand Down
2 changes: 1 addition & 1 deletion ipam/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ func (am *addressManager) restore() error {
// Check if the VM is rebooted.
modTime, err := am.store.GetModificationTime()
if err == nil {

rebootTime, err := platform.GetLastRebootTime()
log.Printf("[ipam] reboot time %v store mod time %v", rebootTime, modTime)

Expand Down Expand Up @@ -147,6 +146,7 @@ func (am *addressManager) restore() error {
for _, as := range am.AddrSpaces {
for _, ap := range as.Pools {
ap.as = as
ap.RefCount = 0

for _, ar := range ap.Addresses {
ar.InUse = false
Expand Down
8 changes: 8 additions & 0 deletions network/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ func (nm *networkManager) restore() error {
return err
}

// Delete the networks left behind after reboot
for _, extIf := range nm.ExternalInterfaces {
for _, nw := range extIf.Networks {
log.Printf("[net] Deleting the network %s on reboot\n", nw.Id)
nm.deleteNetwork(nw.Id)
}
}

// Clear networkManager contents
nm.TimeStamp = time.Time{}
for extIfName := range nm.ExternalInterfaces {
Expand Down
8 changes: 8 additions & 0 deletions platform/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,15 @@ func GetLastRebootTime() (time.Time, error) {
bootPM := strings.Contains(strings.Split(systemBootTime, " ")[2], "PM")

month := strings.Split(bootDate, "/")[0]
if len(month) < 2 {
month = "0" + month
}

day := strings.Split(bootDate, "/")[1]
if len(day) < 2 {
day = "0" + day
}

year := strings.Split(bootDate, "/")[2]
year = strings.Trim(year, ",")
hour := strings.Split(bootTime, ":")[0]
Expand Down
28 changes: 26 additions & 2 deletions store/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ func (kvs *jsonFileStore) Lock(block bool) error {
}

// Unlock unlocks the store.
func (kvs *jsonFileStore) Unlock() error {
func (kvs *jsonFileStore) Unlock(forceUnlock bool) error {
kvs.Mutex.Lock()
defer kvs.Mutex.Unlock()

if !kvs.locked {
if !forceUnlock && !kvs.locked {
return ErrStoreNotLocked
}

Expand Down Expand Up @@ -202,3 +202,27 @@ func (kvs *jsonFileStore) GetModificationTime() (time.Time, error) {

return info.ModTime().UTC(), nil
}

// GetLockFileModificationTime returns the modification time of the lock file of the persistent store.
func (kvs *jsonFileStore) GetLockFileModificationTime() (time.Time, error) {
kvs.Mutex.Lock()
defer kvs.Mutex.Unlock()

lockFileName := kvs.fileName + lockExtension

// Check if the file exists.
file, err := os.Open(lockFileName)
if err != nil {
return time.Time{}.UTC(), err
}

defer file.Close()

info, err := os.Stat(lockFileName)
if err != nil {
log.Printf("os.stat() for file %v failed: %v", lockFileName, err)
return time.Time{}.UTC(), err
}

return info.ModTime().UTC(), nil
}
4 changes: 2 additions & 2 deletions store/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestLockingStoreGivesExclusiveAccess(t *testing.T) {
}

// Unlock the first store.
err = kvs.Unlock()
err = kvs.Unlock(false)
if err != nil {
t.Errorf("Failed to unlock first store: %v", err)
}
Expand All @@ -198,7 +198,7 @@ func TestLockingStoreGivesExclusiveAccess(t *testing.T) {
}

// Unlock the second store.
err = kvs2.Unlock()
err = kvs2.Unlock(false)
if err != nil {
t.Errorf("Failed to unlock second store: %v", err)
}
Expand Down
3 changes: 2 additions & 1 deletion store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ type KeyValueStore interface {
Write(key string, value interface{}) error
Flush() error
Lock(block bool) error
Unlock() error
Unlock(forceUnlock bool) error
GetModificationTime() (time.Time, error)
GetLockFileModificationTime() (time.Time, error)
}

var (
Expand Down

0 comments on commit e98936c

Please sign in to comment.