GC: always detect and unmount leftovers #1856
Conversation
stage1TreeStoreID, err := p.getStage1TreeStoreID() | ||
if err != nil { | ||
stderr("error getting stage1 treeStoreID: %v", err) | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to resist this error too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, if we can't get the treeStoreID
we should still be able to force-GC the pod.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. PR updated
} | ||
|
||
// unmount all leftover mounts | ||
stdout("GC of leftover mounts for pod %q...", p.uuid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to output this every time? Just an implementation detail, IMHO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need this stdout, I think the previous stdout in emptyExitedGarbage() was enough.
I would like to validate that the shared mounts and then make-rprivate+umount works in practice when there are several pods.
|
The reason I am asking these two tests is because I think the number of mounts will increase exponentially with the number of pods (or Fibonacci? I am not sure):
If it is indeed the case, then I think we should check @philips ' suggestion with |
The number of mount points seems to grow quickly, from my test script:
|
@alban The user provided volumes are mounted with just This is not only a problem of scaling but also of containers blocking each other in GC. I've solved this problem by unmounting all instances of a pod's rootfs, also if they live in a different pod's rootfs due to recursive mounts. I've left this code in even though we don't use recursive binds now, since we might provide the option to configure this per mount and will need it then. |
stderr("Skipping stage1 GC") | ||
} else { | ||
stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID) | ||
if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err is a shadowed variable. When you enable go vet --shadow, it will compliant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Should we enable the --shadow
flag in our testscript?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know.
I thought that shadowing with if err := ...; err != nil {
was idiomatic in Golang.
It would be better to add that code when we actually need it because we are not sure it's going to be added. |
} | ||
|
||
// unmount all leftover mounts | ||
if err := stage0.ForceMountGC(p.path(), p.uuid.String()); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: rename function to stage0.MountGC()
.
} | ||
|
||
if strings.HasPrefix(mountPoint, path) { | ||
for i, s := range lineResult { | ||
s := s[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use strings.Split, no need to do this s := s[0]
.
Since it does not use recursive binds, this branch could be simplified: no need to complicate the parsing of |
Assuming it is the stage1 that may still construct recursive bind mounts which we need to detect properly to be able to clean it up. WRT the stage1 fly this is needed for the recursive mounts for |
mode string | ||
) | ||
|
||
// lineRegex := regexp.MustCompile(`[^ ]+`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leftover?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If strings.Split
works, you can remove this comment :)
A rebase would be good for the next iteration :) |
This is for unmounting recursive bind-mounts, as well as the overlay mounts. It also has the advantage of not attempting to unmount something that is not there, e.g. if a reboot happened and the mounts are gone anyway.
I think it looks good! @krnowak are you still reviewing it or is it good to you too? |
No no, I'm done with it. LFAD if green. |
GC: always detect and unmount leftovers
👍 |
This covers unmounting of recursive bind-mounts, as well as the overlay mounts.
It also has the advantage of not attempting to unmount something that is
not there, e.g. if a reboot happened and the mounts are gone anyway.