Change in titan.TestPorts.AF_PACKET[master]: add module parameter "sleep_on_enobufs" to work around -ENOBUFS

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Fri Jan 29 19:31:16 UTC 2021


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/titan.TestPorts.AF_PACKET/+/22539 )


Change subject: add module parameter "sleep_on_enobufs" to work around -ENOBUFS
......................................................................

add module parameter "sleep_on_enobufs" to work around -ENOBUFS

AF_PACKET sockets have these incredibly useful semantics in where
for both non-blocking and blocking I/O, they will tell you the
socket is rwite-able, but then still return -1 and sett errno=ENOBUFS
if the current socket buffer / transmit queue is full.

All we can do is usleep and retry.  The new module parameter, if set
to non-zero, determines the number of microseconds we shall sleep before
any retry.  If set to zero, the existing behavior is preserved:
TTCN_error().

Related: SYS#5343
Change-Id: I1608403d94a10ae52c7e1de0f1b02687b048c01e
---
M src/AF_PACKET_PT.cc
M src/AF_PACKET_PT.hh
2 files changed, 17 insertions(+), 5 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/titan.TestPorts.AF_PACKET refs/changes/39/22539/1

diff --git a/src/AF_PACKET_PT.cc b/src/AF_PACKET_PT.cc
index aa2def6..935f47c 100644
--- a/src/AF_PACKET_PT.cc
+++ b/src/AF_PACKET_PT.cc
@@ -108,6 +108,8 @@
 			mNetdev_name = NULL;
 		}
 		mNetdev_name = strdup(parameter_value);
+	} else if (!strcmp(parameter_name, "sleep_on_enobufs")) {
+		mSleepUsOnEnobufs = atoi(parameter_value);
 	} else
 		TTCN_error("Unsupported test port parameter `%s'.", parameter_name);
 }
@@ -204,13 +206,22 @@
 
 void AF__PACKET__PT_PROVIDER::outgoing_send(const AF__PACKET__Unitdata& send_par)
 {
-	int rc;
-
 	assert(mSocket >= 0);
 
-	rc = write(mSocket, send_par.data(), send_par.data().lengthof());
-	if (rc < send_par.data().lengthof())
-		TTCN_error("Short write on AF_PACKET socket: %s", strerror(errno));
+	while (true) {
+		int rc = write(mSocket, send_par.data(), send_par.data().lengthof());
+		if (rc == send_par.data().lengthof())
+			break;
+		if (mSleepUsOnEnobufs && rc == -1 && errno == -ENOBUFS) {
+			/* This is fscking insane.  Even select() would tell us the FD
+			 * is write-able, but then we still get -ENOBUFS.  The only way
+			 * to do this os to sleep. */
+			usleep(mSleepUsOnEnobufs);
+		} else if (rc < send_par.data().lengthof()) {
+			TTCN_error("Short write on AF_PACKET socket: %s", strerror(errno));
+			break;
+		}
+	}
 }
 
 
diff --git a/src/AF_PACKET_PT.hh b/src/AF_PACKET_PT.hh
index 7f8f6b5..ab3e8c6 100644
--- a/src/AF_PACKET_PT.hh
+++ b/src/AF_PACKET_PT.hh
@@ -50,6 +50,7 @@
 
 private:
 	char *mNetdev_name;		/* name of the network interface */
+	bool mSleepUsOnEnobufs;		/* how many us to sleep on ENOBUFS */
 	int mIfindex;			/* interface index of the network device */
 	int mSocket;			/* socket/file descriptor of the AF_PACKET socket */
 	uint8_t mRxBuf[2048];		/* read buffer */

-- 
To view, visit https://gerrit.osmocom.org/c/titan.TestPorts.AF_PACKET/+/22539
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: titan.TestPorts.AF_PACKET
Gerrit-Branch: master
Gerrit-Change-Id: I1608403d94a10ae52c7e1de0f1b02687b048c01e
Gerrit-Change-Number: 22539
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210129/9e912704/attachment.htm>


More information about the gerrit-log mailing list