XCP-ng
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    Xen Orchestra web UI becomes unresponsive when an NFS backup remote goes offline

    Scheduled Pinned Locked Moved Unsolved Xen Orchestra
    11 Posts 4 Posters 363 Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • F
      frb94
      last edited by

      Hi everyone,

      I am a very new user of XCPNG in my homelab. I think it's a fantastic product and i'm very happy with it. I have an issue that i did not find any reference online. I tried to troubleshoot it with my knowledge, but i did not go far. The following paragraph was written by chatgpt with the finding "we" had. It's all correct as far as i can tell.

      I'm experiencing a reproducible issue with Xen Orchestra when an NFS backup remote becomes unavailable.

      My backup storage is hosted on a Synology NAS configured with Auto Poweroff, which automatically shuts down the NAS after a period of inactivity.

      Xen Orchestra remains powered on 24/7.

      The expectation is that an unavailable backup remote should not affect the availability of the Xen Orchestra management interface, especially when no backup job is running.

      However, after the NAS has been powered off for some time, the entire XO web interface becomes unresponsive.

      After investigating the issue, I found that multiple Node.js libuv worker threads become blocked inside NFS kernel operations.

      Environment

      • Xen Orchestra: Installed from source (ronivay script)
      • XO build: xen-orchestra-202611011738 (November 1, 2026)
      • XO server: Linux, managed by systemd
      • XO server IP: 10.0.0.30
      • Backup storage: Synology NAS
      • NAS IP: 10.0.0.28
      • Remote type: NFS
      • NFS version: 4.0
      • NFS mount options: hard,timeo=600,retrans=2
      • NAS power management: Automatic shutdown after inactivity

      Steps to reproduce

      • Configure an NFS backup remote in Xen Orchestra.
      • Run backup jobs successfully.
      • Wait until all backup operations have finished.
      • Allow the Synology NAS to shut down automatically.
      • Keep Xen Orchestra running.
      • After some time, try opening the XO web interface.

      Same behaviour when trying to enable the already-disabled remote while nas is off.

      Observed result: Chrome keeps loading indefinitely, without displaying the login page.

      The issue occurs even when accessing XO directly by its IP address.

      Investigation

      1. The NFS mount remains active

      Even though the NAS is offline, the NFS remote remains mounted:

      10.0.0.28:/volume2/xobackup
      /run/xo-server/mounts/9fc232df-4d0c-4a15-93b5-c0585c1dd9c9
      nfs4 rw,vers=4.0,hard,proto=tcp,timeo=600,retrans=2

      The Linux kernel repeatedly reports:

      nfs: server 10.0.0.28 not responding, timed out
      nfs: server 10.0.0.28 not responding, still trying

      These messages continue for hours while the NAS is unavailable.

      1. XO remains running

      The service is still reported as active:

      xo-server.service - XO Server
      Active: active (running)
      Main PID: 729 (MainThread)

      The main Node.js thread is not blocked in NFS I/O:

      PID STAT WCHAN
      729 Ssl do_epoll_wait

      1. Multiple libuv workers are blocked

      This is the most interesting finding.

      Running:

      ps -T -p 729 -o pid,tid,stat,wchan:32,comm

      produces:

      PID TID STAT WCHAN COMMAND
      729 729 Ssl do_epoll_wait MainThread
      729 862 Dsl rpc_wait_bit_killable libuv-worker
      729 863 Dsl rpc_wait_bit_killable libuv-worker
      729 864 Dsl rpc_wait_bit_killable libuv-worker
      729 865 Dsl rpc_wait_bit_killable libuv-worker
      729 2840 Ssl futex_wait_queue libuv-worker

      Four libuv workers are blocked in uninterruptible sleep, waiting for NFS RPC operations.

      1. HTTP works without compression

      Interestingly, XO still responds correctly to uncompressed HTTP requests.

      From the XO machine:

      curl -k https://127.0.0.1/signin

      Result:

      HTTP: 200
      Time: 0.005740s

      From another Windows PC:

      curl.exe -k -v https://10.0.0.30/signin -o NUL

      Result:

      HTTP/1.1 200 OK
      Content-Length: 5664
      100 5664

      The entire HTML document is transferred successfully.

      1. HTTP compression hangs

      However, enabling HTTP compression causes the request to hang.

      From Windows:

      curl.exe -k -v --compressed --max-time 10 https://10.0.0.30/signin -o NUL

      Result:

      Accept-Encoding: deflate, gzip
      Request completely sent off

      Operation timed out after 10012 milliseconds
      with 0 bytes received

      The same behavior can be reproduced locally on the XO server using curl --compressed.

      This appears to explain why Chrome cannot display the login page, while basic uncompressed HTTP requests still succeed.

      1. XO logs reference backup remote operations

      The xo-server logs also show stack traces involving:

      BackupNg._listVmBackupsOnRemote
      BackupNg._listVmBackupsWithBackoff

      This suggests XO is attempting to access backup metadata on the unavailable remote.

      Possible root cause

      My hypothesis is that filesystem operations against the unavailable NFS hard mount block libuv worker threads.

      Node.js uses the libuv thread pool for asynchronous filesystem operations and some other operations, including zlib compression.

      If the available workers become blocked waiting for NFS RPC responses, HTTP compression tasks may be unable to complete.

      This would explain the observed behavior:

      • Uncompressed HTTP requests work.
      • Compressed HTTP requests hang.
      • The browser cannot load the GUI.
      • Several libuv workers are stuck in rpc_wait_bit_killable.

      I have confirmed the blocked workers and the compression-dependent HTTP timeout, but I have not yet confirmed the internal scheduling mechanism within Node.js.

      Recovery attempt

      I attempted to terminate the blocked worker threads with kill -9.

      This caused the main Node.js thread to enter a zombie state, while one worker remained blocked:

      PID TID STAT WCHAN
      729 729 Zsl -
      729 864 Dsl rpc_wait_bit_killable

      I also tried a lazy unmount:

      umount -l /run/xo-server/mounts/9fc232df-4d0c-4a15-93b5-c0585c1dd9c9

      The command completed, but the blocked worker remained in the same state.

      These were recovery experiments, not recommended procedures.

      Expected behavior

      Ideally, if an NFS backup remote becomes unavailable:

      • Backup operations involving that remote should report an error or remain isolated.
      • The management GUI should remain responsive.
      • Unrelated operations should continue functioning.
      • An unavailable backup repository should not exhaust the Node.js worker pool.
      • Temporary unavailability of the backup storage should not require force restarting the XO VM.

      Questions

      Is this a known issue with Xen Orchestra's handling of unavailable NFS remotes?

      Is there a recommended configuration for NFS repositories hosted on NAS devices that may power off automatically?

      Does Xen Orchestra periodically access or keep NFS remotes mounted even when no backup jobs are running?

      Would increasing UV_THREADPOOL_SIZE be a reasonable mitigation, or could filesystem operations still exhaust the larger pool?

      Could the remote filesystem operations be isolated from the main xo-server process to prevent this scenario?

      I would prefer to retain NFS hard mounts for backup integrity rather than switching to soft.

      I can provide additional logs and diagnostics if useful.

      Thanks!

      poddingueP 1 Reply Last reply
      Reply Quote 0
      • poddingueP
        poddingue Vates 🪐 @frb94
        last edited by

        This looks like the same thing @acebmxer ran into in July (https://xcp-ng.org/forum/topic/12339), and your libuv reading matches what the XO devs wrote in https://github.com/vatesfr/xen-orchestra/pull/10587.

        As I read their write-up, with a hard mount every background operation on the dead remote (listing backups, retries) holds one of xo-server's file-access threads until the NAS comes back, and once they're all taken the web UI can't be served either.

        Olivier's advice back then (https://xcp-ng.org/forum/post/106632) was to disable the remote while the NAS is still up and only then power it off, and acebmxer scripted that on the Synology so the remote gets disabled at shutdown and enabled again at startup through the XO API.

        If XO is already stuck, XO 6.10.0 added xo-server-db disable-remote <id>, which you run while xo-server is stopped so the remote isn't mounted again on the next start; your November 1 build should have it if I read the dates right, but I haven't tried it myself.

        About UV_THREADPOOL_SIZE I'm only guessing, but since a hung NFS call never gives its thread back I'd expect a bigger pool to just take longer to fill, and the PR says they tried capping the threads one remote can use and dropped the idea for now. @Team-XO-Backend will know better than me whether more is planned.

        F acebmxerA 2 Replies Last reply
        Reply Quote 1
        • F
          frb94 @poddingue
          last edited by

          @poddingue

          Thank you very much for the answer.

          This is my idea for now, but i'll look into better ways to do this.

          */5 * * * * /opt/scripts/enabledisableremote.sh
          
          #!/bin/bash
          
          export PATH="/usr/local/bin:/usr/bin:/bin:$HOME/.npm-global/bin:$PATH"
          
          REMOTE="9fc232df-4d0c-4a15-93b5-c0585c1dd9c9"
          NAS="10.0.0.28"
          
          # Stato attuale del Remote
          CURRENT=$(/usr/local/bin/xo-cli remote.getAll --json | jq -r --arg id "$REMOTE" '.[] | select(.id == $id) | .enabled')
          
          # Stato desiderato in base alla raggiungibilità del NAS
          if ping -c 1 -W 2 "$NAS" > /dev/null 2>&1; then
              DESIRED=true
          else
              DESIRED=false
          fi
          
          # Cambia stato solo se necessario
          if [[ "$CURRENT" == "true" || "$CURRENT" == "false" ]]; then
              if [[ "$CURRENT" != "$DESIRED" ]]; then
                  /usr/local/bin/xo-cli remote.set id="$REMOTE" enabled="$DESIRED"
              fi
          fi
          
          1 Reply Last reply
          Reply Quote 0
          • acebmxerA
            acebmxer @poddingue
            last edited by

            @poddingue @frb94

            Yes if I recall (I may not have stated on the forum) that I still ended up with issues and just abounded the idea. Not sure on the time line when they attempted a patch to when i stopped disabling the remote.

            F 1 Reply Last reply
            Reply Quote 1
            • F
              frb94 @acebmxer
              last edited by

              @acebmxer So what are you doing now? Given the manual, NFS is the way, but i can't have the remote available h24 and also i would like to have a functioning XO 😀

              acebmxerA poddingueP 2 Replies Last reply
              Reply Quote 1
              • acebmxerA
                acebmxer @frb94
                last edited by

                @frb94

                Just leaving it on 24/7 😞 winter is here now or so we thought (its 75f outside today) . If there is any update on this i would try again. but as it seems you are having the same issue i did then, it does not appear to be fixed.

                1 Reply Last reply
                Reply Quote 0
                • poddingueP poddingue marked this topic as a question
                • poddingueP
                  poddingue Vates 🪐 @frb94
                  last edited by

                  If you have the time, an issue on https://github.com/vatesfr/xen-orchestra/issues with your build date and that ps -T output would make the case better than I can.

                  F 2 Replies Last reply
                  Reply Quote 0
                  • F
                    frb94 @poddingue
                    last edited by

                    @poddingue Taking the time to do this it's the bare minium! Here you go: https://github.com/vatesfr/xen-orchestra/issues/10741

                    1 Reply Last reply
                    Reply Quote 0
                    • florentF
                      florent Vates 🪐 XO Team
                      last edited by

                      when a NFS munt in hard mount mode fails, it is quite tricky to handle on user land, and falling back to a soft mount means we accept to loose data without knowing

                      To unstuck a XO with a brken NFS , we added a cli tool that allow you to disable a remote here https://github.com/vatesfr/xen-orchestra/pull/10587

                      F 1 Reply Last reply
                      Reply Quote 0
                      • F
                        frb94 @florent
                        last edited by

                        @florent

                        I performed another test to reproduce the issue and evaluate the recovery mechanism introduced in PR #10587.

                        Unfortunately, I encountered a limitation that may prevent the new disable-remote command from being used in the exact failure scenario it is intended to address.

                        1. Reproducing the issue

                        With the NFS remote enabled, I shut down the NAS.

                        Initially, Xen Orchestra remained accessible, but one libuv worker became blocked in rpc_wait_bit_killable.

                        After some time, all four libuv workers were blocked:

                        TID  STAT  WCHAN                    COMMAND
                        863  Dsl   rpc_wait_bit_killable    libuv-worker
                        864  Dsl   rpc_wait_bit_killable    libuv-worker
                        865  Dsl   rpc_wait_bit_killable    libuv-worker
                        866  Dsl   rpc_wait_bit_killable    libuv-worker
                        

                        The xo-server process was still running, but the libuv worker pool was completely blocked.

                        I also observed multiple df -kP processes attempting to access the unavailable NFS mount.

                        2. Attempting to stop xo-server

                        I then executed:

                        systemctl stop xo-server
                        

                        However, systemd was unable to terminate the service, even after sending SIGKILL.

                        The final status was:

                        Active: failed (Result: timeout)
                        Main PID: 738
                        
                        Processes still around after SIGKILL. Ignoring.
                        State 'final-sigterm' timed out. Killing.
                        Killing process 738 (MainThread) with signal SIGKILL.
                        Processes still around after final SIGKILL. Entering failed mode.
                        Unit process 738 (MainThread) remains running after unit stopped.
                        

                        Checking the remaining process:

                        ps -p 738 -o pid,ppid,stat,wchan:32,comm
                        

                        Returned:

                        PID  PPID  STAT  WCHAN                    COMMAND
                        738     1  Ds    rpc_wait_bit_killable    MainThread
                        

                        All other Node.js threads had disappeared, but the main thread remained stuck in an uninterruptible kernel wait.

                        3. Attempting a lazy unmount

                        I then tried:

                        umount -l /run/xo-server/mounts/9fc232df-4d0c-4a15-93b5-c0585c1dd9c9
                        

                        The command completed successfully, and findmnt -t nfs,nfs4 no longer showed the NFS mount.

                        However, the Node.js process remained blocked:

                        PID  STAT  WCHAN                    COMMAND
                        738  Ds    rpc_wait_bit_killable    MainThread
                        

                        Therefore, detaching the NFS mount did not release the already pending kernel operation.

                        4. Implications for PR #10587

                        As I understand it, the new xo-server-db disable-remote <id> command is intended to be executed while xo-server is stopped.

                        However, this test shows that when an NFS hard remote becomes unavailable:

                        1. All four libuv workers can become blocked.
                        2. xo-server becomes unresponsive.
                        3. systemctl stop xo-server can fail, even after SIGKILL.
                        4. The Node.js process can remain stuck in an uninterruptible kernel wait.
                        5. Even umount -l does not necessarily release the blocked process.

                        5. Question about the intended recovery procedure

                        If xo-server cannot be fully stopped because its process remains stuck in state D, how is the new disable-remote command expected to be used safely?

                        Is the intended procedure to execute the database command while the old Node.js process is still present but systemd reports the service as failed?

                        Or is a VM reboot / restoration of NFS connectivity still required before the recovery command can be used?

                        I have not executed disable-remote in this condition yet, because the original Node.js process is still present and I wanted to avoid modifying the database while it might still be in use.

                        My concern is that the new CLI provides a way to prevent the problematic remote from being accessed on the next startup, but does not necessarily provide a complete recovery path when the existing xo-server process cannot terminate.

                        I would appreciate clarification on the intended recovery procedure for this specific scenario.

                        1 Reply Last reply
                        Reply Quote 0
                        • F
                          frb94 @poddingue
                          last edited by

                          @poddingue @florent

                          I really do not want to look like i'm not appreciating the platform. I am a sysadmin currently evaluating XCP-ng and Xen Orchestra as a replacement for VMware, and I have to say this issue is making me a bit concerned. Of course for now it's my homelab, but it is already a show stopper for me.

                          I understand that NFS hard mounts can block when the server goes offline, but I really wouldn't expect an unavailable backup repository to make the entire XO Web UI unresponsive, especially when no backup jobs are running.

                          To me, this feels like vCenter becoming unusable just because one of the backup repositories is down. That's a pretty big deal in a production environment. Also, i have not yet tested what happens to vms running on local SR and management plane of a host when the main NFS SR may become unavailable.

                          What worries me even more is that, as my tests showed, once XO gets stuck, even SIGKILL can't terminate the process, so recovering isn't straightforward either.

                          Am I missing something here? Is there something wrong with my setup, or is this actually expected behavior?

                          I really like XCP-ng and XO so far, but I'm trying to understand how companies handle this kind of situation in production. Surely a failed backup destination shouldn't take down the whole management interface?

                          1 Reply Last reply
                          Reply Quote 0

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better 💗

                          Register Login
                          • First post
                            Last post