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

overlord,systemd: do not restart mount units on snapd start #13685

Conversation

alfonsosanchezbeato
Copy link
Member

@alfonsosanchezbeato alfonsosanchezbeato commented Mar 11, 2024

Do not restart the mount units when starting snapd even if the file
itself has been modified. This is to prevent systemd stopping services
when the mount unit gets restarted, as there are required dependencies
in the mount path for services defined in snaps.

@alfonsosanchezbeato alfonsosanchezbeato added the Run nested The PR also runs tests inluded in nested suite label Mar 11, 2024
@alfonsosanchezbeato alfonsosanchezbeato added this to the 2.62 milestone Mar 11, 2024
@alfonsosanchezbeato alfonsosanchezbeato changed the title overlord,systemd: do not restart snapd snap mount units on start overlord,systemd: do not restart mount units on snapd start Mar 12, 2024
@pedronis pedronis added the ⚠ Critical High-priority stuff (e.g. to fix master) label Mar 12, 2024
Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

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

thanks, so this is beyond just snapd itself, as we turn off restarting of all mounts in snapmgr?

@@ -1160,7 +1160,7 @@ func (s *SystemdTestSuite) TestAddMountUnit(c *C) {
mockSnapPath := filepath.Join(c.MkDir(), "/var/lib/snappy/snaps/foo_1.0.snap")
makeMockFile(c, mockSnapPath)

mountUnitName, err := NewUnderRoot(rootDir, SystemMode, nil).EnsureMountUnitFile("Mount unit for foo, revision 42", mockSnapPath, "/snap/snapname/123", "squashfs")
mountUnitName, err := NewUnderRoot(rootDir, SystemMode, nil).EnsureMountUnitFile("Mount unit for foo, revision 42", mockSnapPath, "/snap/snapname/123", "squashfs", &systemd.EnsureMountUnitFlags{})
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we want to add a test with IgnoreModified: true here as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added now (see testEnsureMountUnitChanged)

Copy link
Contributor

@valentindavid valentindavid left a comment

Choose a reason for hiding this comment

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

Looks good. I have left some comments more for discussion. I think the PR is fine to merge if the tests pass.

@@ -323,6 +323,9 @@ type MountUnitOptions struct {
Fstype string
Options []string
Origin string
// IgnoreModified is set if we do not want to restart the
// mount unit if modified
IgnoreModified bool
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure this is obvious from the name. Maybe PreventRestartModified?

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed

@@ -1508,19 +1518,20 @@ func hostFsTypeAndMountOptions(fstype string) (hostFsType string, options []stri
return hostFsType, options
}

func (s *systemd) EnsureMountUnitFile(description, what, where, fstype string) (string, error) {
func (s *systemd) EnsureMountUnitFile(description, what, where, fstype string, flags *EnsureMountUnitFlags) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should just not use this function when we need to set the flag, but use EnsureMountUnitFileWithOptions.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought about that, but hostFsTypeAndMountOptions would need to be public as well or build fstype/options slightly differently. Maybe something to consider in the future, I've added a TODO about this now.

return "", err

// If just modified, some times it is not convenient to restart
if modified != mountUpdated || !unitOptions.IgnoreModified {
Copy link
Contributor

Choose a reason for hiding this comment

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

In the else case, we could make a reload. I think that will safely change the options if they changed with a -o remount.

Copy link
Member Author

Choose a reason for hiding this comment

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

Isn't the previous call to daemon-reload already reloading the unit configuration? Afaiu, reload-or-restart would only run anything under ExecReload= in the unit if present, or restart otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

daemon-reload does not do the remount. Maybe it is not well documented in systemd, but the mount unit has a reload. See https://github.com/systemd/systemd/blob/7b44a24c1bc764b5c0555fed08911665e1e7d446/src/core/mount.c#L2437

That calls in the end mount_enter_remounting https://github.com/systemd/systemd/blob/7b44a24c1bc764b5c0555fed08911665e1e7d446/src/core/mount.c#L1228

Which will use -o remount.

That said, -o remount does not support all changes. For example, you cannot change the device.

Comment on lines 1298 to 1309
// Ensure mount files, but do not restart mount units
// of snap files if the units are modified as services
// in the snap have a Requires= on them. Otherwise the
// services would be restarted.
if _, err = sysd.EnsureMountUnitFile(info.MountDescription(),
squashfsPath, whereDir, "squashfs",
&systemd.EnsureMountUnitFlags{IgnoreModified: true}); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I see you decided not to restart any mount units not just snapd. I think this is fine. Could you add in the comment, that if we decided to revert that we should never restart the mount for snapd otherwise snapd will kill itself on first start after an update?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added an additional comment about snapd

Copy link
Member Author

@alfonsosanchezbeato alfonsosanchezbeato left a comment

Choose a reason for hiding this comment

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

Thanks for the reviews, I've answered the comments and squashed the commits.

Comment on lines 1298 to 1309
// Ensure mount files, but do not restart mount units
// of snap files if the units are modified as services
// in the snap have a Requires= on them. Otherwise the
// services would be restarted.
if _, err = sysd.EnsureMountUnitFile(info.MountDescription(),
squashfsPath, whereDir, "squashfs",
&systemd.EnsureMountUnitFlags{IgnoreModified: true}); err != nil {
return err
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Added an additional comment about snapd

@@ -323,6 +323,9 @@ type MountUnitOptions struct {
Fstype string
Options []string
Origin string
// IgnoreModified is set if we do not want to restart the
// mount unit if modified
IgnoreModified bool
Copy link
Member Author

Choose a reason for hiding this comment

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

Changed

return "", err

// If just modified, some times it is not convenient to restart
if modified != mountUpdated || !unitOptions.IgnoreModified {
Copy link
Member Author

Choose a reason for hiding this comment

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

Isn't the previous call to daemon-reload already reloading the unit configuration? Afaiu, reload-or-restart would only run anything under ExecReload= in the unit if present, or restart otherwise.

@@ -1508,19 +1518,20 @@ func hostFsTypeAndMountOptions(fstype string) (hostFsType string, options []stri
return hostFsType, options
}

func (s *systemd) EnsureMountUnitFile(description, what, where, fstype string) (string, error) {
func (s *systemd) EnsureMountUnitFile(description, what, where, fstype string, flags *EnsureMountUnitFlags) (string, error) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I thought about that, but hostFsTypeAndMountOptions would need to be public as well or build fstype/options slightly differently. Maybe something to consider in the future, I've added a TODO about this now.

@codecov-commenter
Copy link

codecov-commenter commented Mar 12, 2024

Codecov Report

Attention: Patch coverage is 87.87879% with 4 lines in your changes are missing coverage. Please review.

Project coverage is 78.89%. Comparing base (81d3d51) to head (2fad2d1).
Report is 7 commits behind head on master.

Files Patch % Lines
systemd/systemd.go 76.92% 2 Missing and 1 partial ⚠️
overlord/snapstate/snapmgr.go 90.00% 0 Missing and 1 partial ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #13685   +/-   ##
=======================================
  Coverage   78.89%   78.89%           
=======================================
  Files        1040     1040           
  Lines      133862   133876   +14     
=======================================
+ Hits       105610   105624   +14     
- Misses      21658    21659    +1     
+ Partials     6594     6593    -1     
Flag Coverage Δ
unittests 78.89% <87.87%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM with one comment about passing flags by value and one comment about wording of the documentation.

@@ -124,20 +124,21 @@ func (s *emulation) LogReader(services []string, n int, follow, namespaces bool)
return nil, fmt.Errorf("LogReader")
}

func (s *emulation) EnsureMountUnitFile(description, what, where, fstype string) (string, error) {
func (s *emulation) EnsureMountUnitFile(description, what, where, fstype string, flags *EnsureMountUnitFlags) (string, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Passing EnsureMountUnitFlags by value is probably better here. It's less worrying about escape analysis to optimize this away, less chance of a nil pointer.

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed now

// remove this type instead?
type EnsureMountUnitFlags struct {
// PreventRestartIfModified is set if we do not want to restart the
// mount unit if modified
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// mount unit if modified
// mount unit even thought it has been modified.```

Do not restart the mount units when starting snapd even if the file
itself has been modified. This is to prevent systemd stopping services
when the mount unit gets restarted, as there are required dependencies
in the mount path for services defined in snaps.
related to remounting units for installed snaps if we have new options
set in snapd.
@alfonsosanchezbeato alfonsosanchezbeato merged commit 253256f into snapcore:master Mar 13, 2024
38 of 44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚠ Critical High-priority stuff (e.g. to fix master) Run nested The PR also runs tests inluded in nested suite
Projects
None yet
5 participants