-
Notifications
You must be signed in to change notification settings - Fork 120
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
failure to reconnect with -persist #93
Comments
Hi, TL;DR: Here is my experience with the -persist option of nbd-client, can you help me?I want to use NBD over an unreliable network connection. So I was trying to use nbd-client with the -persist option. A while ago somone on irc (#nbd on oftc.net) told me that -persist is broken on recent kernels and I should try to use -nonetlink (Thanks!). So I did that (using debian buster). I also started nbd-client with -nofork to get debug outputs. Test 1:I connected nbd, interrupted the network connection and nbd-client exited with
Okay, that's not what I wanted so I had a look at the sourcecode of nbd-client (debian source package nbd-3.19). Near the end of main(), there is this section that gets executed:
Okay, we are not on Kernel 2.4, my kernel version is 4.19. Test 2:I found out that ioctl returned 0 in case of a network disconnect. So I changed
to
and things got better. After a network disconnect, nbd-client tried to reconnect:
A connection retry was done about once per second. Yay! I restored my network connection and it worked:
Test 3:The test above was done without a mounted filesystem. Now I mounted a filesystem (readonly, via LUKS crypto) and tried it again. Unfortunately, the result was a little bit different. The kernel said it was busy and retries were attempted quickly after another. nbd-client printed:
The reconnect in nbd-client does not print an error, but the next iteration of
returns "Device or resource busy". Now I am at a point where I would need to debug or understand the kernel nbd driver, what I have not attempted yet. (__nbd_ioctl calls nbd_start_device_ioctl for NBD_DO_IT, this calls nbd_start_device, and this returns -EBUSY if nbd->task_recv is set. best regards, |
This is still an issue with version 3.18 |
I see the same behaviour as nand11 with version 3.21 |
I can confirm that there's no attempt to reconnect on 3.21. |
So. -persist uses an old quirk in the ioctl configuration interface that used to work at some point, but seems to have been lost after a few maintainer changes for the kernel module of nbd. The netlink interface does not have anything to support -persist; when using the netlink interface, nbd-client has exited long before the connection is dropped, and so there is no way for it to discover that this has happened. In order for -persist to work again, I think we need to go back to the drawing board. Meanwhile a possible workaround could be to use the multiple connection feature; if the connection drops, and you still have another connection open, then that allows you to continue working (but obviously that doesn't work if you only have one server and that one is being restarted). For now, I think I'll just disable -persist (better to not have a feature rather than one that does nothing), and talk to the kernel maintainer to see how we can fix this. |
In that case, would you also consider enabling timeout by default? From what I see, even if I don't use -persist, like
And the server reboots, I get a block device and nbd-client forever in D state, until I reboot. Seems like timeout is essential here. |
It's actually in the D state until the TCP timeout, which is a per-system setting that defaults to 2 hours and 12 minutes (IIRC). The timeout thing is another of those bad ideas that I should probably get rid of; it triggers if the device is perfectly happily connected but idle. This may be a good idea in some cases, but not in most. |
Well that would explain why my kiosks randomly fail (well, clearly not as random as I thought) if they sit idle for too long. How would I go about disabling the timeout? |
If you don't explicitly pass the -t or -timeout parameter to nbd-client, it shouldn't be set. If you still see things going wrong there, please file a (separate) bug. |
Wait, now I'm confused. The timeout is set by default, or by default it never times out? Cause at this point, this has become quite a problem for me, but I've never been able (or had enough time and patience) to really track it down. I'm not sure if my kiosks are failing from this timeout (seems to happen only during idle) or if it's a lucky network failure. I'm thinking of switching to ISCSI, but the CoW feature of NBD is very useful to me. (Does the timeout in nbd-server also close on idle?) |
Neither the client nor the server timeout should be set by default (which means neither should time out by default). The TCP keepalive probes are set, and it's not possible to switch them off. As long as the remote end is still functioning properly, these shouldn't interrupt your connection, however. |
Hi, is there any chance this is getting fixed in the near future, or a way to work around this issue ? I have setup backups on a remote server for my laptop, for this a wireguard VPN is setup between the hosts, and the server runs an nbd-server. |
A simple workaround is to make sure the connection never remains idle for too long. Just touching a file in the mounted NBD file system every once in a while should do that. |
That's a very sad situation, I was testing NBD as a really appealing candidate for remote backups, but ended up on this non-working persist situation, and the D state as well when timeout is not set. Yes I think we should rework all of this a few ways:
But this would only be used to make sure the timeout doesn't kill idle connections and actually only kills dead ones (killing idle connections didn't happen in my tests). The fact that the daemon cannot automatically reconnect by default with
Worse, it loops like crazy eating the CPU trying to do that in loops. I agree that it may become important to get back to the blackboard. It seems to me we're dealing with a bunch of chicken-and-egg problems here. Maybe we're just missing a "reconnect" operation to communicate with the kernel instead of the "connect" one, I don't know. |
Oh, this thread is still active? Then it may make sense to share my experience. I tried iscsi over an unreliable network connection and it worked. It is slow over this kind of network, as expected, but it can handle reconnects. I am using the standard debian packages targetcli-fb (server) and open-iscsi (client). For iscsi, the client demon iscsid does connection-level error processing. But I have not looked at the source code to see how things are handled differently between nbd and iscsi. |
Very interesting, thanks a lot for sharing your experience. That's definitely something I should have a look at! |
Many thanks @nand11 for your insights. I've followed some howtos (there are different server implementations so it may look confusing at first but "tgtd" did work fine). It worked very well, and in addition it's particularly robust to connection outage. I've unplugged links as well as removed/restored/changed IP address on the interface. There's a 5s timeout after which the connection is declared dead and is destroyed, then a new one is attempted via the regular paths, so that should resist rebooting firewalls and triple-play boxes silently changing IPs. I'll go that way now, even if the configuration is less trivial, it looks way more robust. Thanks again! |
This issue was affecting me pretty badly so I built an alternative |
Interesting to see some work still being done around this. However the choice of nodejs makes it a showstopper for many of us using embedded devices (typically where the full OS+config fits in a 16 MB NOR flash). But it likely has use cases in other environments. Now that I've got iscsi working (using much more complex components and configs), I have not yet figured if nbd still has some benefits (beyond its significant simplicity). |
Just in case anyone's interested here, I have migrated my setup to NVMe/TCP using nvmetcli for the server, and nvme-cli for the client. Reconnects work flawlessly if the problem doesn't present for too long (it stops retrying after 1h). |
Thanks for the info. I personally migrated to iSCSI instead, which is amazingly complicated but rock solid and never failed me once in one year despite multiple short and long network outages. Why does nvme-cli stop retrying after one hour ? Is it a config setting or anything else ? |
What are the practical use cases for nbd if it can't handle a simple server restart? Seems like a lot of coordination required to use nbd with this constraint. |
you can use netlink interface to reconfig the device, establish a new sock with server and pass the socket fd to device with NBD_CMD_RECONFIGURE but the thing is how to check if the sock that device hold is broken? I can't find a good way to do that maybe use a thread to periodically ping the server with the sock? |
What is the fix for this? I am investigating using this for XFS on top of S3. But it keeps erroring out in the nbd-client part and everything stops working. Is there a way to run iSCSI with S3 backing storage? |
On Mon, Aug 05, 2024 at 12:39:43PM -0700, Michael Conrad wrote:
What is the fix for this? I am investigating using this for XFS on top
of S3. But it keeps erroring out in the nbd-client part and everything
stops working. Is there a way to run iSCSI with S3 backing storage?
A kernel patch is (probably...) required.
When using the ioctl API, the -persist code will immediately try to
reconnect if the NBD_DO_IT ioctl exits with an error state. Previously,
the kernel was written such that the kernel would freeze all writes to
the NBD device until the nbd-client process exited, but I believe this
has been lost over a number of refactors (although I'm not entirely
sure of this). When using the netlink API, there is no opportunity to do
this as the nbd-client process immediately exits after setting up the
connection and does not wait for errors. So there would need to be a
monitor mode etc, which currently does not exist. So if this can still
work at all, you'll need to specify the -nonetlink option to nbd-client.
I have recently started working on the nbd driver in the kernel to
improve support of various things, and this is one of the things that
I'm planning on working on, but it will take a while.
In the mean time, if the -nonetlink option does not work, another option
could be to use multiple nbd connections to a single device (which
*only* works with the netlink interface... I know, I know). If doing
that, and a single connection to the server fails, then the second one
will still exist and the connection will not drop. See the -connections
(-C) option to nbd-client for details on that one.
…--
***@***.***{be,co.za}
wouter@{grep.be,fosdem.org,debian.org}
I will have a Tin-Actinium-Potassium mixture, thanks.
|
@yoe yoe, thanks for your work on nbd. I got excited as all the others in this thread have, for nbd's simplicity, mainly. It was very appealing for a scenario similar to that remote backup/LUKS thing someone else tried. I'm flatlining now as this persist option is still not working and reconnect is also still failing. So sad. A simple test setup with a vanishing nbd-server was enough. After nbd-server restarts it results in nbd-client ebusy errors and a blocking
So iSCSI it is. For now. Edit: version under test (VUT): server 1:3.23-3ubuntu1.22.04.1, client 1:3.26.1-1ubuntu0.1 |
This is still an issue with version 3.24 |
multipath seems to be a good choice, I will try to use this tool to solve the problem |
I still need to do a proper job getting logs together, but maybe someone can tell me I'm being dumb before I put too much time into this.
Currently, filesystems I have mounted from nbd devices panic on I/O failure if I restart the corresponding server. I would like nbd to renegotiate the connection if the server drops, and
-persist
seems to do the right thing . However, if I set up a test environment on the local machine and restart the server after connecting:The call simply returns, and does not attempt to reconnect. From the log message, it does not take the branch at
nbd/nbd-client.c
Line 1292 in 128fd55
nbd/nbd-client.c
Line 1329 in 128fd55
ioctl
call would return >= 0, but it seems to.I realize that the filesystem may also need some love to get the desired behavior, but that's moot if nbd does not renegotiate.
The text was updated successfully, but these errors were encountered: