-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add support for mounting volumes with local driver and options #3931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for mounting volumes with local driver and options #3931
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mheon The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
@rhatdan PTAL - you said this was blocking your work on overlay volumes |
|
I think not, but thought I'd ask. Any anticipated db upgrade issues? |
|
The first commit should address most of them. The bigger issue was the locks PR that went in earlier - we'll need a |
|
Thanks @mheon. A quick browse and the code LGTM. The |
libpod/boltdb_state.go
Outdated
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.
any reason not to volStateJSON, err = json.Marshal?
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 think json.Marshal on a nil pointer makes angry errors
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.
Oh wait, i see what you're saying. Probably will work.
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.
This only works when changing the short decl := to an assignment =. Using the short decl := any variable on the left will be created unless already being declared in the same scope. Since volStateJSON is declared in an outer scope, it won't work unless we declare err before and change it to an assignment.
|
lgtm other than nit question ... have you measured any perf impact to overall container running with this? |
|
Should be 0 on containers that do not mount shared volumes. On those with volumes requiring a full mount call, on first mount, it's pretty substantial - around 1s extra for a tmpfs, in my measurements. This about matches what I saw with Docker, though - was how I figured out they had to be doing the mount on container launch. |
vrothberg
left a comment
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.
Nice work, @mheon. Just a couple of nits.
I looked into the man pages and noticed that there's no information about supported drivers. The only information I found is that the default is local.
pkg/varlinkapi/volumes.go
Outdated
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 could use define.ErrNotImplemented.Error() here.
libpod/volume_internal.go
Outdated
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.
Can we use a constant instead of "local"?
libpod/volume.go
Outdated
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.
Why are we changing the identifiers of the options and the driver? Prefixing with volume feels redundant since it's a VolumeConfig.
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 need to discard anything already in the database. Previously we were doing absolutely no validation on these fields - now we're properly vetting their contents. We can't go back and make previous containers safe, so the next best option is to ignore them (they were all acting like volumes without options prior to this PR anyways)
libpod/boltdb_state.go
Outdated
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.
This only works when changing the short decl := to an assignment =. Using the short decl := any variable on the left will be created unless already being declared in the same scope. Since volStateJSON is declared in an outer scope, it won't work unless we declare err before and change it to an assignment.
libpod/container_internal.go
Outdated
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 we move it down a few lines, we can spare the defer and save a few cycles.
libpod/runtime_volume_linux.go
Outdated
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.
Same here: can we use a constant for "local"?
libpod/volume_internal_linux.go
Outdated
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.
"error getting ..."?
libpod/volume_internal_linux.go
Outdated
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'd prefer calling the syscall directly. I am no mount expert, so I may be totally unaware of the difficulties.
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.
My initial attempt tried that, but I abandoned it pretty quickly due to difficulties syncing up the defaults. Docker allows semi-arbitrary options to be passed, does almost no authentication, and pops them straight into a call to mount. We would need to reverse-engineer somewhat large tracts of the functionality of Coreutils mount to make this work properly without it.
pkg/varlinkapi/volumes.go
Outdated
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.
Don't we need the options as well?
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.
Oh, oops, that one's a mistake, reverting
|
I would like to see @vrothberg questions addressed, as well as squash the PRs, and add some tests. Examples in man pages would also be nice. Looks very good. |
4267b38 to
29941a9
Compare
|
Addressed review comments |
|
@mheon can you squash your commits. |
|
Sure |
f177d64 to
5b150b6
Compare
In upcoming commits, we're going to turn on the backends for these fields. Volumes with these set will act fundamentally differently from other volumes. There will probably be validation required for each field. Until now, though, we've freely allowed creation of volumes with these set - they just did nothing. So we have no idea what could be in the DB with old volumes. Change the struct tags so we don't have to worry about old, unvalidated data. We'll start fresh with new volumes. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
We need to be able to track the number of times a volume has been mounted for tmpfs/nfs/etc volumes. As such, we need a mutable state for volumes. Add one, with the expected update/save methods in both states. There is backwards compat here, in that older volumes without a state will still be accepted. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
cc80069 to
f6ca089
Compare
|
Added tests |
7c7e94e to
d168f57
Compare
|
Assuming things go green, I think we're good for final review and merge |
d168f57 to
f24fa83
Compare
|
/retest |
cfdd268 to
951ecb3
Compare
When volume options and the local volume driver are specified, the volume is intended to be mounted using the 'mount' command. Supported options will be used to volume the volume before the first container using it starts, and unmount the volume after the last container using it dies. This should work for any local filesystem, though at present I've only tested with tmpfs and btrfs. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
When we fail to remove a container's SHM, that's an error, and we need to report it as such. This may be part of our lingering storage woes. Also, remove MNT_DETACH. It may be another cause of the storage removal failures. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
951ecb3 to
de9a394
Compare
|
Going green. @rhatdan @baude @vrothberg @TomSweeneyRedHat @giuseppe PTAL |
vrothberg
left a comment
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.
LGTM
|
/lgtm |
Volumes with the
localdriver and mount options specified are mounted using themountcommand, instead of being plain directories. The volumes are mounted as the first container using them is started, and unmounted when the last container using them exits.Given the mount/unmount behavior, we need to add a mount counter to volumes to know when to mount/unmount. This requires adding a mutable state to volumes, with associated methods in the DB to update and save the state.
Missing tests right now, but I've tested locally with tmpfs and btrfs with positive results.