Configuring vmnet_read_max_packets_key and vmnet_write_max_packets_key

Hi,

I have couple of inquiries regarding the vmnet framework:

  1. Incorporating Global Variables:

    • How should we integrate the new global variables in macOS 15.0+ vmnet_read_max_packets_key and vmnet_write_max_packets_key into our configuration to optimize packet transmission? Are those values populated dynamically or manually if so any recommended value ranges ?
  2. Buffer Allocation Issue:

    • What strategies can we employ to mitigate this buffer allocation error and ensure more reliable packet transmission? We occasionally encounter the following error during packet writes:
      Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved."  Error Domain=NSPOSIXErrorDomain Code=55 "No buffer space available"

Your insights on these matters would be greatly appreciated.

Answered by DTS Engineer in 821866022

vmnet_read_max_packets_key is a property key for the interface_desc dictionary you pass to vmnet_start_interface. Quoting the doc comments, it controls the maximum value that *pktcnt may have in the call to vmnet\_read().

Historically there was an arbitrary limit to this. AFAICT that limit was 200. You can now use vmnet_read_max_packets_key to configure that limit yourself, although I believe the upper bound isn’t much bigger, namely, 256.

Likewise for vmnet_write_max_packets_key.


Written by i3z in 772725021
We occasionally encounter the following error during packet writes

For context, error 55 is ENOBUFS.

What routine is returning that error? vmnet_write?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

vmnet_read_max_packets_key is a property key for the interface_desc dictionary you pass to vmnet_start_interface. Quoting the doc comments, it controls the maximum value that *pktcnt may have in the call to vmnet\_read().

Historically there was an arbitrary limit to this. AFAICT that limit was 200. You can now use vmnet_read_max_packets_key to configure that limit yourself, although I believe the upper bound isn’t much bigger, namely, 256.

Likewise for vmnet_write_max_packets_key.


Written by i3z in 772725021
We occasionally encounter the following error during packet writes

For context, error 55 is ENOBUFS.

What routine is returning that error? vmnet_write?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the explanation!

What routine is returning that error? vmnet_write?

The error happens when I try to write the data from vmnet_read to the VM's file descriptor, for example, when downloading a set of packages from the Internet using shared mode.

The first thing I did was set up the dictionary with the vmnet_read_max_packets_key and vmnet_write_max_packets_key as suggested. However, I noticed that after starting the interface, I’m unable to retrieve the set values—they always return 0.

I’ve also experimented with different values, whether below the suggested limit, higher, or even very low unsigned integers, but there doesn’t seem to be any noticeable effect. That said, I’m able to set other keys and retrieve their values without any issues, so this behavior seems specific to these particular keys.

To further investigate, I started the interface without adding those keys, and here’s what I observed when sending packets back to the vm:

  • First round (233 packets) – All packets were delivered successfully without any issue.

  • Second round (63 packets) – Again, all packets were delivered successfully.

  • Third round (10 packets) – One packet failed with the error: "No buffer space available." The rest were delivered successfully.

This suggests that the system was able to handle 233 and 63 packets without any issues, but when sending 10 packets, the "No buffer space available" error occurred randomly, regardless of the number of estimated packets.

It’s puzzling because even in the case of 233 packets, they were all delivered, which exceeds the previous 200-packet historical limit (now 256). Take a look at the logs below:

Estimated packets: 233
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
... etc all delivered 
Estimated packets: 63
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
... etc all delivered 
Estimated packets: 10
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  632 bytes
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes

Here is another example

Estimated packets: 8
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
> TX  632 bytes
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
Estimated packets: 25
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  632 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
ENOBUFS
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1284 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes
> TX  1506 bytes

Note: TCP has built-in mechanisms to handle retransmissions of dropped packets, but other protocols might not have such error recovery, leading to potential data loss or incomplete transfers.

If you have any insights or suggestions, I’d be grateful for your thoughts on this.

Configuring vmnet_read_max_packets_key and vmnet_write_max_packets_key
 
 
Q