Drbd resource out of sync after node reboot: what to do next?

I’ve now finished updating a three-node Proxmox+linstor/drbd cluster, which is now on PVE 9.2.21, drbd 9.3.4, linstor 1.35.2

At the end of this upgrade, I needed to reboot node virtual5 to go from kernel 7.0.14-22-pve to 7.0.14-23-pve (Proxmox have released a new kernel in the last couple of days). I moved all the VMs off and rebooted it.

However, one of the volumes, which is primary on virtual6 and secondary on virtual1 and virtual5, has gone slightly out of sync. dmesg on virtual6 showed the following when virtual5 reconnected:

[202913.274911] drbd pm-4b8bd822/0 drbd1017 virtual5: expected n_oos:93 to be 0

which was also reflected in Prometheus metrics and drbdadm status:

drbd_peerdevice_outofsync_bytes{conn_name="virtual5", instance="virtual6.nsrc.org", job="linstor-node", name="pm-4b8bd822", node="virtual6", peer_node_id="1", volume="0"} 380928

brian@virtual6:~$ sudo drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:60262872 written:27087784
  virtual1 role:Secondary
    peer-disk:UpToDate
        received:0 sent:915403
  virtual5 role:Secondary
    peer-disk:UpToDate
        received:0 sent:357467 out-of-sync:372

(93 x 4K blocks = 372 x 1K blocks = 380928 bytes)

I left it overnight, and this morning did an online verify. The number of out-of-sync blocks has reduced from 93 to 71, but it’s still clearly not in sync.

[243430.785626] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify done (total 596 sec; paused 0 sec; 87976 K/sec)
[243430.785936] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify found 71 4k blocks out of sync!

Questions

  1. What’s my next step to resolve this safely? I am thinking that I’d probably need to do drbdadm invalidate or drbdadm outdate on the secondary (virtual5) but I’m not sure of the difference between these commands.
  2. Is there something that I should have done to prevent this? For example, should I do drbdadm down all on a node just before rebooting it? Or are the systemd units in drbd-utils doing this already?
  3. Should this have happened at all, given that drbd on both nodes is the latest 9.3.4? Is it worth digging down further into the underlying cause?

Additional info

Full kernel logs from both the reboot (disconnect/reconnect) and the online verify are here: https://gist.github.com/candlerb/ce5d5dd7d904773bf53cea8ec9f6a4f9

Oddly, I’m seeing no messages of the form “Out of sync: start=XXX, size=YYY (sectors)” which means I can’t do a manual check of the affected blocks as per this thread.

General config:

brian@virtual1:~$ linstor v l -r pm-4b8bd822
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Resource    │ Node     │ StoragePool │ VolNr │ MinorNr │ DeviceName    │ Allocated │ InUse  │    State │ Repl           │
╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ pm-4b8bd822 │ virtual1 │ sata_ssd    │     0 │    1017 │ /dev/drbd1017 │ 50.02 GiB │ Unused │ UpToDate │ Established(2) │
│ pm-4b8bd822 │ virtual5 │ sata_ssd    │     0 │    1017 │ /dev/drbd1017 │ 50.02 GiB │ Unused │ UpToDate │ Established(2) │
│ pm-4b8bd822 │ virtual6 │ sata_ssd    │     0 │    1017 │ /dev/drbd1017 │ 50.02 GiB │ InUse  │ UpToDate │ Established(2) │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

brian@virtual5:~$ uname -a
Linux virtual5 7.0.14-23-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-23 (2026-10-07T20:25Z) x86_64 GNU/Linux
brian@virtual5:~$ cat /sys/module/drbd/version
9.3.4
brian@virtual5:~$ dpkg-query -l | egrep -i 'drbd|linstor'
hi  drbd-dkms                            9.3.4-1                              all          RAID 1 over TCP/IP for Linux module source
hi  drbd-reactor                         1.12.0-1                             amd64        Monitors DRBD resources via plugins.
hi  drbd-utils                           9.35.0-1                             amd64        RAID 1 over TCP/IP for Linux (user utilities)
ii  linstor-client                       1.29.1-1                             all          Linstor client command line tool
hi  linstor-common                       1.35.2-1                             all          DRBD distributed resource management utility
hi  linstor-controller                   1.35.2-1                             all          DRBD distributed resource management utility
ii  linstor-gui                          2.6.0-1                              all          Administration GUI for LINSTOR clusters.
ii  linstor-proxmox                      8.3.2-1                              all          DRBD distributed resource management utility
hi  linstor-satellite                    1.35.2-1                             all          DRBD distributed resource management utility
ii  python-linstor                       1.29.1-1                             all          Linstor python api library
brian@virtual5:~$ sudo drbdadm dump pm-4b8bd822
# resource pm-4b8bd822 on virtual5: not ignored, not stacked
# defined at /var/lib/linstor.d/pm-4b8bd822.res:10
resource pm-4b8bd822 {
    on virtual5 {
        node-id 1;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/sata_ssd/pm-4b8bd822_00000;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual1 {
        node-id 0;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual6 {
        node-id 2;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    connection {
        host virtual5         address         ipv4 10.0.0.5:7017;
        host virtual1         address         ipv4 10.0.0.1:7017;
        net {
            _name        virtual1;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
    connection {
        host virtual5         address         ipv4 10.0.0.5:7017;
        host virtual6         address         ipv4 10.0.0.6:7017;
        net {
            _name        virtual6;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
    options {
        on-no-quorum     io-error;
        quorum           majority;
    }
    net {
        cram-hmac-alg    sha1;
        shared-secret    XXXXXXXX;
        allow-two-primaries yes;
        verify-alg       sha256;
    }
}


brian@virtual6:~$ uname -a
Linux virtual6 7.0.14-23-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-23 (2026-10-07T20:25Z) x86_64 GNU/Linux
brian@virtual6:~$ cat /sys/module/drbd/version
9.3.4
brian@virtual6:~$ dpkg-query -l | egrep -i 'drbd|linstor'
hi  drbd-dkms                            9.3.4-1                              all          RAID 1 over TCP/IP for Linux module source
hi  drbd-reactor                         1.12.0-1                             amd64        Monitors DRBD resources via plugins.
hi  drbd-utils                           9.35.0-1                             amd64        RAID 1 over TCP/IP for Linux (user utilities)
ii  linstor-client                       1.29.1-1                             all          Linstor client command line tool
hi  linstor-common                       1.35.2-1                             all          DRBD distributed resource management utility
hi  linstor-controller                   1.35.2-1                             all          DRBD distributed resource management utility
ii  linstor-gui                          2.6.0-1                              all          Administration GUI for LINSTOR clusters.
ii  linstor-proxmox                      8.3.2-1                              all          DRBD distributed resource management utility
hi  linstor-satellite                    1.35.2-1                             all          DRBD distributed resource management utility
ii  python-linstor                       1.29.1-1                             all          Linstor python api library
brian@virtual6:~$ sudo drbdadm dump pm-4b8bd822
# resource pm-4b8bd822 on virtual6: not ignored, not stacked
# defined at /var/lib/linstor.d/pm-4b8bd822.res:10
resource pm-4b8bd822 {
    on virtual6 {
        node-id 2;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/sata_ssd/pm-4b8bd822_00000;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual1 {
        node-id 0;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual5 {
        node-id 1;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    connection {
        host virtual6         address         ipv4 10.0.0.6:7017;
        host virtual1         address         ipv4 10.0.0.1:7017;
        net {
            _name        virtual1;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
    connection {
        host virtual6         address         ipv4 10.0.0.6:7017;
        host virtual5         address         ipv4 10.0.0.5:7017;
        net {
            _name        virtual5;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
    options {
        on-no-quorum     io-error;
        quorum           majority;
    }
    net {
        cram-hmac-alg    sha1;
        shared-secret    XXXXXXXX;
        allow-two-primaries yes;
        verify-alg       sha256;
    }
}

I also note that Linstor did produce some error reports at the time that virtual5 was rebooted:

brian@virtual1:~$ linstor error-reports list
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Id                    │ Datetime            │ Node       │ Exception                                                          │
╞═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ 6ACBBCF7-B63BE-000000 │ 2026-10-11 18:33:26 │ S|virtual5 │ ResourceException: Failed to adjust DRBD resource linstor_db       │
│ 6ACBBCF7-B63BE-000001 │ 2026-10-11 18:33:27 │ S|virtual5 │ ResourceException: Failed to adjust DRBD resource pm-4628dd67      │
│ 6ACBBCF7-B63BE-000002 │ 2026-10-11 18:33:28 │ S|virtual5 │ StorageException: Failed to query symlinks of device /dev/drbd1013 │
│ 6ACBBCF7-B63BE-000003 │ 2026-10-11 18:33:28 │ S|virtual5 │ StorageException: Failed to query symlinks of device /dev/drbd1008 │
│ 6ACBBCF7-B63BE-000004 │ 2026-10-11 18:33:28 │ S|virtual5 │ StorageException: Failed to query symlinks of device /dev/drbd1009 │
│ 6ACBBCF7-B63BE-000005 │ 2026-10-11 18:33:28 │ S|virtual5 │ StorageException: Failed to query symlinks of device /dev/drbd1011 │
│ 6ACBBCF7-B63BE-000006 │ 2026-10-11 18:33:29 │ S|virtual5 │ StorageException: Failed to query symlinks of device /dev/drbd1018 │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

However, I presume these were transient as the satellite came online: for example, the missing /dev/drbdXXXX devices are now present. And the two ResourceException resources are not the one which has gone out of sync. So I don’t think this is related.


Aside: it would be nice if Linstor could report on out-of-sync volumes, and/or schedule periodic online verify - if it already can, I’ve not found it. I only see a mention in passing the manual: “Perhaps you have to run nightly online verifications of your volumes’ consistency” which talks about configuring verify-alg.

I re-ran the verify on virtual5. I notice now that because I am not specifying the peer device, it’s verifying against both peers (the primary and the other secondary):

root@virtual5:/home/brian# drbdadm status pm-4b8bd822 --statistics; dmesg | grep pm-4b8bd822 | tail
pm-4b8bd822 role:Secondary
  disk:UpToDate open:no
      read:106608840 written:16151692
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:53.51
        received:70504 sent:0
  virtual6 role:Primary
    replication:VerifyS peer-disk:UpToDate done:48.45
        received:3692615 sent:0

On completion, this time on virtual6 I see it’s down to 52 x 4K blocks out of sync (=208KiB), plus one unchecked.

[249258.737309] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( Established -> VerifyT ) [remote]
[249258.743356] drbd pm-4b8bd822/0 drbd1017: Online Verify start sector: 0
[249899.743978] drbd pm-4b8bd822/0 drbd1017 virtual5: Skipped verify, too busy: start=69746488, size=8 (sectors)
[249899.752671] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify done but 1 4k blocks skipped (total 641 sec; paused 0 sec; 81800 K/sec)
[249899.753164] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify found 52 4k blocks out of sync!
[249899.753402] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( VerifyT -> Established ) [resync-finished]
[249899.753647] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync
[249899.757719] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync exit code 0

Hmm. Then I ran drbdadm verify pm-4b8bd822 again, but this time on the primary (virtual6). And I see that the out-of-sync counter goes down as it progresses!

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:220332591 written:42437689
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:1.48
        received:0 sent:4285867
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:1.46
        received:0 sent:3727931 out-of-sync:208

(wait a bit)

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:231487399 written:42444431
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:12.06
        received:0 sent:4288982
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:12.15
        received:0 sent:3731045 out-of-sync:192

(wait a bit more)

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:245276729 written:42451648
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:25.23
        received:0 sent:4293374
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:25.28
        received:0 sent:3735438 out-of-sync:172

(wait some more)

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:282749323 written:42472428
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:62.02
        received:0 sent:4308654
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:59.94
        received:0 sent:3750718 out-of-sync:148

(nearly done)

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:322886908 written:42496302
  virtual1 role:Secondary
    peer-disk:UpToDate
        received:0 sent:4324438
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:98.50
        received:0 sent:3766502 out-of-sync:104

(finished)

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Primary
  disk:UpToDate open:yes
      read:323674180 written:42497546
  virtual1 role:Secondary
    peer-disk:UpToDate
        received:0 sent:4325409
  virtual5 role:Secondary
    peer-disk:UpToDate
        received:0 sent:3767473 out-of-sync:104

root@virtual6:/home/brian# dmesg | grep pm-4b8bd822 | tail
[250093.855804] drbd pm-4b8bd822: Committing cluster-wide state change 626715118 (16ms)
[250093.856144] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( Established -> VerifyS ) [verify]
[250093.856437] drbd pm-4b8bd822/0 drbd1017 virtual5: Starting Online Verify from sector 0
[250675.776442] drbd pm-4b8bd822/0 drbd1017 virtual1: Online verify done (total 581 sec; paused 0 sec; 90244 K/sec)
[250675.776457] drbd pm-4b8bd822/0 drbd1017 virtual1: repl( VerifyS -> Established ) [resync-finished]
[250691.576684] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify done (total 597 sec; paused 0 sec; 87828 K/sec)
[250691.577073] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify found 26 4k blocks out of sync!
[250691.577351] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( VerifyS -> Established ) [resync-finished]
[250691.585988] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync
[250691.589351] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync exit code 0

Down to 26 x 4KiB blocks out of sync now. (Coincidentally, exactly half the number before?!)

I really don’t know what’s going on here. Pure guesses:

  • Perhaps the affected blocks are “hot” and being overwritten anyway, and therefore healing the problems as a side effect? However, I left it for about 11 hours after the initial sync problem, and the number of OOS 4K blocks only dropped from 93 to 71 on the first verify. Each subsequent verify seems to reduce the errors further.
  • Perhaps the online verify is seing ghost errors for blocks which are being actively replicated? But then I wouldn’t expect the number of mismatched blocks to keep going down.

This is actually getting very weird (but interesting).

The following day, I ran drbdadm verify three more times. The out-of-sync:N KiB dropped to 80, then 56, then 44. Another day I ran it again, and it dropped to just 20.

Today I decided to halt the VM entirely and use a small python prog (below) to compare the underlying disk in 16K chunks (on each machine: ./verify.py >pre-virtualX)

I was expecting virtual5 to be different: after all, this is the one reporting out-of-sync with virtual6.

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Secondary
  disk:UpToDate open:no
      read:607568698 written:117425945
  virtual1 role:Secondary
    peer-disk:UpToDate
        received:0 sent:45401829
  virtual5 role:Secondary
    peer-disk:UpToDate
        received:0 sent:44843893 out-of-sync:20

Surprisingly, what I found was that virtual1 was different.

root@virtual1:/home/brian# shasum pre-virtual1
e6085cefad3b5bacddeb96dc5214d1edba9787e0  pre-virtual1
root@virtual5:/home/brian# shasum pre-virtual5
bf6102faed58679e3b5e31c2f5bc6020360702ea  pre-virtual5
root@virtual6:/home/brian# shasum pre-virtual6
bf6102faed58679e3b5e31c2f5bc6020360702ea  pre-virtual6

With the VM still stopped, I did another drbdadm verify on virtual6:

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Secondary
  disk:UpToDate open:no
      read:655179006 written:117425945
  virtual1 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:46.02
        received:0 sent:45401829
  virtual5 role:Secondary
    replication:VerifyS peer-disk:UpToDate done:44.77
        received:0 sent:44843893 out-of-sync:20

... wait until finished ...

root@virtual6:/home/brian# drbdadm status pm-4b8bd822 --statistics
pm-4b8bd822 role:Secondary
  disk:UpToDate open:no
      read:712446058 written:117425945
  virtual1 role:Secondary
    peer-disk:UpToDate
        received:0 sent:45401829
  virtual5 role:Secondary
    peer-disk:UpToDate
        received:0 sent:44843893 out-of-sync:20

Note that the count of out-of-sync KiB has not changed. Then I re-ran the python as ./verify.py >post-virtualX:

root@virtual1:/home/brian# shasum post-virtual1
206413fe65434373d9df7bb2ca5363a4245d4e9b  post-virtual1      # this has changed!!
root@virtual5:/home/brian# shasum post-virtual5
bf6102faed58679e3b5e31c2f5bc6020360702ea  post-virtual5
root@virtual6:/home/brian# shasum post-virtual6
bf6102faed58679e3b5e31c2f5bc6020360702ea  post-virtual6

And finally, restarted the VM so I can spend some time analyzing the results.

Mismatch reports

Firstly, I note that the message in dmesg shows the count of 4K blocks which don’t match, but does not report specifically which blocks are out of sync (which I’m sure older versions of drbd9 did). Is this now hidden behind some flag?

root@virtual6:/home/brian# dmesg | tail -20
[515804.948017] drbd pm-4b8bd822: role( Primary -> Secondary ) [kvm:2475224 auto-demote]
[515805.148367] tap112i0: left allmulticast mode
[515805.148736] vmbr0: port 5(tap112i0) entered disabled state
[516068.431896] drbd pm-4b8bd822: Preparing cluster-wide state change 583518440: 2->0 repl( VerifyS )
[516068.436769] drbd pm-4b8bd822: State change 583518440: primary_nodes=0, weak_nodes=0
[516068.437023] drbd pm-4b8bd822: Committing cluster-wide state change 583518440 (5ms)
[516068.437335] drbd pm-4b8bd822/0 drbd1017 virtual1: repl( Established -> VerifyS ) [verify]
[516068.437616] drbd pm-4b8bd822/0 drbd1017 virtual1: Starting Online Verify from sector 0
[516068.438880] drbd pm-4b8bd822: Preparing cluster-wide state change 1542661374: 2->1 repl( VerifyS )
[516068.450457] drbd pm-4b8bd822: State change 1542661374: primary_nodes=0, weak_nodes=0
[516068.450680] drbd pm-4b8bd822: Committing cluster-wide state change 1542661374 (12ms)
[516068.450915] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( Established -> VerifyS ) [verify]
[516068.451161] drbd pm-4b8bd822/0 drbd1017 virtual5: Starting Online Verify from sector 0
[516619.010132] drbd pm-4b8bd822/0 drbd1017 virtual1: Online verify done (total 550 sec; paused 0 sec; 95332 K/sec)
[516619.010421] drbd pm-4b8bd822/0 drbd1017 virtual1: repl( VerifyS -> Established ) [resync-finished]
[516634.063230] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify done (total 565 sec; paused 0 sec; 92800 K/sec)
[516634.063509] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify found 5 4k blocks out of sync!
[516634.063755] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( VerifyS -> Established ) [resync-finished]
[516634.063979] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync
[516634.067059] drbd pm-4b8bd822/0 drbd1017 virtual5: helper command: /sbin/drbdadm out-of-sync exit code 0

Secondly, this message seems to be saying that the mismatch is with virtual5 (as does drbdadm status --statistics). But my own verify compared virtual5 == virtual6, with virtual1 different. This means I find it very hard to trust what drbdadm is telling me.

This in turn makes me wonder: is there any chance I have I got the IP addresses of the nodes the wrong way round??! (only external public IPs elided below).

root@virtual6:/home/brian# drbdadm dump pm-4b8bd822
# resource pm-4b8bd822 on virtual6: not ignored, not stacked
# defined at /var/lib/linstor.d/pm-4b8bd822.res:10
resource pm-4b8bd822 {
    on virtual6 {
        node-id 2;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/sata_ssd/pm-4b8bd822_00000;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual1 {
        node-id 0;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    on virtual5 {
        node-id 1;
        volume 0 {
            disk {
                discard-granularity 4096;
                discard-zeroes-if-aligned  no;
                rs-discard-granularity 4096;
            }
            device       minor 1017;
            disk         /dev/drbd/this/is/not/used;
            meta-disk    internal;
            tiebreaker   yes;
        }
    }
    connection {
        host virtual6         address         ipv4 10.0.0.6:7017;
        host virtual1         address         ipv4 10.0.0.1:7017;
        net {
            _name        virtual1;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
    connection {
        host virtual6         address         ipv4 10.0.0.6:7017;
        host virtual5         address         ipv4 10.0.0.5:7017;
        net {
            _name        virtual5;
            allow-two-primaries yes;
            verify-alg   sha256;
        }
    }
...
}

root@virtual1:/home/brian# ip a | grep 'inet '
    inet 127.0.0.1/8 scope host lo
    inet 10.0.0.1/24 scope global ens7f1np1.99
    inet 10.0.1.1/24 scope global ens7f0np0.97
    inet 10.0.2.1/24 scope global ens7f1np1.98
    inet XXX.XXX.XXX.32/25 scope global vmbr0

root@virtual5:/home/brian# ip a | grep 'inet '
    inet 127.0.0.1/8 scope host lo
    inet 10.0.0.5/24 scope global ens1f1.99
    inet 10.0.1.5/24 scope global ens1f0.97
    inet 10.0.2.5/24 scope global ens1f1.98
    inet XXX.XXX.XXX.49/25 scope global vmbr0

root@virtual6:/home/brian# ip a | grep 'inet '
    inet 127.0.0.1/8 scope host lo
    inet 10.0.0.6/24 scope global ens1f1.99
    inet 10.0.1.6/24 scope global ens1f0.97
    inet 10.0.2.6/24 scope global ens1f1.98
    inet XXX.XXX.XXX.50/25 scope global vmbr0

root@virtual1:/home/brian# linstor node interface list virtual1 -p
+-------------------------------------------------------------------+
| virtual1  | NetInterface | IP             | Port | EncryptionType |
|===================================================================|
| + StltCon | default      | XXX.XXX.XXX.32 | 3366 | PLAIN          |
| +         | drbd         | 10.0.0.1       |      |                |
+-------------------------------------------------------------------+
root@virtual1:/home/brian# linstor node interface list virtual5 -p
+-------------------------------------------------------------------+
| virtual5  | NetInterface | IP             | Port | EncryptionType |
|===================================================================|
| + StltCon | default      | XXX.XXX.XXX.49 | 3366 | PLAIN          |
| +         | drbd         | 10.0.0.5       |      |                |
+-------------------------------------------------------------------+
root@virtual1:/home/brian# linstor node interface list virtual6 -p
+-------------------------------------------------------------------+
| virtual6  | NetInterface | IP             | Port | EncryptionType |
|===================================================================|
| + StltCon | default      | XXX.XXX.XXX.50 | 3366 | PLAIN          |
| +         | drbd         | 10.0.0.6       |      |                |
+-------------------------------------------------------------------+

root@virtual1:/home/brian# linstor node list-properties virtual1 -p
+----------------------------+
| Key             | Value    |
|============================|
| CurStltConnName | default  |
| NodeUname       | virtual1 |
| PrefNic         | drbd     |
+----------------------------+
... others match

No, this all looks fine to me.

So why is dmesg and drbdadm telling me that virtual5 and virtual6 mismatch? Am I totally misreading this output?

In any case, this is something which should be possible to reproduce. I wonder if the mapping between numeric node id and node name is not right.

Differences between virtual1 and virtual5/6

I’m pretty sure the drbd metadata is at the end of the logical volume, so I compared only the start of the logical volume, up to the size of the /dev/drbd1017 device. And for efficiency I used 16K blocks instead of 4K.

At the start, virtual1 and virtual6 differed in three places:

root@virtual6:/home/brian# diff -u pre-virtual1 pre-virtual6
--- pre-virtual1	2026-10-15 03:09:37.793108960 -0700
+++ pre-virtual6	2026-10-15 02:32:43.566749521 -0700
@@ -318,7 +318,7 @@
 897256b
 897256b
 897256b
-4c2701f
+3c70951
 b9c3102
 897256b
 897256b
@@ -7102,7 +7102,7 @@
 897256b
 897256b
 897256b
-d0fd6b9
+75b283a
 7af228f
 7da29fa
 4f0caaf
@@ -23486,7 +23486,7 @@
 897256b
 897256b
 897256b
-d19bf3f
+45220dd
 a869b48
 26a73cb
 ff9dad1

After the verify, they differ in only one place (the first one)

root@virtual6:/home/brian# diff -u pre-virtual6 post-virtual6
root@virtual6:/home/brian# diff -u post-virtual1 post-virtual6
--- post-virtual1	2026-10-15 03:09:32.298078211 -0700
+++ post-virtual6	2026-10-15 02:46:12.640257030 -0700
@@ -318,7 +318,7 @@
 897256b
 897256b
 897256b
-4c2701f
+3c70951
 b9c3102
 897256b
 897256b

(which could be no more than 4 x 4K total differences, even though drbd still says 5 x 4K mismatch). Also note that 897256b is the sha1sum of 16KB all zeros.

But the data returned by virtual1 itself changed after the verify:

root@virtual6:/home/brian# diff -u pre-virtual1 post-virtual1
--- pre-virtual1	2026-10-15 03:09:37.793108960 -0700
+++ post-virtual1	2026-10-15 03:09:32.298078211 -0700
@@ -7102,7 +7102,7 @@
 897256b
 897256b
 897256b
-d0fd6b9
+75b283a
 7af228f
 7da29fa
 4f0caaf
@@ -23486,7 +23486,7 @@
 897256b
 897256b
 897256b
-d19bf3f
+45220dd
 a869b48
 26a73cb
 ff9dad1

At this point, I have to entertain the theory that the SSD on virtual1 is returning varying data. This is a plain LVM going direct to SSD: there is no underlying RAID controller or suchlike, and it’s a standard “thick” logical volume.

root@virtual1:/home/brian# pvs
  PV         VG       Fmt  Attr PSize   PFree
  /dev/sda   sata_ssd lvm2 a--  894.25g   8.00m
  /dev/sdb   sata_ssd lvm2 a--  894.25g  <3.90g
  /dev/sdc   sata_ssd lvm2 a--  894.25g 417.78g
  /dev/sdd   sata_ssd lvm2 a--  894.25g 742.24g
root@virtual1:/home/brian# lvs | grep pm-4b8bd822
  pm-4b8bd822_00000 sata_ssd -wi-ao----  <50.02g
root@virtual1:/home/brian# lvs -a --segments -o +seg_pe_ranges | grep pm-4b8bd822
  pm-4b8bd822_00000           sata_ssd -wi-ao----    1 linear      10.00g /dev/sdb:163423-165983
  pm-4b8bd822_00000           sata_ssd -wi-ao----    1 linear      10.00g /dev/sdb:171106-173666
  pm-4b8bd822_00000           sata_ssd -wi-ao----    1 linear     <30.01g /dev/sdc:178806-186487

However, I would find this theory much easier to entertain if I could trust the output from drbdadm verify telling me which disks don’t match.

I think my next step is to try and replicate the drbd verify peer-naming issue - unless someone can first explain to me how I’m misinterpreting the logs I’m seeing. And once I understand what’s going on there, I can return to potential SSD hardware problems.

Regards,

Brian.


Python code

Here’s the python script verify.py

#!/usr/bin/python3
import hashlib

SRC="/dev/sata_ssd/pm-4b8bd822_00000"
LIMIT=53692358656   # this is the volume size reported by `blockdev --getsize64 /dev/drbd1017`
CHUNK=16384

n = LIMIT
with open(SRC,"rb") as f:
    while n > 0:
        bs = min(n, CHUNK)
        n -= bs
        data = f.read(bs)
        if len(data) != bs:
            raise RuntimeError(f"Wanted {bs}, got {len(data)}")
        h = hashlib.new('sha1')
        h.update(data)
        print(h.hexdigest()[0:7])

Sigh: here’s the final outcome.

With some VM testing I realised that dd goes via the VFS cache: for example if you intentionally corrupt some data with a dd write to the LVM volume, then get drbd to repair it, then a dd read from LVM still shows the corrupt data unless you do iflag=direct.

I also wondered if this had something to do with flash block sizes. So I stopped the production VM again, and checked the contents of all three disks using iflags=direct with four different block sizes:

dd if=/dev/sata_ssd/pm-4b8bd822_00000 iflag=direct bs=4k | ...
dd if=/dev/sata_ssd/pm-4b8bd822_00000 iflag=direct bs=16k | ...
dd if=/dev/sata_ssd/pm-4b8bd822_00000 iflag=direct bs=128k | ...
dd if=/dev/sata_ssd/pm-4b8bd822_00000 iflag=direct bs=128M | ...

(again, limiting to the size of the drbd user volume, and taking hashes). All of them returned exactly the same data. Across all three nodes!

Then I re-ran drbdadm verify on virtual6 (the primary). It still reported the same small number of mismatches:

[611987.599036] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify found 5 4k blocks out of sync!

Since the VM was stopped, I brought the resource down and up, then re-verified:

drbdadm down pm-4b8bd822
drbdadm up pm-4b8bd822
drbdadm verify pm-4b8bd822

although somewhat scarily, this fixed the problem by resyncing the 5 supposedly out-of-date blocks (I’m not entire sure which direction it synced them in)

[612276.649364] drbd pm-4b8bd822/0 drbd1017 virtual5: pdsk( Outdated -> Inconsistent ) repl( WFBitMapS -> SyncSource ) replication( yes -> no ) [receive-bitmap]
[612276.650105] drbd pm-4b8bd822/0 drbd1017 virtual5: Began resync as SyncSource (will sync 20 KB [5 bits set]).

...
[612313.680660] drbd pm-4b8bd822/0 drbd1017: meta-data IO uses: blk-bio
[612313.681143] drbd pm-4b8bd822/0 drbd1017: Meta data written without the bitmap provenance feature; all out-of-sync bits toward node(s) 0x3 count as set with reason
[612313.681694] drbd pm-4b8bd822/0 drbd1017: disk( Diskless -> Attaching ) [attach]
[612313.681960] drbd pm-4b8bd822/0 drbd1017: Maximum number of peer devices = 7
[612313.682444] drbd pm-4b8bd822: Method to ensure write ordering: flush
[612313.682688] drbd pm-4b8bd822/0 drbd1017: Allocating 11204 KiB for new bitmap
[612313.685497] drbd pm-4b8bd822/0 drbd1017: resync bitmap: bits=13108486 bits_4k=13108486 words=1433747 pages=2801
[612313.707046] drbd pm-4b8bd822/0 drbd1017: bitmap READ of 2801 pages took 22 ms
[612313.715244] drbd pm-4b8bd822/0 drbd1017: recounting of set bits took additional 8ms
[612313.716001] drbd1017: detected capacity change from 0 to 104867888
[612313.716664] drbd pm-4b8bd822/0 drbd1017: size = 50 GB (52433944 KB)

Aside: “Meta data written without the bitmap provenance feature”: can I upgrade the metadata of an existing volume, or would it need to be recreated>

I also note “recounting of set bits”. And this time, the verify reports no out of sync blocks:

[613008.654908] drbd pm-4b8bd822/0 drbd1017 virtual1: Online verify done (total 582 sec; paused 0 sec; 90092 K/sec)
[613008.655247] drbd pm-4b8bd822/0 drbd1017 virtual1: repl( VerifyS -> Established ) [resync-finished]
[613019.428443] drbd pm-4b8bd822/0 drbd1017 virtual5: Online verify done (total 592 sec; paused 0 sec; 88568 K/sec)
[613019.428770] drbd pm-4b8bd822/0 drbd1017 virtual5: repl( VerifyS -> Established ) [resync-finished]

At this point there’s no longer any visible problem, and therefore I can’t debug this strangeness any further. I wonder if there’s some drift between the stored out-of-sync blocks count, and the actual out-of-sync blocks? This is the only way I can explain not seeing “Out of sync: start=N, size=M” messages in kernel logs, because in a test environment, I see these are generated on every verify pass for as long as there’s mismatched data.

The SSD weirdness I was seeing might be because I was reading data directly from the LVM volume (without iflag=direct), instead of going via /dev/drbdXXXX. I did this because I didn’t want any chance of drbd redirecting the I/O to another node. However, once a block has been read and is in VFS cache, if drbd changes it on disk, the VFS cache is stale; a subsequent read from LVM without iflag=direct is misleading.

I now have to close this as “can’t reproduce”. But maybe in future I’ll build all pools with ZFS mirroring beneath them, to allow for healing of data errors.