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

New custom-persist feature #551

Merged
merged 18 commits into from
Mar 1, 2025
Merged

New custom-persist feature #551

merged 18 commits into from
Mar 1, 2025

Conversation

Guiiix
Copy link
Member

@Guiiix Guiiix commented Jan 28, 2025

This PR adds a new feature custom-persist described in QubesOS/qubes-issues#1006

When the custom-persist feature is enabled, we no longer need to worry about the bind directories configured in /rw/config/qubes-bind-dirs.d.
Copy link

codecov bot commented Jan 28, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 70.46%. Comparing base (664df47) to head (cc84ec6).
Report is 31 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #551      +/-   ##
==========================================
- Coverage   70.57%   70.46%   -0.12%     
==========================================
  Files           3        3              
  Lines         469      474       +5     
==========================================
+ Hits          331      334       +3     
- Misses        138      140       +2     

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

@Guiiix Guiiix force-pushed the custom-persist branch 2 times, most recently from 987de8f to 3583fca Compare February 2, 2025 07:35
@deeplow
Copy link

deeplow commented Feb 13, 2025

Happy to see this getting implemented. And @Guiiix happy to see a new face on the Qubes team :)

Here's some feedback from giving this and it's sister PR a spin. Although I haven't been able to get this working yet (but I could be setting it up wrongly).

What I did:

  • installed 4.3 from a recent nightly build
  • installed this package on fedora-41-xfce and the respective dom0 package
  • shut down fedora-41-xfce
  • create a qube called minimal-state based on fedora-41-xfce
  • added custom-persist to minimal-state
  • qvm-features minimal-state custom-persist.test "/home/user/some-dir"
  • then started a terminal in minimal-state
  • in minimal-state I ran mkdir /home/user/some-dir && touch /home/user/some-dir/test
  • restarted minimal-state

Expected:

  • /home/user/some-dir/test (and it's parent dir) to exist

What happened instead:

  • /home/user/some-dir not present
  • fedora-41-xfce wouldn't open GUI applications any longer - and yes, I did add custom-persist just to check if this would start working and it did, but with some side-effects: the app qube would have the template's home instead. I even though it had actually the template's private volume mounted.

So I'm probably doing something wrong. Is this the expected usage of this feature or am I messing something in the process?

@marmarek
Copy link
Member

/home/user/some-dir not present

Yes, I think bind-dirs does not create dirs on its own, they need to exist beforehand. This is especially relevant since by looking at just the path, you don't have enough info to create it - it can be either a file or a directory, you don't know what permissions to use, owner etc...

But maybe this can be extended with some defaults? For example if doesn't exist, then create as a dir, with owner same as the parent directory, and default mode of 755? Or extend the syntax to allow specify those details...

@marmarek
Copy link
Member

fedora-41-xfce wouldn't open GUI applications any longer - and yes, I did add custom-persist just to check if this would start working and it did, but with some side-effects: the app qube would have the template's home instead. I even though it had actually the template's private volume mounted.

Can you check why? The default /home from the template should be good enough for normal applications to start...

@qubesos-bot
Copy link

qubesos-bot commented Feb 13, 2025

OpenQA test summary

Complete test suite and dependencies: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2025022819-4.3&flavor=pull-requests

Test run included the following:

New failures, excluding unstable

Compared to: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2025021804-4.3&flavor=update

  • system_tests_basic_vm_qrexec_gui

  • system_tests_extra

    • TC_00_Direct_whonix-workstation-17: test_031_sign_verify_detached (failure)
      AssertionError: subkey generation failed: b''b'2025-02-28 16:24:38....
  • system_tests_basic_vm_qrexec_gui_zfs

  • system_tests_audio

  • system_tests_basic_vm_qrexec_gui_btrfs

  • system_tests_suspend@hw1

    • suspend: wait_serial (wait serial expected)
      # wait_serial expected: qr/p5~T5-\d+-/...
  • system_tests_basic_vm_qrexec_gui@hw7

  • system_tests_kde_gui_interactive

    • simple_gui_apps: unnamed test (unknown)

    • simple_gui_apps: Failed (test died)
      # Test died: no candidate needle with tag(s) 'menu-vm-settings' mat...

    • simple_gui_apps: unnamed test (unknown)

    • simple_gui_apps: wait_serial (wait serial expected)
      # wait_serial expected: qr/2E8vz-\d+-/...

  • system_tests_guivm_vnc_gui_interactive

    • gui_filecopy: unnamed test (unknown)
    • gui_filecopy: Failed (test died)
      # Test died: no candidate needle with tag(s) 'work-text-editor' mat...
  • system_tests_basic_vm_qrexec_gui_xfs

  • system_tests_basic_vm_qrexec_gui_ext4

Failed tests

25 failures
  • system_tests_basic_vm_qrexec_gui

  • system_tests_extra

    • TC_00_Direct_whonix-workstation-17: test_031_sign_verify_detached (failure)
      AssertionError: subkey generation failed: b''b'2025-02-28 16:24:38....
  • system_tests_basic_vm_qrexec_gui_zfs

  • system_tests_audio

  • system_tests_basic_vm_qrexec_gui_btrfs

  • system_tests_suspend@hw1

    • suspend: wait_serial (wait serial expected)
      # wait_serial expected: qr/p5~T5-\d+-/...

    • suspend: Failed (test died + timed out)
      # Test died: command 'true' timed out at /usr/lib/os-autoinst/autot...

  • system_tests_basic_vm_qrexec_gui@hw7

  • system_tests_kde_gui_interactive

    • simple_gui_apps: unnamed test (unknown)

    • simple_gui_apps: Failed (test died)
      # Test died: no candidate needle with tag(s) 'menu-vm-settings' mat...

    • simple_gui_apps: unnamed test (unknown)

    • simple_gui_apps: wait_serial (wait serial expected)
      # wait_serial expected: qr/2E8vz-\d+-/...

  • system_tests_guivm_vnc_gui_interactive

    • gui_filecopy: unnamed test (unknown)
    • gui_filecopy: Failed (test died)
      # Test died: no candidate needle with tag(s) 'work-text-editor' mat...
  • system_tests_basic_vm_qrexec_gui_xfs

  • system_tests_basic_vm_qrexec_gui_ext4

Fixed failures

Compared to: https://openqa.qubes-os.org/tests/129058#dependencies

14 fixed
  • system_tests_whonix

    • whonixcheck: fail (unknown)
      Whonixcheck for sys-whonix failed...

    • whonixcheck: unnamed test (unknown)

  • system_tests_suspend

    • suspend: unnamed test (unknown)
    • suspend: Failed (test died)
      # Test died: no candidate needle with tag(s) 'SUSPEND-FAILED' match...
  • system_tests_qrexec

  • system_tests_audio

  • system_tests_whonix@hw7

    • whonixcheck: fail (unknown)
      Whonixcheck for sys-whonix failed...

    • whonixcheck: unnamed test (unknown)

  • system_tests_basic_vm_qrexec_gui_btrfs

    • TC_03_QvmRevertTemplateChanges: test_000_revert_linux (error)
      subprocess.CalledProcessError: Command '['sha1sum', '/var/lib/qubes...
  • system_tests_suspend@hw1

  • system_tests_kde_gui_interactive

    • clipboard_and_web: unnamed test (unknown)
    • clipboard_and_web: Failed (test died)
      # Test died: no candidate needle with tag(s) 'clipboard-paste-notif...

Unstable tests

Performance Tests

Performance degradation:

29 performance degradations
  • debian-12-xfce_exec: 8.31 :small_red_triangle_up: ( previous job: 7.15, degradation: 116.24%)
  • debian-12-xfce_exec-data-simplex: 68.47 :small_red_triangle_up: ( previous job: 48.93, degradation: 139.94%)
  • debian-12-xfce_exec-data-duplex: 69.55 :small_red_triangle_up: ( previous job: 50.76, degradation: 137.01%)
  • debian-12-xfce_exec-data-duplex-root: 85.79 :small_red_triangle_up: ( previous job: 64.91, degradation: 132.17%)
  • debian-12-xfce_socket-data-duplex: 166.11 :small_red_triangle_up: ( previous job: 81.49, degradation: 203.84%)
  • fedora-41-xfce_exec-data-simplex: 73.38 :small_red_triangle_up: ( previous job: 49.65, degradation: 147.80%)
  • fedora-41-xfce_exec-data-duplex: 72.91 :small_red_triangle_up: ( previous job: 49.08, degradation: 148.55%)
  • fedora-41-xfce_exec-data-duplex-root: 111.80 :small_red_triangle_up: ( previous job: 81.65, degradation: 136.92%)
  • fedora-41-xfce_socket-data-duplex: 152.37 :small_red_triangle_up: ( previous job: 78.62, degradation: 193.80%)
  • whonix-gateway-17_exec-data-simplex: 70.54 :small_red_triangle_up: ( previous job: 48.76, degradation: 144.65%)
  • whonix-gateway-17_exec-data-duplex: 78.20 :small_red_triangle_up: ( previous job: 48.55, degradation: 161.06%)
  • whonix-gateway-17_exec-data-duplex-root: 101.18 :small_red_triangle_up: ( previous job: 70.13, degradation: 144.28%)
  • whonix-gateway-17_socket-data-duplex: 161.79 :small_red_triangle_up: ( previous job: 82.74, degradation: 195.54%)
  • whonix-workstation-17_exec-data-simplex: 65.81 :small_red_triangle_up: ( previous job: 47.01, degradation: 139.97%)
  • whonix-workstation-17_exec-data-duplex: 70.89 :small_red_triangle_up: ( previous job: 49.48, degradation: 143.28%)
  • whonix-workstation-17_exec-data-duplex-root: 92.80 :small_red_triangle_up: ( previous job: 79.93, degradation: 116.10%)
  • whonix-workstation-17_socket-data-duplex: 157.93 :small_red_triangle_up: ( previous job: 81.71, degradation: 193.28%)
  • dom0_root_seq1m_q8t1_read 3:read_bandwidth_kb: 270530.00 :small_red_triangle_up: ( previous job: 486352.00, degradation: 55.62%)
  • dom0_root_seq1m_q8t1_write 3:write_bandwidth_kb: 184205.00 :small_red_triangle_up: ( previous job: 276742.00, degradation: 66.56%)
  • dom0_root_seq1m_q1t1_read 3:read_bandwidth_kb: 63859.00 :small_red_triangle_up: ( previous job: 423495.00, degradation: 15.08%)
  • dom0_root_seq1m_q1t1_write 3:write_bandwidth_kb: 25113.00 :small_red_triangle_up: ( previous job: 185030.00, degradation: 13.57%)
  • dom0_root_rnd4k_q32t1_read 3:read_bandwidth_kb: 12717.00 :small_red_triangle_up: ( previous job: 100699.00, degradation: 12.63%)
  • dom0_root_rnd4k_q32t1_write 3:write_bandwidth_kb: 1542.00 :small_red_triangle_up: ( previous job: 3277.00, degradation: 47.06%)
  • fedora-41-xfce_root_rnd4k_q32t1_write 3:write_bandwidth_kb: 2168.00 :small_red_triangle_up: ( previous job: 3785.00, degradation: 57.28%)
  • fedora-41-xfce_root_rnd4k_q1t1_write 3:write_bandwidth_kb: 810.00 :small_red_triangle_up: ( previous job: 1126.00, degradation: 71.94%)
  • fedora-41-xfce_private_rnd4k_q32t1_write 3:write_bandwidth_kb: 2797.00 :small_red_triangle_up: ( previous job: 3885.00, degradation: 71.99%)
  • fedora-41-xfce_private_rnd4k_q1t1_write 3:write_bandwidth_kb: 1228.00 :small_red_triangle_up: ( previous job: 1613.00, degradation: 76.13%)
  • fedora-41-xfce_volatile_seq1m_q8t1_read 3:read_bandwidth_kb: 337162.00 :small_red_triangle_up: ( previous job: 392725.00, degradation: 85.85%)
  • fedora-41-xfce_volatile_rnd4k_q1t1_write 3:write_bandwidth_kb: 1018.00 :small_red_triangle_up: ( previous job: 2693.00, degradation: 37.80%)

Remaining performance tests:

43 tests
  • debian-12-xfce_exec-root: 28.90 :small_red_triangle_up: ( previous job: 27.97, degradation: 103.32%)
  • debian-12-xfce_socket: 7.77 🟢 ( previous job: 8.33, improvement: 93.32%)
  • debian-12-xfce_socket-root: 8.84 :small_red_triangle_up: ( previous job: 8.20, degradation: 107.79%)
  • fedora-41-xfce_exec: 9.50 :small_red_triangle_up: ( previous job: 9.13, degradation: 104.05%)
  • fedora-41-xfce_exec-root: 62.94 :small_red_triangle_up: ( previous job: 61.17, degradation: 102.90%)
  • fedora-41-xfce_socket: 8.70 :small_red_triangle_up: ( previous job: 8.66, degradation: 100.43%)
  • fedora-41-xfce_socket-root: 8.70 :small_red_triangle_up: ( previous job: 8.61, degradation: 101.04%)
  • whonix-gateway-17_exec: 6.40 🟢 ( previous job: 7.87, improvement: 81.34%)
  • whonix-gateway-17_exec-root: 38.57 :small_red_triangle_up: ( previous job: 38.36, degradation: 100.54%)
  • whonix-gateway-17_socket: 7.01 🟢 ( previous job: 7.54, improvement: 92.86%)
  • whonix-gateway-17_socket-root: 7.50 🟢 ( previous job: 8.27, improvement: 90.69%)
  • whonix-workstation-17_exec: 8.07 🟢 ( previous job: 8.23, improvement: 98.12%)
  • whonix-workstation-17_exec-root: 54.08 :small_red_triangle_up: ( previous job: 52.56, degradation: 102.88%)
  • whonix-workstation-17_socket: 8.10 🟢 ( previous job: 8.21, improvement: 98.66%)
  • whonix-workstation-17_socket-root: 8.17 🟢 ( previous job: 8.20, improvement: 99.66%)
  • dom0_root_rnd4k_q1t1_read 3:read_bandwidth_kb: 11576.00 :green_circle: ( previous job: 10163.00, improvement: 113.90%)
  • dom0_root_rnd4k_q1t1_write 3:write_bandwidth_kb: 672.00 :green_circle: ( previous job: 282.00, improvement: 238.30%)
  • dom0_varlibqubes_seq1m_q8t1_read 3:read_bandwidth_kb: 468742.00 :small_red_triangle_up: ( previous job: 475329.00, degradation: 98.61%)
  • dom0_varlibqubes_seq1m_q8t1_write 3:write_bandwidth_kb: 97087.00 :green_circle: ( previous job: 95209.00, improvement: 101.97%)
  • dom0_varlibqubes_seq1m_q1t1_read 3:read_bandwidth_kb: 433116.00 :small_red_triangle_up: ( previous job: 433474.00, degradation: 99.92%)
  • dom0_varlibqubes_seq1m_q1t1_write 3:write_bandwidth_kb: 169543.00 :green_circle: ( previous job: 164133.00, improvement: 103.30%)
  • dom0_varlibqubes_rnd4k_q32t1_read 3:read_bandwidth_kb: 104366.00 :green_circle: ( previous job: 99808.00, improvement: 104.57%)
  • dom0_varlibqubes_rnd4k_q32t1_write 3:write_bandwidth_kb: 8183.00 :small_red_triangle_up: ( previous job: 8767.00, degradation: 93.34%)
  • dom0_varlibqubes_rnd4k_q1t1_read 3:read_bandwidth_kb: 7698.00 :green_circle: ( previous job: 7053.00, improvement: 109.15%)
  • dom0_varlibqubes_rnd4k_q1t1_write 3:write_bandwidth_kb: 4422.00 :green_circle: ( previous job: 3868.00, improvement: 114.32%)
  • fedora-41-xfce_root_seq1m_q8t1_read 3:read_bandwidth_kb: 379643.00 :small_red_triangle_up: ( previous job: 396586.00, degradation: 95.73%)
  • fedora-41-xfce_root_seq1m_q8t1_write 3:write_bandwidth_kb: 149953.00 :green_circle: ( previous job: 99783.00, improvement: 150.28%)
  • fedora-41-xfce_root_seq1m_q1t1_read 3:read_bandwidth_kb: 310965.00 :small_red_triangle_up: ( previous job: 343795.00, degradation: 90.45%)
  • fedora-41-xfce_root_seq1m_q1t1_write 3:write_bandwidth_kb: 44317.00 :small_red_triangle_up: ( previous job: 44770.00, degradation: 98.99%)
  • fedora-41-xfce_root_rnd4k_q32t1_read 3:read_bandwidth_kb: 86714.00 :small_red_triangle_up: ( previous job: 86742.00, degradation: 99.97%)
  • fedora-41-xfce_root_rnd4k_q1t1_read 3:read_bandwidth_kb: 8588.00 :small_red_triangle_up: ( previous job: 8623.00, degradation: 99.59%)
  • fedora-41-xfce_private_seq1m_q8t1_read 3:read_bandwidth_kb: 414129.00 :green_circle: ( previous job: 401907.00, improvement: 103.04%)
  • fedora-41-xfce_private_seq1m_q8t1_write 3:write_bandwidth_kb: 255252.00 :green_circle: ( previous job: 116848.00, improvement: 218.45%)
  • fedora-41-xfce_private_seq1m_q1t1_read 3:read_bandwidth_kb: 352581.00 :small_red_triangle_up: ( previous job: 357875.00, degradation: 98.52%)
  • fedora-41-xfce_private_seq1m_q1t1_write 3:write_bandwidth_kb: 80465.00 :green_circle: ( previous job: 41375.00, improvement: 194.48%)
  • fedora-41-xfce_private_rnd4k_q32t1_read 3:read_bandwidth_kb: 86812.00 :small_red_triangle_up: ( previous job: 87999.00, degradation: 98.65%)
  • fedora-41-xfce_private_rnd4k_q1t1_read 3:read_bandwidth_kb: 8301.00 :small_red_triangle_up: ( previous job: 8744.00, degradation: 94.93%)
  • fedora-41-xfce_volatile_seq1m_q8t1_write 3:write_bandwidth_kb: 189909.00 :green_circle: ( previous job: 139933.00, improvement: 135.71%)
  • fedora-41-xfce_volatile_seq1m_q1t1_read 3:read_bandwidth_kb: 298145.00 :green_circle: ( previous job: 294875.00, improvement: 101.11%)
  • fedora-41-xfce_volatile_seq1m_q1t1_write 3:write_bandwidth_kb: 102052.00 :green_circle: ( previous job: 78093.00, improvement: 130.68%)
  • fedora-41-xfce_volatile_rnd4k_q32t1_read 3:read_bandwidth_kb: 90327.00 :green_circle: ( previous job: 71108.00, improvement: 127.03%)
  • fedora-41-xfce_volatile_rnd4k_q32t1_write 3:write_bandwidth_kb: 3978.00 :green_circle: ( previous job: 3959.00, improvement: 100.48%)
  • fedora-41-xfce_volatile_rnd4k_q1t1_read 3:read_bandwidth_kb: 8159.00 :small_red_triangle_up: ( previous job: 8408.00, degradation: 97.04%)

@deeplow
Copy link

deeplow commented Feb 14, 2025

Can you check why? The default /home from the template should be good enough for normal applications to start...

It seems to be some some permission / SELinux issue.

The following is the tail of the console log for fedora-41-xfce, after I tried to open xfce4-terminal:

.[?2004h[user@fedora-41-xfce /]$ [  229.808955] kauditd_printk_skb: 21 callbacks suppressed
[2025-02-14 13:51:05] [  229.808959] audit: type=1100 audit(1739541065.606:202): pid=9087 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='op=PAM:authentication grantors=pam_rootok acct="user" exe="/usr/lib/qubes/qrexec-agent" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:05] [  229.809992] audit: type=1103 audit(1739541065.607:203): pid=9087 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='op=PAM:setcred grantors=pam_rootok acct="user" exe="/usr/lib/qubes/qrexec-agent" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:05] [  229.810072] audit: type=1006 audit(1739541065.607:204): pid=9087 uid=0 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 old-auid=4294967295 auid=1000 tty=(none) old-ses=4294967295 ses=9 res=1
[2025-02-14 13:51:05] [  229.810129] audit: type=1300 audit(1739541065.607:204): arch=c000003e syscall=1 success=yes exit=4 a0=3 a1=7ffd0bf5cef0 a2=4 a3=0 items=0 ppid=9085 pid=9087 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=9 comm="qrexec-agent" exe="/usr/lib/qubes/qrexec-agent" subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 key=(null)
[2025-02-14 13:51:05] [  229.810230] audit: type=1327 audit(1739541065.607:204): proctitle="/usr/lib/qubes/qrexec-agent"
[2025-02-14 13:51:05] [  229.810270] audit: type=2300 audit(1739541065.607:205): pid=9087 uid=0 auid=1000 ses=9 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='op=pam_selinux default-context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 selected-context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 exe="/usr/lib/qubes/qrexec-agent" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:05] [  229.814457] audit: type=1400 audit(1739541065.611:206): avc:  denied  { sendto } for  pid=9088 comm="(sd-worker)" path="/run/systemd/journal/socket" scontext=system_u:system_r:systemd_nsresourced_t:s0 tcontext=system_u:system_r:syslogd_t:s0 tclass=unix_dgram_socket permissive=0
[2025-02-14 13:51:05] [  229.814551] audit: type=1300 audit(1739541065.611:206): arch=c000003e syscall=42 success=no exit=-13 a0=4 a1=7ffc627357b0 a2=1e a3=7ffc62735860 items=0 ppid=288 pid=9088 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="(sd-worker)" exe="/usr/lib/systemd/systemd-nsresourced" subj=system_u:system_r:systemd_nsresourced_t:s0 key=(null)
[2025-02-14 13:51:05] [  229.814663] audit: type=1327 audit(1739541065.611:206): proctitle="(sd-worker)"
[2025-02-14 13:51:05] [  229.820970] audit: type=1400 audit(1739541065.618:207): avc:  denied  { sendto } for  pid=9088 comm="systemd-nsresou" path="/run/systemd/journal/socket" scontext=system_u:system_r:systemd_nsresourced_t:s0 tcontext=system_u:system_r:syslogd_t:s0 tclass=unix_dgram_socket permissive=0
[2025-02-14 13:51:35] [  259.880643] kauditd_printk_skb: 3 callbacks suppressed
[2025-02-14 13:51:35] [  259.880646] audit: type=1131 audit(1739541095.677:209): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-hostnamed comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:35] [  259.911736] audit: type=1334 audit(1739541095.709:210): prog-id=56 op=UNLOAD

And this is what happens in a working template (without custom-persist), which I called fedora-41-xfce3:

.[?2004h[user@fedora-41-xfce3 ~]$ [2025-02-14 13:51:09] [ 2764.414298] kauditd_printk_skb: 16 callbacks suppressed
[2025-02-14 13:51:09] [ 2764.414302] audit: type=1334 audit(1739541069.299:254): prog-id=59 op=UNLOAD
[2025-02-14 13:51:09] [ 2764.414358] audit: type=1334 audit(1739541069.299:255): prog-id=58 op=UNLOAD
[2025-02-14 13:51:09] [ 2764.414640] audit: type=1334 audit(1739541069.300:256): prog-id=60 op=LOAD
[2025-02-14 13:51:09] [ 2764.414673] audit: type=1334 audit(1739541069.300:257): prog-id=61 op=LOAD
[2025-02-14 13:51:09] [ 2764.414698] audit: type=1334 audit(1739541069.300:258): prog-id=62 op=LOAD
[2025-02-14 13:51:09] [ 2764.452838] audit: type=1130 audit(1739541069.338:259): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-hostnamed comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:39] [ 2794.554967] audit: type=1131 audit(1739541099.440:260): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-hostnamed comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[2025-02-14 13:51:39] [ 2794.588549] audit: type=1334 audit(1739541099.474:261): prog-id=60 op=UNLOAD

If I then enable the custom-persist service in fedora-41-xfce, then it works like the other template and it is able to opern GUI applications.

guest-fedora-41-xfce3.log
guest-fedora-41-xfce.log

@marmarek
Copy link
Member

The selinux messages are red herring, it's related to GUI session failing to start, so application is started outside of it. The actual problem is somewhere about GUI agent - see either qubes-gui-agent logs in journal or /home/user/.xsession-errors.

@Guiiix
Copy link
Member Author

Guiiix commented Feb 14, 2025

Hi @deeplow! Thank you for your message. I'm very happy to be part to this adventure with you all :)

I tried to reproduce on release r4.2 (commits backported to branch release 4.2) but I didn't get any error on the template:

  • /home/user/somedir not mounted: as Marek said, this is the expected behavior regarding the current bind_dirs script. You would have the same result without custom-persist if you had added this directory to /rw/config/qubes-bind-dirs.d but it could be relevant to do some changes, at least for this feature.
  • fedora-40-xfce template's GUI is working well

Did bothqubes-bind-dirs.service and qubes-mount-dirs.service started well? systemctl --failed shows anything abnormal?

@marmarek
Copy link
Member

FWIW I also didn't reproduced the GUI apps failure, but I tried it in AppVM, not the template itself.

I added integration tests here: https://github.com/QubesOS/qubes-core-admin/pull/654/files#diff-19c2f2ac398e72a651b363ef17c05d7f0348b8bed0cbbf5c938265e09c76e463R57-R118

There are a couple of things going on. First, it does fail (as expected) on directories that don't exist initially (one may expect /home/user/Downloads to exists already, but in practice it's created on first boot - and that happens after bind-dirs call). But there is another thing - /usr/local/bin/true-copy did persisted but it shouldn't. I see the whole /usr/local being still bind-mounted with /rw/usrlocal...
FWIW that's on debian-12-xfce template.
In the log I see first systemd[1]: Mounting usr-local.mount - /usr/local... and only later Disabling persistent /usr/local.
And also, the same happens for /home, but here I see systemd[1]: mounting home.mount - /home... after Disabling persistent /home message. But here it seems it mounted rootfs (/dev/xvda3, not /dev/xvdb) which I guess is okay.
So, I think at the very least some ordering is wrong, but maybe also missing systemctl daemon-reload call?

@Guiiix
Copy link
Member Author

Guiiix commented Feb 16, 2025

I tried many things to reproduce but I was not able to. Maybe I'm doing wrong. I did the following (I'm running a 4.2-stable version of Qubes):

Rootfs is not mounted for /home nor /usr/local:

root@debian-persist:/home/user# mount | grep -E '(home|local)'
/dev/xvda3 on /home type ext4 (rw,nosuid,nodev,noatime,discard)
/dev/xvda3 on /usr/local type ext4 (rw,noatime,discard)

Order seems to be good in logs:

Feb 16 12:13:17 localhost mount-dirs.sh[362]: Disabling persistent /usr/local
...
Feb 16 12:13:17 localhost systemd[1]: systemd-repart.service - Repartition Root Disk was skipped because no trigger condition checks were met.
Feb 16 12:13:18 localhost systemd[1]: home.mount: Directory /home to mount over is not empty, mounting anyway.
Feb 16 12:13:18 localhost systemd[1]: Mounting home.mount - /home...
Feb 16 12:13:18 localhost systemd[1]: Mounting usr-local.mount - /usr/local...
Feb 16 12:13:18 localhost systemd[1]: Mounted home.mount - /home.
Feb 16 12:13:18 localhost systemd[1]: Mounted usr-local.mount - /usr/local.
Feb 16 12:13:18 localhost systemd[1]: Reached target local-fs.target - Local File Systems.
Feb 16 12:13:18 localhost systemd[1]: Starting apparmor.service - Load AppArmor profiles...
Feb 16 12:13:18 localhost systemd[1]: Starting qubes-bind-dirs.service - Mount configured bind file

@marmarek
Copy link
Member

Could be non-deterministic. What happens if you set vcpus to 1 for this qube?

@marmarek
Copy link
Member

Or maybe it's more likely to fail if you add more custom-persist dirs?

@marmarek
Copy link
Member

In any case, I don't see anything that would guarantee /usr/local and /home being mounted only after bind-dirs is called. I think explicit After= is needed (in the [Unit] section) there.

@Guiiix
Copy link
Member Author

Guiiix commented Feb 16, 2025

You're right, it's probably non-deterministic. Even with 1vcpu and a lot of custom persist directories, it's working well on my VM but something is missing in the Before= section of qubes-mount-dirs.service.

If we want to keep the same behavior as before when this feature is disabled, we don't want /home and /usr/local to be mounted after qubes-bind-dirs as this is mount-dirs.sh that was mouting them just before executing bind-dirs.sh. Instead, we want:

  1. qubes-mount-dirs.service: will create droppins to disable or not /home and /usr/local persistence and do a daemon-reload
  2. mount /home and /usr/local
  3. Run qubes-bind-dirs.service

qubes-bind-dirs.service has a Requires= and After= dependencies with qubes-bind-dirs, home.mount and usr-local.mount so if think we are good but qubes-mount-dirs.service has only a Before= with home.mount, nothing with usr-local.mount.

I guess this is why you see Disabling /usr/local after systemd[1]: Mounting usr-local.mount - /usr/local....

@Guiiix
Copy link
Member Author

Guiiix commented Feb 16, 2025

I added a sleep at the beginning of mount-dirs.sh and now /usr/local is mounted from /dev/xvdb. /home is still mounted from /dev/xvda3. When adding usr-local.mount in Before= of qubes-mount-dirs.service, both are mounted from /dev/xvda3.

@Guiiix
Copy link
Member Author

Guiiix commented Feb 23, 2025

This should do the job if my understanding of cp --parents is correct.

@marmarek
Copy link
Member

But at least tests are green now :)

@deeplow
Copy link

deeplow commented Feb 24, 2025

But I don't see anything in Thunar. Am I missing something?

Thanks for testing. I think this only happens on files / directories under /home/user.

I have followed your steps, although when updating to the step "update qubes-core-agent and qubes-core-agent-systemd with this version" I had to downgrade to qubes-core-agent-linux 4.3.16-1 and 4 other packages (but I guess this is intended since the branch may have not yet been rebased).

qvm-features
user@dom0:~$ qvm-features minimal-state2
menu-items              xfce4-terminal.desktop thunar.desktop org.mozilla.firefox.desktop xfce-settings-manager.desktop
custom-persist.exists   dir:user:user:755:/home/user/somedir
custom-persist.exists2  file:user:user:700:/var/test
service.custom-persist  1

I do still see the mounts:

somedir

mount
/dev/xvdb on /home/user/somedir type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)
/dev/xvdb on /home/user/somedir type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)
/dev/xvdb on /var/test type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)

So I think what's happening here is that when the mounts happen in home, they should up in thunar. You tested with a file in /var/.


Also, in the mount output I do notice a duplicate entry for the directory. Is this intended?

journalctl -u qubes-bind-dirs.service -u qubes-mount-dirs.service
Feb 24 12:01:08 fedora systemd[1]: Starting qubes-mount-dirs.service - Initialize and mount /rw and /home...
Feb 24 12:01:08 fedora mount-dirs.sh[398]: Private device management: checking /dev/xvdb
Feb 24 12:01:08 fedora mount-dirs.sh[398]: Private device management: fsck.ext4 of /dev/xvdb succeeded
Feb 24 12:01:08 fedora mount-dirs.sh[406]: Checking /rw
Feb 24 12:01:08 fedora mount-dirs.sh[406]: Private device size management: enlarging /dev/xvdb
Feb 24 12:01:08 fedora mount-dirs.sh[406]: Private device size management: resize2fs of /dev/xvdb succeeded
Feb 24 12:01:08 fedora mount-dirs.sh[410]: chcon: failed to set type security context component to ‘system_u:object_r:root_t:s0’: Invalid argument
Feb 24 12:01:08 fedora mount-dirs.sh[406]: Finished checking /rw
Feb 24 12:01:08 fedora mount-dirs.sh[397]: Disabling persistent /home
Feb 24 12:01:08 fedora mount-dirs.sh[397]: initialize_home: populating unconditionally /home/user from /etc/skel
Feb 24 12:01:09 fedora mount-dirs.sh[397]: initialize_home: adjusting permissions unconditionally on /home/user
Feb 24 12:01:09 fedora mount-dirs.sh[397]: Disabling persistent /usr/local
Feb 24 12:01:09 fedora systemd[1]: Finished qubes-mount-dirs.service - Initialize and mount /rw and /home.
Feb 24 12:01:09 fedora systemd[1]: Starting qubes-bind-dirs.service - Mount configured bind files and directories...
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: custom-persist: pre-creating file /rw/bind-dirs/var/test with rights user:user 700
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: /var/spool/cron is not a symlink
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: /var/spool/cron is neither a directory nor a file and the path does not exist below /rw, skipping.
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: /home/user/somedir is not a symlink
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: Bind mounting /rw/home/user/somedir onto /home/user/somedir
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: /var/test is not a symlink
Feb 24 12:01:09 minimal-state2 bind-dirs.sh[527]: Bind mounting /rw/bind-dirs/var/test onto /var/test
Feb 24 12:01:09 minimal-state2 systemd[1]: Finished qubes-bind-dirs.service - Mount configured bind files and directories.

@marmarek
Copy link
Member

The "eject" icon there is especially confusing. Will it actually unmount the thing if you click it? Maybe for some reason Thunar thinks it's a removable device... I wonder how it gets that, there is no device attached after all (so it can't be udev, and probably not udisks either).

@Guiiix
Copy link
Member Author

Guiiix commented Feb 26, 2025

So I think what's happening here is that when the mounts happen in home, they should up in thunar. You tested with a file in /var/.

Ah yes I got the eject button too with a bind mount in /home. IIUC this is the service gvfs-udisks2-volume-monitor that is responsible for listing removable devices in the sidebar. Filtering is done by looking at the mount path:

https://github.com/GNOME/gvfs/blob/master/monitor/udisks2/what-is-shown.txt

If we add x-gvfs-hide mount option in bind_dirs.sh it's better but we still see an entry in Thunar:

[user@fedora-41-persist ~]$ sudo mount | grep xvdb
/dev/xvdb on /rw type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)
/dev/xvdb on /home/user/.bash_history type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)
/dev/xvdb on /home/user/.bash_history type ext4 (rw,nosuid,nodev,relatime,seclabel,discard,x-gvfs-hide)
/dev/xvdb on /home/user/Downloads type ext4 (rw,nosuid,nodev,relatime,seclabel,discard)
/dev/xvdb on /home/user/Downloads type ext4 (rw,nosuid,nodev,relatime,seclabel,discard,x-gvfs-hide)

Capture d’écran_2025-02-26_21-51-25

This is related to the second problem

Also, in the mount output I do notice a duplicate entry for the directory. Is this intended?
journalctl -u qubes-bind-dirs.service -u qubes-mount-dirs.service

Duplicates mounts that might be caused by mount propagation:

https://unix.stackexchange.com/questions/464605/why-do-repeated-bind-mounts-create-entries-for-the-source-directory

As the second entry is automatically generated, we can't add the x-gvfs-hide. As for gvfs-udisks2-volume-monitor paths monitored seem to be hard-coded:

https://github.com/GNOME/gvfs/blob/master/monitor/udisks2/gvfsudisks2volumemonitor.c#L692

By overriding HOME environment variable in the unit file and setting its value to a something that is not an absolute path, g_get_home_dir() returns NULL and $HOME mount points are ignored. I can add the following drop-in if it's not too ugly:

[user@fedora-41-persist ~]$ cat /usr/lib/systemd/user/gvfs-udisks2-volume-monitor.service.d/30_qubes.conf 
[Service]
Environment="HOME=fakehome"

Will it actually unmount the thing if you click it?

It tries but got permission denied

@marmarek
Copy link
Member

Duplicates mounts that might be caused by mount propagation:

This makes sense. So, it's basically caused by having home.mount that mounts /home to /home. Maybe instead of changing What field, it can be disabled some other way, for example with ConditionPathExists=/nonexistent?

@Guiiix
Copy link
Member Author

Guiiix commented Feb 27, 2025

Ah yes!! I was thinking ConditionPathExists didn't work with mount units but when I tested before, mount units were generated by systemd-fstab-generator and that was causing drop-ins to be ignored.
Now that home.mount and usr-local.mount are regular mount units (not generated ones), it works! Thank you.

So the winning combination is:

  • disable /home and /usr/local using ConditionPathExists
  • mount every bind dir with -o x-gvfs-hide :)

When using custom-persist to pre-create the resource before bind mounting it, we
might have to create its parents too. That was done using mkdir --parents that was
causing parents to be created with root:root ownership which can leads to errors if,
for example, a user wants to bind mount a directory inside its home dir.
With this fix, parents are created with the same ownership as the resource.
…nting

When disabling persistent /home or /usr/local, custom-persist was using a systemd drop-in
to override the What= option and set it to the same value as the Where= one.
This bind mount is unnecessary and was causing trouble when bind mounting other resources
in /home or /usr/local.
Instead, a ConditionPathExists= option is added to control whether this mount happens.
This allows to hide mountpoints from Thunar sidebar (happens when bind mounting
a file or dir in $HOME).
@Guiiix Guiiix requested a review from marmarek February 27, 2025 21:09
@marmarek
Copy link
Member

A minor notes, potentially for the future:

  1. In commit messages have a blank line between a summary and details.
  2. Use 4 spaces for indentation, not 2 (I know the current bind-dirs.sh is quite inconsistent already).

@Guiiix
Copy link
Member Author

Guiiix commented Feb 27, 2025

Noticed, thank you for the clarification!

Comment on lines 110 to 113
test -d "$fso_rw" && mkdir --parents "$fso_ro"
test -f "$fso_rw" && touch "$fso_ro"
if [ -f "$fso_rw" ]; then
parent_directory="$(dirname "$fso_ro")"
test -d "$parent_directory" || mkdir --parents "$parent_directory"
Copy link
Member

Choose a reason for hiding this comment

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

Those two mkdirs are the ones that matter for owner/mode. But here you don't have the settings readily available... maybe you can read them $fso_rw parents (which is already created at this point)?

Copy link
Member Author

@Guiiix Guiiix Feb 27, 2025

Choose a reason for hiding this comment

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

Ah yes my commit is a nonsense...
What about letting this part intact, using mk_parent_dirs to create $path ($fso_ro) parents and mkdir -p to create $rw_path ($fso_rw) parents here:

echo "custom-persist: pre-creating file ${rw_path} with rights ${owner}:${group} ${mode}"
if [ ! -d "$parent_directory" ]; then
if ! mk_parent_dirs "$parent_directory" "$owner" "$group"; then
echo "Unable to create ${rw_path} parent dirs, skipping"
continue
fi
fi
touch "${rw_path}"
elif [ "$resource_type" = "dir" ]; then
echo "custom-persist: pre-creating directory ${rw_path} with rights ${owner}:${group} ${mode}"
if ! mk_parent_dirs "$rw_path" "$owner" "$group"; then
echo "Unable to create ${rw_path} parent dirs, skipping"
continue
fi
else
echo "Invalid entry ${target}, skipping"
continue
fi

EDIT: no, that would only work the first time when $fso_rw doesn't exist...

@marmarek
Copy link
Member

marmarek commented Mar 1, 2025

Thunar now don't show those dirs anymore :)

Generally I think it's all good now. I'll take a look at the whole diff one more, but should be okay.

I noticed one more potential issue - SELinux labels. new dirs have root_t type, instead of user_home_t (for directories in user home). But 1) it isn't anything new in this PR, it's how bind-dirs behave, and 2) user is running as unconfined anyway, so labels in user home don't matter that much.
This can be fixed later, if it turns out to cause issues.

@marmarek marmarek merged commit 01c68af into QubesOS:main Mar 1, 2025
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants