Skip to content
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

CSI: set mounts in alloc hook resources atomically #16722

Merged
merged 2 commits into from
Apr 3, 2023
Merged

Conversation

tgross
Copy link
Member

@tgross tgross commented Mar 29, 2023

Fixes #16623

The allocrunner has a facility for passing data written by allocrunner hooks to taskrunner hooks. Currently the only consumers of this facility are the allocrunner CSI hook (which writes data) and the taskrunner volume hook (which reads that same data).

The allocrunner hook for CSI volumes doesn't set the alloc hook resources atomically. Instead, it gets the current resources and then writes a new version back. Because the CSI hook is currently the only writer and all readers happen long afterwards, this should be safe but #16623 shows there's some sequence of events during restore where this breaks down.

Refactor hook resources so that hook data is accessed via setters and getters that hold the mutex, and ensure the object is instantiated synchronously at the time the AllocRunner is created.


Note to reviewers: the reproduction for the crash is extremely complicated and timing dependent, so we're not going to be able to test this in a unit test. See my comment at #16623 (comment) for how this has been manually tested. There's some follow-up work we're going to need to do in #16746

The allocrunner has a facility for passing data written by allocrunner hooks to
taskrunner hooks. Currently the only consumers of this facility are the
allocrunner CSI hook (which writes data) and the taskrunner volume hook (which
reads that same data).

The allocrunner hook for CSI volumes doesn't set the alloc hook resources
atomically. Instead, it gets the current resources and then writes a new version
back. Because the CSI hook is currently the only writer and all readers happen
long afterwards, this should be safe but #16623 shows there's some sequence of
events during restore where this breaks down.

Refactor hook resources so that hook data is accessed via setters and getters
that hold the mutex.
Copy link
Member

@shoenig shoenig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! much easier to follow.

Comment on lines 25 to 30
func (a *AllocHookResources) GetCSIMounts() map[string]*csimanager.MountInfo {
a.mu.RLock()
defer a.mu.RUnlock()

return a.CSIMounts
return a.csiMounts
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the policy on modifying this map? Maybe add a comment here on what is expected of callers, or return a copy.

Copy link
Member Author

@tgross tgross Apr 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. It's probably safe to "guard" this with a comment because the volume hook is just reading that data and not writing it, but it's way too easy to break later unexpectedly. Returning a copy in a9b2ac8

@tgross
Copy link
Member Author

tgross commented Apr 3, 2023

This will go out in the next regular patch release.

tgross added a commit that referenced this pull request Apr 3, 2023
The allocrunner has a facility for passing data written by allocrunner hooks to
taskrunner hooks. Currently the only consumers of this facility are the
allocrunner CSI hook (which writes data) and the taskrunner volume hook (which
reads that same data).

The allocrunner hook for CSI volumes doesn't set the alloc hook resources
atomically. Instead, it gets the current resources and then writes a new version
back. Because the CSI hook is currently the only writer and all readers happen
long afterwards, this should be safe but #16623 shows there's some sequence of
events during restore where this breaks down.

Refactor hook resources so that hook data is accessed via setters and getters
that hold the mutex.
tgross added a commit that referenced this pull request Apr 3, 2023
The allocrunner has a facility for passing data written by allocrunner hooks to
taskrunner hooks. Currently the only consumers of this facility are the
allocrunner CSI hook (which writes data) and the taskrunner volume hook (which
reads that same data).

The allocrunner hook for CSI volumes doesn't set the alloc hook resources
atomically. Instead, it gets the current resources and then writes a new version
back. Because the CSI hook is currently the only writer and all readers happen
long afterwards, this should be safe but #16623 shows there's some sequence of
events during restore where this breaks down.

Refactor hook resources so that hook data is accessed via setters and getters
that hold the mutex.

Co-authored-by: Tim Gross <tgross@hashicorp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/1.3.x backport to 1.3.x release line backport/1.4.x backport to 1.4.x release line backport/1.5.x backport to 1.5.x release line theme/storage type/bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nomad v1.5.2 panics with a segmentation violation
2 participants