Skip to content

Commit f17e20a

Browse files
committed
Updated network and address managers to ignore stale persisted state from previous boots
1 parent 86e45b8 commit f17e20a

File tree

5 files changed

+74
-3
lines changed

5 files changed

+74
-3
lines changed

common/utils.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io/ioutil"
88
"net"
99
"os/exec"
10+
"time"
1011

1112
"github.com/Azure/azure-container-networking/log"
1213
)
@@ -35,6 +36,26 @@ func LogNetworkInterfaces() {
3536
}
3637
}
3738

39+
// GetLastRebootTime returns the last time the system rebooted.
40+
func GetLastRebootTime() (time.Time, error) {
41+
// Query last reboot time.
42+
out, err := exec.Command("uptime", "-s").Output()
43+
if err != nil {
44+
log.Printf("Failed to query uptime, err:%v", err)
45+
return time.Time{}, err
46+
}
47+
48+
// Parse the output.
49+
layout := "2006-01-02 15:04:05"
50+
rebootTime, err := time.Parse(layout, string(out[:len(out)-1]))
51+
if err != nil {
52+
log.Printf("Failed to parse uptime, err:%v", err)
53+
return time.Time{}, err
54+
}
55+
56+
return rebootTime, nil
57+
}
58+
3859
// ExecuteShellCommand executes a shell command.
3960
func ExecuteShellCommand(command string) error {
4061
log.Debugf("[shell] %s", command)

ipam/manager.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ipam
55

66
import (
77
"sync"
8+
"time"
89

910
"github.com/Azure/azure-container-networking/common"
1011
"github.com/Azure/azure-container-networking/log"
@@ -19,6 +20,8 @@ const (
1920

2021
// AddressManager manages the set of address spaces and pools allocated to containers.
2122
type addressManager struct {
23+
Version string
24+
TimeStamp time.Time
2225
AddrSpaces map[string]*addressSpace `json:"AddressSpaces"`
2326
store store.KeyValueStore
2427
source addressConfigSource
@@ -64,6 +67,7 @@ func NewAddressManager() (AddressManager, error) {
6467

6568
// Initialize configures address manager.
6669
func (am *addressManager) Initialize(config *common.PluginConfig, options map[string]interface{}) error {
70+
am.Version = config.Version
6771
am.store = config.Store
6872
am.netApi, _ = config.NetApi.(network.NetworkManager)
6973

@@ -91,8 +95,20 @@ func (am *addressManager) restore() error {
9195
return nil
9296
}
9397

98+
// After a reboot, all address resources are implicitly released.
99+
// Ignore the persisted state if it is older than the last reboot time.
100+
modTime, err := am.store.GetModificationTime()
101+
if err == nil {
102+
rebootTime, err := common.GetLastRebootTime()
103+
if err == nil && rebootTime.After(modTime) {
104+
log.Printf("[ipam] Ignoring stale state from store.")
105+
log.Printf("[ipam] Store timestamp %v is older than boot timestamp %v.", modTime, rebootTime)
106+
return nil
107+
}
108+
}
109+
94110
// Read any persisted state.
95-
err := am.store.Read(storeKey, am)
111+
err = am.store.Read(storeKey, am)
96112
if err != nil {
97113
if err == store.ErrKeyNotFound {
98114
return nil
@@ -121,6 +137,9 @@ func (am *addressManager) save() error {
121137
return nil
122138
}
123139

140+
// Update time stamp.
141+
am.TimeStamp = time.Now()
142+
124143
err := am.store.Write(storeKey, am)
125144
if err == nil {
126145
log.Printf("[ipam] Save succeeded.\n")

network/manager.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package network
55

66
import (
77
"sync"
8+
"time"
89

910
"github.com/Azure/azure-container-networking/common"
1011
"github.com/Azure/azure-container-networking/log"
@@ -18,6 +19,8 @@ const (
1819

1920
// NetworkManager manages the set of container networking resources.
2021
type networkManager struct {
22+
Version string
23+
TimeStamp time.Time
2124
ExternalInterfaces map[string]*externalInterface
2225
store store.KeyValueStore
2326
sync.Mutex
@@ -52,6 +55,7 @@ func NewNetworkManager() (NetworkManager, error) {
5255

5356
// Initialize configures network manager.
5457
func (nm *networkManager) Initialize(config *common.PluginConfig) error {
58+
nm.Version = config.Version
5559
nm.store = config.Store
5660

5761
// Restore persisted state.
@@ -70,8 +74,20 @@ func (nm *networkManager) restore() error {
7074
return nil
7175
}
7276

77+
// After a reboot, all address resources are implicitly released.
78+
// Ignore the persisted state if it is older than the last reboot time.
79+
modTime, err := nm.store.GetModificationTime()
80+
if err == nil {
81+
rebootTime, err := common.GetLastRebootTime()
82+
if err == nil && rebootTime.After(modTime) {
83+
log.Printf("[net] Ignoring stale state from store.")
84+
log.Printf("[net] Store timestamp %v is older than boot timestamp %v.", modTime, rebootTime)
85+
return nil
86+
}
87+
}
88+
7389
// Read any persisted state.
74-
err := nm.store.Read(storeKey, nm)
90+
err = nm.store.Read(storeKey, nm)
7591
if err != nil {
7692
if err == store.ErrKeyNotFound {
7793
// Considered successful.
@@ -101,6 +117,9 @@ func (nm *networkManager) save() error {
101117
return nil
102118
}
103119

120+
// Update time stamp.
121+
nm.TimeStamp = time.Now()
122+
104123
err := nm.store.Write(storeKey, nm)
105124
if err == nil {
106125
log.Printf("[net] Save succeeded.\n")

store/json.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func (kvs *jsonFileStore) Write(key string, value interface{}) error {
102102
return kvs.flush()
103103
}
104104

105-
// Flush commits in-memory state to backing store.
105+
// Flush commits in-memory state to persistent store.
106106
func (kvs *jsonFileStore) Flush() error {
107107
kvs.Mutex.Lock()
108108
defer kvs.Mutex.Unlock()
@@ -193,3 +193,13 @@ func (kvs *jsonFileStore) Unlock() error {
193193

194194
return nil
195195
}
196+
197+
// GetModificationTime returns the modification time of the persistent store.
198+
func (kvs *jsonFileStore) GetModificationTime() (time.Time, error) {
199+
info, err := os.Stat(kvs.fileName)
200+
if err != nil {
201+
return time.Time{}, err
202+
}
203+
204+
return info.ModTime(), nil
205+
}

store/store.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package store
55

66
import (
77
"fmt"
8+
"time"
89
)
910

1011
// KeyValueStore represents a persistent store of (key,value) pairs.
@@ -14,6 +15,7 @@ type KeyValueStore interface {
1415
Flush() error
1516
Lock(block bool) error
1617
Unlock() error
18+
GetModificationTime() (time.Time, error)
1719
}
1820

1921
var (

0 commit comments

Comments
 (0)