Skip to content

Commit

Permalink
many: add ephemeral-mount-namespace feature
Browse files Browse the repository at this point in the history
When the feature is enabled no mount namespace persistence is attempted.
This is done in response to problematic behavior of ongoing updates,
even under a frozen control group.

This change is disruptive and does not account for tests that currently
observe this behavior.

Signed-off-by: Zygmunt Krynicki <[email protected]>
  • Loading branch information
zyga committed Nov 14, 2024
1 parent e716737 commit db936ed
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 2 deletions.
3 changes: 3 additions & 0 deletions cmd/libsnap-confine-private/feature.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ bool sc_feature_enabled(sc_feature_flag flag)
case SC_FEATURE_HIDDEN_SNAP_FOLDER:
file_name = "hidden-snap-folder";
break;
case SC_FEATURE_EPHEMERAL_MOUNT_NAMESPACE:
file_name = "ephemeral-mount-namespace";
break;
default:
die("unknown feature flag code %d", flag);
}
Expand Down
1 change: 1 addition & 0 deletions cmd/libsnap-confine-private/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ typedef enum sc_feature_flag {
SC_FEATURE_REFRESH_APP_AWARENESS = 1 << 1,
SC_FEATURE_PARALLEL_INSTANCES = 1 << 2,
SC_FEATURE_HIDDEN_SNAP_FOLDER = 1 << 3,
SC_FEATURE_EPHEMERAL_MOUNT_NAMESPACE = 1 << 4,
} sc_feature_flag;

/**
Expand Down
11 changes: 9 additions & 2 deletions cmd/snap-confine/snap-confine.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,13 @@ static void enter_non_classic_execution_environment(sc_invocation *inv,
sc_store_ns_info(inv);

/* Preserve the mount namespace. */
sc_preserve_populated_mount_ns(group);
if (!sc_feature_enabled
(SC_FEATURE_EPHEMERAL_MOUNT_NAMESPACE)) {
sc_preserve_populated_mount_ns(group);
} else {
debug
("NOT preserving per-snap mount namespace");
}
}

/* Older versions of snap-confine created incorrect 777 permissions
Expand Down Expand Up @@ -850,7 +856,8 @@ static void enter_non_classic_execution_environment(sc_invocation *inv,
* sc_join_preserved_user_ns() will never find a preserved mount
* namespace and will always enter this code branch. */
if (sc_feature_enabled
(SC_FEATURE_PER_USER_MOUNT_NAMESPACE)) {
(SC_FEATURE_PER_USER_MOUNT_NAMESPACE) &&
!sc_feature_enabled(SC_FEATURE_EPHEMERAL_MOUNT_NAMESPACE)) {
sc_preserve_populated_per_user_mount_ns(group);
} else {
debug
Expand Down
6 changes: 6 additions & 0 deletions features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ const (
Registries
// AppArmorPrompting enables AppArmor to prompt the user for permission when apps perform certain operations.
AppArmorPrompting
// EphemeralMountNamespace enables non-persistent mount namespaces.
EphemeralMountNamespace

// lastFeature is the final known feature, it is only used for testing.
lastFeature
Expand Down Expand Up @@ -126,6 +128,8 @@ var featureNames = map[SnapdFeature]string{
Registries: "registries",

AppArmorPrompting: "apparmor-prompting",

EphemeralMountNamespace: "ephemeral-mount-namespace",
}

// featuresEnabledWhenUnset contains a set of features that are enabled when not explicitly configured.
Expand All @@ -151,6 +155,8 @@ var featuresExported = map[SnapdFeature]bool{
RefreshAppAwarenessUX: true,
Registries: true,
AppArmorPrompting: true,

EphemeralMountNamespace: true,
}

var (
Expand Down
4 changes: 4 additions & 0 deletions features/features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (*featureSuite) TestName(c *C) {
check(features.RefreshAppAwarenessUX, "refresh-app-awareness-ux")
check(features.Registries, "registries")
check(features.AppArmorPrompting, "apparmor-prompting")
check(features.EphemeralMountNamespace, "ephemeral-mount-namespace")

c.Check(tested, Equals, features.NumberOfFeatures())
c.Check(func() { _ = features.SnapdFeature(1000).String() }, PanicMatches, "unknown feature flag code 1000")
Expand Down Expand Up @@ -107,6 +108,7 @@ func (*featureSuite) TestIsExported(c *C) {
check(features.RefreshAppAwarenessUX, true)
check(features.Registries, true)
check(features.AppArmorPrompting, true)
check(features.EphemeralMountNamespace, true)

c.Check(tested, Equals, features.NumberOfFeatures())
}
Expand Down Expand Up @@ -233,6 +235,7 @@ func (*featureSuite) TestIsEnabledWhenUnset(c *C) {
check(features.RefreshAppAwarenessUX, false)
check(features.Registries, false)
check(features.AppArmorPrompting, false)
check(features.EphemeralMountNamespace, false)

c.Check(tested, Equals, features.NumberOfFeatures())
}
Expand All @@ -247,6 +250,7 @@ func (*featureSuite) TestControlFile(c *C) {
c.Check(features.RefreshAppAwarenessUX.ControlFile(), Equals, "/var/lib/snapd/features/refresh-app-awareness-ux")
c.Check(features.Registries.ControlFile(), Equals, "/var/lib/snapd/features/registries")
c.Check(features.AppArmorPrompting.ControlFile(), Equals, "/var/lib/snapd/features/apparmor-prompting")
c.Check(features.EphemeralMountNamespace.ControlFile(), Equals, "/var/lib/snapd/features/ephemeral-mount-namespace")
// Features that are not exported don't have a control file.
c.Check(features.Layouts.ControlFile, PanicMatches, `cannot compute the control file of feature "layouts" because that feature is not exported`)
}
Expand Down

0 comments on commit db936ed

Please sign in to comment.