diff --git a/roles/svc-storage-nfs-client/README.md b/roles/svc-storage-nfs-client/README.md index ec97c70692..b526991b84 100644 --- a/roles/svc-storage-nfs-client/README.md +++ b/roles/svc-storage-nfs-client/README.md @@ -50,6 +50,12 @@ Solid `1:1` edges are fixed relationships; dashed `0..1` edges are conditional ( Generations written to the share before the bind stay under the export's `backup/` directory, hidden from the nodes; remove them there by hand. +- **Directory delegations off against old ganesha:** When the server + runs nfs-ganesha older than 9.11, every client and the controller set + the kernel's `nfsv4` parameter `directory_delegations` to `N`, at + runtime and in `/etc/modprobe.d`. The parameter is kernel-wide, so on + a lab whose nodes share one kernel it covers every NFS mount of that + host until the module reloads. ## Quick Setup diff --git a/roles/svc-storage-nfs-client/files/shell/directory_delegations.sh b/roles/svc-storage-nfs-client/files/shell/directory_delegations.sh new file mode 100644 index 0000000000..2d95882dbd --- /dev/null +++ b/roles/svc-storage-nfs-client/files/shell/directory_delegations.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -eu +param=/sys/module/nfsv4/parameters/directory_delegations + +[ -e "${param}" ] || exit 0 +[ "$(cat "${param}")" = N ] && exit 0 +echo N >"${param}" +echo CHANGED diff --git a/roles/svc-storage-nfs-client/tasks/directory_delegations.yml b/roles/svc-storage-nfs-client/tasks/directory_delegations.yml new file mode 100644 index 0000000000..e7418ef8f2 --- /dev/null +++ b/roles/svc-storage-nfs-client/tasks/directory_delegations.yml @@ -0,0 +1,27 @@ +--- +- name: "🔍 Read the NFS server's installed packages" + ansible.builtin.package_facts: + delegate_to: "{{ groups['svc-storage-nfs-server'] | first }}" + delegate_facts: true + run_once: true + +- name: "🔧 Stop requesting directory delegations from a ganesha that rejects them" + when: >- + (hostvars[groups['svc-storage-nfs-server'] | first].ansible_facts.packages['nfs-ganesha'] | first).version + is version('9.11', '<') + block: + - name: "🔧 Keep directory delegations off whenever nfsv4 loads" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/infinito-nfs-directory-delegations.conf + line: "options nfsv4 directory_delegations=N" + create: true + owner: root + group: root + mode: "0644" + + - name: "🔧 Turn directory delegations off in the running kernel" + ansible.builtin.script: + cmd: "{{ lookup('path_absolute', 'roles/svc-storage-nfs-client/files/shell/directory_delegations.sh') }}" + executable: /bin/bash + register: svc_storage_nfs_client_directory_delegations + changed_when: "'CHANGED' in svc_storage_nfs_client_directory_delegations.stdout" diff --git a/roles/svc-storage-nfs-client/tasks/main.yml b/roles/svc-storage-nfs-client/tasks/main.yml index 0fc67d391c..68241b326d 100644 --- a/roles/svc-storage-nfs-client/tasks/main.yml +++ b/roles/svc-storage-nfs-client/tasks/main.yml @@ -51,6 +51,10 @@ failed_when: - svc_storage_nfs_client_probe is failed +- name: "🔧 Align the NFS client's directory delegations with the ganesha server" + ansible.builtin.include_tasks: directory_delegations.yml + when: lookup('nfs_flavor') == 'ganesha' + - name: "🔍 Probe-write a marker to confirm the mount is RW" ansible.builtin.copy: dest: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}/.svc-storage-nfs-client-probe.{{ inventory_hostname }}" diff --git a/roles/svc-storage-nfs-server/tasks/03_controller_mount.yml b/roles/svc-storage-nfs-server/tasks/03_controller_mount.yml index fdaddf1a6b..62e83c01e4 100644 --- a/roles/svc-storage-nfs-server/tasks/03_controller_mount.yml +++ b/roles/svc-storage-nfs-server/tasks/03_controller_mount.yml @@ -59,3 +59,7 @@ retries: 12 delay: 5 until: _ctrl_nfs_mount is succeeded + +- name: "🔧 Align the controller's directory delegations with the ganesha server" + ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/svc-storage-nfs-client/tasks/directory_delegations.yml') }}" + when: lookup('nfs_flavor') == 'ganesha'