2020// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121// SOFTWARE.
2222
23- package deduplicated
23+ package fulllocal
2424
2525import (
2626 "container/heap"
@@ -32,24 +32,27 @@ import (
3232 "sync"
3333)
3434
35- // ImprovedSnapshotManager manages snapshots stored on the node.
36- type ImprovedSnapshotManager struct {
35+ // FullLocalSnapshotManager manages snapshots stored on the node.
36+ type FullLocalSnapshotManager struct {
3737 sync.Mutex
38+ baseFolder string
39+
40+ // Stored snapshots
3841 snapshots map [string ]* snapshotting.Snapshot
42+ // Eviction metadata for stored snapshots
3943 snapStats map [string ]* SnapshotStats
4044
41- // Heap of snapshots not in use sorted on score
45+ // Heap of snapshots not in use that can be freed to save space. Sorted by score
4246 freeSnaps SnapHeap
43- baseFolder string
4447
4548 // Eviction
4649 clock int64 // When container last used. Increased to priority terminated container on termination
4750 capacityMib int64
4851 usedMib int64
4952}
5053
51- func NewSnapshotManager (baseFolder string , capacityMib int64 ) * ImprovedSnapshotManager {
52- manager := new (ImprovedSnapshotManager )
54+ func NewSnapshotManager (baseFolder string , capacityMib int64 ) * FullLocalSnapshotManager {
55+ manager := new (FullLocalSnapshotManager )
5356 manager .snapshots = make (map [string ]* snapshotting.Snapshot )
5457 manager .snapStats = make (map [string ]* SnapshotStats )
5558 heap .Init (& manager .freeSnaps )
@@ -67,7 +70,7 @@ func NewSnapshotManager(baseFolder string, capacityMib int64) *ImprovedSnapshotM
6770
6871// AcquireSnapshot returns a snapshot for the specified revision if it is available and increments the internal counter
6972// such that the snapshot can't get removed. Similar to how a RW lock works
70- func (mgr * ImprovedSnapshotManager ) AcquireSnapshot (revision string ) (* snapshotting.Snapshot , error ) {
73+ func (mgr * FullLocalSnapshotManager ) AcquireSnapshot (revision string ) (* snapshotting.Snapshot , error ) {
7174 mgr .Lock ()
7275 defer mgr .Unlock ()
7376
@@ -105,7 +108,7 @@ func (mgr *ImprovedSnapshotManager) AcquireSnapshot(revision string) (*snapshott
105108
106109// ReleaseSnapshot releases the snapshot with the given revision so that it can possibly get deleted if it is not in use
107110// by any other VMs.
108- func (mgr * ImprovedSnapshotManager ) ReleaseSnapshot (revision string ) error {
111+ func (mgr * FullLocalSnapshotManager ) ReleaseSnapshot (revision string ) error {
109112 mgr .Lock ()
110113 defer mgr .Unlock ()
111114
@@ -114,6 +117,10 @@ func (mgr *ImprovedSnapshotManager) ReleaseSnapshot(revision string) error {
114117 return errors .New (fmt .Sprintf ("Get: Snapshot for revision %s does not exist" , revision ))
115118 }
116119
120+ if snapStat .numUsing == 0 {
121+ return errors .New ("Can't release a snapshot that is not in use" )
122+ }
123+
117124 snapStat .numUsing -= 1
118125
119126 if snapStat .numUsing == 0 {
@@ -125,9 +132,9 @@ func (mgr *ImprovedSnapshotManager) ReleaseSnapshot(revision string) error {
125132 return nil
126133}
127134
128- // InitSnapshot initializes a snapshot by adding its metadata to the ImprovedSnapshotManager . Once the snapshot has been created,
135+ // InitSnapshot initializes a snapshot by adding its metadata to the FullLocalSnapshotManager . Once the snapshot has been created,
129136// CommitSnapshot must be run to finalize the snapshot creation and make the snapshot available fo ruse
130- func (mgr * ImprovedSnapshotManager ) InitSnapshot (revision , image string , coldStartTimeMs int64 , memSizeMib , vCPUCount uint32 , sparse bool ) (* []string , * snapshotting.Snapshot , error ) {
137+ func (mgr * FullLocalSnapshotManager ) InitSnapshot (revision , image string , coldStartTimeMs int64 , memSizeMib , vCPUCount uint32 , sparse bool ) (* []string , * snapshotting.Snapshot , error ) {
131138 mgr .Lock ()
132139
133140 if _ , present := mgr .snapshots [revision ]; present {
@@ -172,13 +179,19 @@ func (mgr *ImprovedSnapshotManager) InitSnapshot(revision, image string, coldSta
172179}
173180
174181// CommitSnapshot finalizes the snapshot creation and makes it available for use.
175- func (mgr * ImprovedSnapshotManager ) CommitSnapshot (revision string ) error {
182+ func (mgr * FullLocalSnapshotManager ) CommitSnapshot (revision string ) error {
176183 mgr .Lock ()
177184 snapStat , present := mgr .snapStats [revision ]
178185 if ! present {
179186 mgr .Unlock ()
180187 return errors .New (fmt .Sprintf ("Snapshot for revision %s to commit does not exist" , revision ))
181188 }
189+
190+ if snapStat .usable {
191+ mgr .Unlock ()
192+ return errors .New (fmt .Sprintf ("Snapshot for revision %s has already been committed" , revision ))
193+ }
194+
182195 snap := mgr .snapshots [revision ]
183196 mgr .Unlock ()
184197
@@ -201,7 +214,7 @@ func (mgr *ImprovedSnapshotManager) CommitSnapshot(revision string) error {
201214
202215// freeSpace makes sure neededMib of disk space is available by removing unused snapshots. Make sure to have a lock
203216// when calling this function.
204- func (mgr * ImprovedSnapshotManager ) freeSpace (neededMib int64 ) (* []string , error ) {
217+ func (mgr * FullLocalSnapshotManager ) freeSpace (neededMib int64 ) (* []string , error ) {
205218 var toDelete []string
206219 var freedMib int64 = 0
207220 var removeContainerSnaps []string
@@ -213,7 +226,7 @@ func (mgr *ImprovedSnapshotManager) freeSpace(neededMib int64) (*[]string, error
213226 toDelete = append (toDelete , snapStat .revisionId )
214227
215228 snap := mgr .snapshots [snapStat .revisionId ]
216- removeContainerSnaps = append (removeContainerSnaps , snap .ContainerSnapName )
229+ removeContainerSnaps = append (removeContainerSnaps , snap .GetContainerSnapName () )
217230 freedMib += snapStat .TotalSizeMiB
218231 }
219232
0 commit comments