VOGONS


mTCP NetDrive: network attached storage for DOS 2.0 or better

Topic actions

Reply 420 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

@Grzyb:

So to summarize, you have two machines that are fine with the 2025-01-10 code but fail when doing writes on this code. Can you send me the TCPDump with the packet data inside of it? I see the three reads and a write there but I'd like to see the hex of the commands to see if something unusual happened.

Also, can you try limiting the maximum write size to 1KB? That effectively turns off the large write feature and makes it look like the old code.

Edit: Ignore everything .. it's broken for me too, and I have no idea how I could have broken it this badly. Small updates and files work, but above a certain size writes do not work.

Last edited by mbbrutman on 2026-09-12, 02:59. Edited 2 times in total.

Reply 421 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

@Ringding

I love virtual machines ... they make this so easy to debug.

When the machine freezes it is actually in a spin loop waiting for a write command to complete. I see the exact instructions that it is sitting on and they line up with the code. Interrupts are disabled, which is a bad thing. The packet driver can't deliver a packet to NetDrive when interrupts are disabled and the timeout mechanism doesn't work because it is based on timer ticks, which also don't work with interrupts disabled.

I added some debug code to record the state of the flags on entry to my code and interrupts were disabled before my code started running. That is a bug in whatever disabled interrupts and then called DOS to do something. I'm going to bet that this code doesn't work on any network type of drive if it is doing this. It is not safe to call DOS with interrupts disabled. I added another instruction to re-enable interrupts in the device driver, and everything was fine. That's fine for debug purposes, but I'm not going to ship code like that because I don't know what disabled the interrupts and what it was trying to protect. So blindly re-enabling interrupts is not safe either.

I'd say use SmartDrv, but don't enable the write caching feature - it is either broken, or there is a bad interaction between it and the Borland IDE. The Borland IDE is running under DPMI so who knows where the interaction is.

Reply 422 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

@Grzyb

I think I know what is going on. The code is sending packets to the packet driver faster than the card can put them on the wire. This is resulting in truncated packets and errors sending packets. If you do "nd s d:" (or whatever your drive is) you will probably see a counter for "Packet send errors" that is above zero.

Try use the nd command to limit the size of writes to 8KB or even 4KB and the problem should go away, at the expense of reduced performance.

Why didn't I see this? Because I test either on a virtual machine or on a slow machine. I actually did see this happen on a P133 back a few months ago but I didn't figure out what was going on - now it makes sense. The P133 did have the problem, and limiting the write size fixed it.

Reply 423 of 432, by Grzyb

User metadata
Rank l33t
Rank
l33t
mbbrutman wrote on 2026-09-12, 03:51:

Try use the nd command to limit the size of writes to 8KB or even 4KB and the problem should go away, at the expense of reduced performance.

Better, but still not quite there:

The attachment mws4.png is no longer available

PERFECTION:

The attachment mws1.png is no longer available

BTW, I'm tired of running back and forth between the client and the server, to restart the server whenever I reboot the client.
I really could use something like "if the image is open RW, and the same IP tries to re-open it, then re-open it".

In 2003, I voted in favour of joining the European Union. However, due to later developments - especially the restrictions on cash usage - I have withdrawn my support. DOWN WITH THE EU!

Reply 424 of 432, by Grzyb

User metadata
Rank l33t
Rank
l33t
zuldan wrote on 2025-02-14, 21:33:

[3] Compatibility with the ODI driver so IPX multiplayer games can be run when mounting ISO’s via NetDrive

There are still some issues, but I already managed to run Doom from NetDrive disks on two machines, with IPX multiplayer...

.BAT

lsl
e100bodi
odipkt 0 0x60
ipxodi
nd connect ...

NET.CFG

Link Support
buffers 6 1600
Link Driver e100bodi
Frame Ethernet_II
Frame Ethernet_802.3
Protocol IPX 0 Ethernet_802.3

In 2003, I voted in favour of joining the European Union. However, due to later developments - especially the restrictions on cash usage - I have withdrawn my support. DOWN WITH THE EU!

Reply 425 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

@Grzyb When the large writes were failing, did you see an increase in the number of packet send errors as reported by the NetDrive status command? It is kind of important for me to know that if I'm going to craft a fix for this to make it faster. Being limited to 1KB writes is not really useful on a fast machine.

As for not wanting to walk and and forth to the server to kill dead sessions - use an image that is "session scoped." You can connect as many times as you need to, do writes, and even trash the image. As soon as you disconnect the changes disaspear. If you don't disconnect ending the server cleans everything out. The faster reconnect without explicitly disconnecting is on the todo list, but this will help you until that is ready.

Reply 426 of 432, by Grzyb

User metadata
Rank l33t
Rank
l33t
mbbrutman wrote on 2026-09-12, 13:46:

@Grzyb When the large writes were failing, did you see an increase in the number of packet send errors as reported by the NetDrive status command?

First, without pressing R(etry):

The attachment 1.png is no longer available
The attachment 2.png is no longer available

Reboot, connect as above, wait for "copy" to fail - the last traffic is:


01:05:37.553433 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 4112
01:05:37.553434 IP 192.168.0.102 > localhost.localdomain: udp
01:05:37.553434 IP 192.168.0.102 > localhost.localdomain: udp
01:05:37.553639 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16

Press R(etry) several times - no new traffic visible.

Press A(bort) - there is new traffic:


01:08:03.684770 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 528
01:08:03.685451 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16
01:08:03.687774 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 528
01:08:03.688197 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16
01:08:03.691211 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 528
01:08:03.691681 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16
01:08:03.694321 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 528
01:08:03.694752 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16
01:08:03.710710 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 22
01:08:03.711200 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 528
01:08:03.714296 IP 192.168.0.102.p2pgroup > localhost.localdomain.globe: UDP, length 528
01:08:03.714720 IP localhost.localdomain.globe > 192.168.0.102.p2pgroup: UDP, length 16
01:08:09.125515 ARP, Request who-has 192.168.0.102 tell localhost.localdomain, length 28
01:08:09.133644 ARP, Reply 192.168.0.102 is-at 00:80🇦🇩78:72:e7 (oui Unknown), length 46

The attachment 3.png is no longer available

As for not wanting to walk and and forth to the server to kill dead sessions - use an image that is "session scoped."

Very good idea - also resolves the problem of images being trashed with lost clusters due to incomplete writes!

In 2003, I voted in favour of joining the European Union. However, due to later developments - especially the restrictions on cash usage - I have withdrawn my support. DOWN WITH THE EU!

Reply 427 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

/Sigh ... your packet driver is not reporting the send errors. Mine does, but it would be nice if they all did - when I see a send error I could have it back off 1ms.

Anyway, I'll see what I can do with my P133. I might do something like let it burst 4 packets at a time, then insert 1ms delays for additional packets. Or I could set the default to be 4KB for writes, and to get them larger you need to set it explicitly.

Reply 428 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

@Grzyb,

Well, I've got a nice fix for my system. My packet driver gives me an error when it can't send a packet, so I can set a back-off time and insert a delay between packets. It's adaptive so the user doesn't have to know that it is happening - it just works. It won't work on your system that doesn't report the error.

I'm thinking of doing the following:

  • Set a reasonable default for fast systems. I think one half of a millisecond between "back to back" packet sends will work, but that is a guess.
  • Provide an option to specify "auto" or "adaptive", and assuming the packet driver reports errors correctly this will pick nearly the perfect delay.
  • Allow the user to force a specific delay.

Would you be interested in trying this out? If so, I'll send you a private build of the test code.

Reply 429 of 432, by doshea

User metadata
Rank Oldbie
Rank
Oldbie
mbbrutman wrote on 2026-09-12, 02:34:
@Ringding […]
Show full quote

@Ringding

I love virtual machines ... they make this so easy to debug.

When the machine freezes it is actually in a spin loop waiting for a write command to complete. I see the exact instructions that it is sitting on and they line up with the code. Interrupts are disabled, which is a bad thing. The packet driver can't deliver a packet to NetDrive when interrupts are disabled and the timeout mechanism doesn't work because it is based on timer ticks, which also don't work with interrupts disabled.

I added some debug code to record the state of the flags on entry to my code and interrupts were disabled before my code started running. That is a bug in whatever disabled interrupts and then called DOS to do something. I'm going to bet that this code doesn't work on any network type of drive if it is doing this. It is not safe to call DOS with interrupts disabled. I added another instruction to re-enable interrupts in the device driver, and everything was fine. That's fine for debug purposes, but I'm not going to ship code like that because I don't know what disabled the interrupts and what it was trying to protect. So blindly re-enabling interrupts is not safe either.

I'd say use SmartDrv, but don't enable the write caching feature - it is either broken, or there is a bad interaction between it and the Borland IDE. The Borland IDE is running under DPMI so who knows where the interaction is.

Ouch!

I looked through some old Borland technical information notes in the hope that this might have been a known issue. Unfortunately, all I found was this article, which describes how to do a clean boot, but still suggests running SMARTDRV without /X, so I guess they weren't aware of problems with it:

TI1566C.txt How to boot clean (under DOS and Windows) Category :General Platform :All Product :Borland C++ A […]
Show full quote

TI1566C.txt How to boot clean (under DOS and Windows)
Category :General
Platform :All
Product :Borland C++ All
...
C:\WINDOWS\SMARTDRV.EXE 1024 512

Unfortunately I didn't search all the tech notes I have - I really need to index them somehow!

Reply 430 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

I should correct something I wrote earlier ...

When something does INT 21h to invoke a DOS function interrupts are going to be disabled by the CPU, because that is what the INT instruction does. But DOS generally tries to re-enable interrupts fairly early. (It happens here in DOS 4: https://github.com/microsoft/MS-DOS/blob/2d04 … S/DISP.ASM#L299) Once DOS has re-enabled interrupts nothing else should disable interrupts and forget to turn them back on again, as doing so kills the keyboard, timer, network cards, etc.

I suspect that SmartDrv has the bug here. Normally SmartDrv is used with locally connected devices; it explicitly excludes network drives but it can't tell NetDrive is a network drive because NetDrive looks like a block mode device driver. The BIOS code for floppy drives and hard drives doesn't use IRQs, and there is probably an assumption that block mode device drives don't need IRQs either. So doing local device access with interrupts disabled works by accident, unless your local device actually needs interrupts to work.

Reply 431 of 432, by _Krille_

User metadata
Rank Newbie
Rank
Newbie

I've discovered that the RAMDrive created by NetDrive is not compatible with SMARTDrive (holy hell that's a lot of drives in one sentence) unless the element size is set to the minimum of 1024 bytes (e.g. SMARTDRV /E:1024 - See this for more info on SMARTDrive). Doing that kills the performance to the point where it's not worth using SMARTDrive and not doing it will hang the machine if trying to read the README.TXT on the RAMDrive (try for example 'type readme.txt'). I've been stepping through the code in DEBUG and when the DOS call to read the file (INT 21h, AH=3Fh) happens it will eventually end up in this never ending loop (CX is zero on entry);

(0) [0x000000007d15] 0766:06b5 (unk. ctxt): xor ah, ah ; 32e4
<bochs:2835>
Next at t=2231346881
(0) [0x000000007d17] 0766:06b7 (unk. ctxt): inc ah ; fec4
<bochs:2836>
Next at t=2231346882
(0) [0x000000007d19] 0766:06b9 (unk. ctxt): shr cx, 1 ; d1e9
<bochs:2837>
Next at t=2231346883
(0) [0x000000007d1b] 0766:06bb (unk. ctxt): jnb .-6 (0x00007d17) ; 73fa

Reply 432 of 432, by mbbrutman

User metadata
Rank Oldbie
Rank
Oldbie

That problem is fixed ... the RAM drive that NetDrive uses for a non-connected drive letter is now using a standard 512 byte sector size, which also fixes CHKDSK in FreeDOS which hated the non-standard sector size.