Skip to content

Conversation

@pranav767
Copy link
Contributor

This PR closes #12308

What? (description)

  • Add support for adding extra mount options for volumes.

Why? (reasoning)

Acceptance

Please use the following checklist:

  • you linked an issue (if applicable)
  • you included tests (if applicable)
  • you ran conformance (make conformance)
  • you formatted your code (make fmt)
  • you linted your code (make lint)
  • you generated documentation (make docs)
  • you ran unit-tests (make unit-tests)

See make help for a description of the available targets.

@github-project-automation github-project-automation bot moved this to To Do in Planning Jan 13, 2026
@talos-bot talos-bot moved this from To Do to In Review in Planning Jan 13, 2026
MountReadOnly *bool `yaml:"readOnly,omitempty"`
// description: |
// Additional mount options to pass to the mount syscall.
//
Copy link
Contributor Author

@pranav767 pranav767 Jan 13, 2026

Choose a reason for hiding this comment

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

I’ve kept this mount option flexible to allow both boolean flags and key–value pairs (where key–value pairs are expressed as key=value), representing key–value pairs as plain strings feels a bit off—please let me know if there’s a better way to model this.
This will look like

mount:
  readOnly: false
  options:
    - noatime        # boolean flag
    - nodiratime     # boolean flag
    - nosuid         # boolean flag
    - nodev          # boolean flag
    - uid=1000       # key=value
    - gid=1000       # key=value
    - size=100m      # filesystem-specific key=value (e.g., tmpfs)

Copy link
Member

Choose a reason for hiding this comment

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

We had an internal discussion about this, and the consensus was that we are not happy with a free-form field.

We were considering the following (probably separate) fields, we don't have good names for them, but:

  • DisableAccessTime (defaults to false) -> triggers proper no*atime based on filesystem type
  • Secure (defaults to true, breaking change) -> triggers nosuid, nodev (if the filesystems supports it), and it should be explicitly set to false (breaking change for 1.13, but in the direction of better security)
  • uid/gid might be interesting, but if we do that, we need to do this as separate fields
  • size doesn't apply (yet), as there is no support for tmpfs

Copy link
Contributor Author

@pranav767 pranav767 Jan 13, 2026

Choose a reason for hiding this comment

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

I've removed mountOptions and used separate fields : DisableAccessTime and Secure.

  • For uid/gid we should only apply them for filesystems that support those mount options
    (examples: vfat, fat, ntfs, cifs, nfs, tmpfs, virtiofs ) some of these might not be supported yet by talos but no harm while using validation. We cannot validate this at config time because the filesystem is discovered at runtime, the mount controller can check the filesystem type for this, I can add that logic if this is alright.

Also, there are several other mount options available, let me know if you want additional typed fields.


| Field | Type | Description | Value(s) |
|-------|------|-------------|----------|
|`readOnly` |bool |Mount the volume read-only. | |
Copy link
Contributor Author

@pranav767 pranav767 Jan 13, 2026

Choose a reason for hiding this comment

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

The docs page currently does not show mount options in the config here. I’m guessing this is because it’s an optional parameter, so I haven’t included those extra options here.

@shanduur shanduur force-pushed the feat/support-for-adding-extra-mount-options branch from 40d3df8 to e7a7da7 Compare January 15, 2026 12:26
@shanduur
Copy link
Member

shanduur commented Jan 15, 2026

I think we need E2E test for those options as well before we can merge it.

Edit:
In this file: https://github.com/siderolabs/talos/blob/v1.12.1/internal/integration/api/volumes.go

@pranav767 pranav767 force-pushed the feat/support-for-adding-extra-mount-options branch 2 times, most recently from 2773555 to 2fb7b50 Compare January 15, 2026 21:03
@pranav767
Copy link
Contributor Author

@shanduur , Added E2E test for both disableAccessTime and secure mount options.
I can move the PR to draft if further discussion is needed around including additional mount options.

@shanduur
Copy link
Member

The tests are failing with:

2026/01/16 09:38:02 172.20.1.6: {"component":"controller-runtime","controller":"block.MountController","error":"failed to mount \"e-694b99c\": openfs failed: failed to create root filesystem: FSCONFIG_SET_FLAG failed: invalid argument: key=\"nosuid\"","msg":"2026/01/16 09:38:02.099973 [talos] controller failed","talos-level":"info","talos-service":"machined","talos-time":"2026-01-16T09:38:02.099993382Z"}

Comment on lines 194 to 195
// Build mount parameters based on configuration
var params []block.ParameterSpec
Copy link
Member

Choose a reason for hiding this comment

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

Those are FS_CONFIG parameters, you want Mount Parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you give another try for integration test on github actions, I've updated mount.go to use mount params,

@pranav767 pranav767 force-pushed the feat/support-for-adding-extra-mount-options branch 2 times, most recently from 603f88f to 9d128f2 Compare January 19, 2026 17:01
Add DisableAccessTime and Secure mount options for existing volumes.
DisableAccessTime adds noatime parameter to disable access time updates.
Secure adds nosuid and nodev parameters for security (defaults to true).
Add integration tests for both options.

Signed-off-by: Pranav Patil <[email protected]>
@pranav767 pranav767 force-pushed the feat/support-for-adding-extra-mount-options branch from 9d128f2 to 0c8ab63 Compare January 20, 2026 21:16
Comment on lines 194 to 205
// Build mount parameters based on configuration
var params []block.ParameterSpec

if existingVolumeConfig.Mount().DisableAccessTime() {
params = append(params, block.NewBooleanParameter("noatime"))
}

// Add secure mount options (nosuid, nodev) by default
if existingVolumeConfig.Mount().Secure() {
params = append(params, block.NewBooleanParameter("nosuid"))
params = append(params, block.NewBooleanParameter("nodev"))
}
Copy link
Member

Choose a reason for hiding this comment

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

Okay, I've did some more reading and this is not a correct way to propagate the parameters. You should follow the same path as ReadOnly is doing, so the values are properly read and if needed, the volume is remounted. The params are read and set only once on the disk provisioning, as they are referring to the filesystem, and can't be updated - you need to reprovision the Volume to do this.

Also, this should be captured in the VolumeMountRequest:

// HandleExistingVolumeMountRequest returns a MountTransformFunc for existing volumes.
// It sets `VolumeMountRequestSpec.ReadOnly` based on the existing configuration.
func HandleExistingVolumeMountRequest(existingVolumeConfig configconfig.ExistingVolumeConfig) func(m *block.VolumeMountRequest) error {
return func(m *block.VolumeMountRequest) error {
m.TypedSpec().ReadOnly = existingVolumeConfig.Mount().ReadOnly()
return nil
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the tip @shanduur ,
After reading I've updated all 3 bits for mounts (mounts, mount_request and mount_status)

Add DisableAccessTime and Secure mount options for existing volumes.
DisableAccessTime adds noatime parameter to disable access time updates.
Secure adds nosuid and nodev parameters for security (defaults to true).
Add integration tests for both options.

Signed-off-by: Pranav Patil <[email protected]>
if err := p.moveMount(p.target); err != nil {
return fmt.Errorf("error mounting %q to %q: %w", p.Source(), p.target, err)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried setting mount attributes directly using mount_setattr, but this failed with EINVAL when attempting to apply MOUNT_ATTR_NOATIME | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NODEV on mounts created via the new mount API.

Example error:

ERROR controller failed {"component":"controller-runtime","controller":"block.MountController","error":"failed to mount \"e-test-data\": failed to mount: 1 error(s) occurred:
        error setting mount attributes on \"/var/mnt/test-data\": setattr failed for fd=70 target=\"/var/mnt/test-data\" flags=36864 attr=unix.MountAttr{Attr_set:0x16, Attr_clr:0x0, Propagation:0x0, Userns_fd:0x0}: invalid argument"}

I tested multiple variations:

  • Calling mount_setattr both before and after move_mount
  • Different flag combinations
  • With and without AT_RECURSIVE

In all cases, setting these attributes via mount_setattr failed with EINVAL.
Using MS_REMOUNT works reliably for these flags, while mount_setattr does work correctly for MOUNT_ATTR_RDONLY.

@pranav767
Copy link
Contributor Author

Dropping some logs which I tried while testing with the changes:

~/siderolabs/talos$ cat /tmp/test-runtime-disable.yaml
 ---
 apiVersion: v1alpha1
 kind: ExistingVolumeConfig
 name: test-data
 discovery:
   volumeSelector:
     match: volume.partition_label == "u-test-volume"
 mount:
   disableAccessTime: false
   secure: false

~/siderolabs/talos$ sudo -E _out/talosctl-linux-amd64 patch mc -n 172.20.0.3 --mode=no-reboot -p @/tmp/test-runtime-disable.yaml && sleep 5 && sudo -E _out/talosctl-linux-amd64 read /proc/mounts -n 172.20.0.3 | grep test-data
patched MachineConfigs.config.talos.dev/v1alpha1 at the node 172.20.0.3
Applied configuration without a reboot
/dev/sda1 /var/mnt/test-data xfs rw,seclabel,noatime,inode64,logbufs=8,logbsize=32k,noquota 0 0

For Mount options: disableAccessTime & secure enabled


cat /tmp/test-runtime-enable2.yaml 
---
apiVersion: v1alpha1
kind: ExistingVolumeConfig
name: test-data
discovery:
  volumeSelector:
    match: volume.partition_label == "u-test-volume"
mount:
  disableAccessTime: true
  secure: true

sudo -E _out/talosctl-linux-amd64 patch mc -n 172.20.0.3 --mode=no-reboot -p @/tmp/test-runtime-enable2.yaml && sleep 3 && sudo -E _out/talosctl-linux-amd64 read /proc/mounts -n 172.20.0.3 | grep test-data
patched MachineConfigs.config.talos.dev/v1alpha1 at the node 172.20.0.3
Applied configuration without a reboot
/dev/sda1 /var/mnt/test-data xfs rw,seclabel,nosuid,nodev,noatime,inode64,logbufs=8,logbsize=32k,noquota 0 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

opaque mount options for volumes

3 participants