<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/titan.TestPorts.AF_PACKET/+/22539">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add module parameter "sleep_on_enobufs" to work around -ENOBUFS<br><br>AF_PACKET sockets have these incredibly useful semantics in where<br>for both non-blocking and blocking I/O, they will tell you the<br>socket is rwite-able, but then still return -1 and sett errno=ENOBUFS<br>if the current socket buffer / transmit queue is full.<br><br>All we can do is usleep and retry.  The new module parameter, if set<br>to non-zero, determines the number of microseconds we shall sleep before<br>any retry.  If set to zero, the existing behavior is preserved:<br>TTCN_error().<br><br>Related: SYS#5343<br>Change-Id: I1608403d94a10ae52c7e1de0f1b02687b048c01e<br>---<br>M src/AF_PACKET_PT.cc<br>M src/AF_PACKET_PT.hh<br>2 files changed, 17 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/titan.TestPorts.AF_PACKET refs/changes/39/22539/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/AF_PACKET_PT.cc b/src/AF_PACKET_PT.cc</span><br><span>index aa2def6..935f47c 100644</span><br><span>--- a/src/AF_PACKET_PT.cc</span><br><span>+++ b/src/AF_PACKET_PT.cc</span><br><span>@@ -108,6 +108,8 @@</span><br><span>                         mNetdev_name = NULL;</span><br><span>                 }</span><br><span>            mNetdev_name = strdup(parameter_value);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else if (!strcmp(parameter_name, "sleep_on_enobufs")) {</span><br><span style="color: hsl(120, 100%, 40%);">+           mSleepUsOnEnobufs = atoi(parameter_value);</span><br><span>   } else</span><br><span>               TTCN_error("Unsupported test port parameter `%s'.", parameter_name);</span><br><span> }</span><br><span>@@ -204,13 +206,22 @@</span><br><span> </span><br><span> void AF__PACKET__PT_PROVIDER::outgoing_send(const AF__PACKET__Unitdata& send_par)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      assert(mSocket >= 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    rc = write(mSocket, send_par.data(), send_par.data().lengthof());</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc < send_par.data().lengthof())</span><br><span style="color: hsl(0, 100%, 40%);">-         TTCN_error("Short write on AF_PACKET socket: %s", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+ while (true) {</span><br><span style="color: hsl(120, 100%, 40%);">+                int rc = write(mSocket, send_par.data(), send_par.data().lengthof());</span><br><span style="color: hsl(120, 100%, 40%);">+         if (rc == send_par.data().lengthof())</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (mSleepUsOnEnobufs && rc == -1 && errno == -ENOBUFS) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* This is fscking insane.  Even select() would tell us the FD</span><br><span style="color: hsl(120, 100%, 40%);">+                         * is write-able, but then we still get -ENOBUFS.  The only way</span><br><span style="color: hsl(120, 100%, 40%);">+                        * to do this os to sleep. */</span><br><span style="color: hsl(120, 100%, 40%);">+                 usleep(mSleepUsOnEnobufs);</span><br><span style="color: hsl(120, 100%, 40%);">+            } else if (rc < send_par.data().lengthof()) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      TTCN_error("Short write on AF_PACKET socket: %s", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span> }</span><br><span> </span><br><span> </span><br><span>diff --git a/src/AF_PACKET_PT.hh b/src/AF_PACKET_PT.hh</span><br><span>index 7f8f6b5..ab3e8c6 100644</span><br><span>--- a/src/AF_PACKET_PT.hh</span><br><span>+++ b/src/AF_PACKET_PT.hh</span><br><span>@@ -50,6 +50,7 @@</span><br><span> </span><br><span> private:</span><br><span>  char *mNetdev_name;             /* name of the network interface */</span><br><span style="color: hsl(120, 100%, 40%);">+   bool mSleepUsOnEnobufs;         /* how many us to sleep on ENOBUFS */</span><br><span>        int mIfindex;                   /* interface index of the network device */</span><br><span>  int mSocket;                    /* socket/file descriptor of the AF_PACKET socket */</span><br><span>         uint8_t mRxBuf[2048];           /* read buffer */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/titan.TestPorts.AF_PACKET/+/22539">change 22539</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/titan.TestPorts.AF_PACKET/+/22539"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: titan.TestPorts.AF_PACKET </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1608403d94a10ae52c7e1de0f1b02687b048c01e </div>
<div style="display:none"> Gerrit-Change-Number: 22539 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>