netd: all: use system() instead of logwrap() for now.
The logwrapper uses a blocking read() which does not always
correctly detect when the child process at the other end is gone.
This is a quick workaround for http://b/5144246
A cleaner logwrapper parent() will follow.
Add support for BandwidthController() to use either system() or
logwrap(). It looks at "persist.bandwidth.uselogwrap" to be 0 or 1.
Change-Id: I2d17732214f1a7fef6838eee05d827695b707ab0
Signed-off-by: JP Abgrall <jpa@google.com>
diff --git a/BandwidthController.cpp b/BandwidthController.cpp
index 441818d..233c104 100644
--- a/BandwidthController.cpp
+++ b/BandwidthController.cpp
@@ -43,6 +43,7 @@
const char BandwidthController::IP6TABLES_PATH[] = "/system/bin/ip6tables";
const char BandwidthController::ALERT_IPT_TEMPLATE[] = "%s %s -m quota2 ! --quota %lld --name %s";
const int BandwidthController::ALERT_RULE_POS_IN_COSTLY_CHAIN = 4;
+bool BandwidthController::useLogwrapCall = false;
/**
* Some comments about the rules:
@@ -124,6 +125,8 @@
enableBandwidthControl();
}
+ property_get("persist.bandwidth.uselogwrap", value, "0");
+ useLogwrapCall = !strcmp(value, "1");
}
int BandwidthController::runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling) {
@@ -149,6 +152,7 @@
int argc = 0;
char *next = buffer;
char *tmp;
+ int res;
std::string fullCmd = cmd;
@@ -164,28 +168,33 @@
}
}
- argc = 0;
- argv[argc++] = iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH;
+ fullCmd.insert(0, " ");
+ fullCmd.insert(0, iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH);
- LOGD("runIptablesCmd(): %s %s", argv[0], fullCmd.c_str());
- if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) {
- LOGE("iptables command too long");
- return -1;
- }
-
- while ((tmp = strsep(&next, " "))) {
- argv[argc++] = tmp;
- if (argc >= MAX_CMD_ARGS) {
- LOGE("iptables argument overflow");
+ if (!useLogwrapCall) {
+ res = system(fullCmd.c_str());
+ } else {
+ if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) {
+ LOGE("iptables command too long");
return -1;
}
- }
- argv[argc] = NULL;
- /* TODO(jpa): Once this stabilizes, remove logwrap() as it tends to wedge netd
- * Then just talk directly to the kernel via rtnetlink.
- */
- return logwrap(argc, argv, 0);
+ argc = 0;
+ while ((tmp = strsep(&next, " "))) {
+ argv[argc++] = tmp;
+ if (argc >= MAX_CMD_ARGS) {
+ LOGE("iptables argument overflow");
+ return -1;
+ }
+ }
+
+ argv[argc] = NULL;
+ res = logwrap(argc, argv, 0);
+ }
+ if (res) {
+ LOGE("runIptablesCmd(): failed %s res=%d", fullCmd.c_str(), res);
+ }
+ return res;
}
int BandwidthController::enableBandwidthControl(void) {
diff --git a/BandwidthController.h b/BandwidthController.h
index 70a4e1e..3e45d40 100644
--- a/BandwidthController.h
+++ b/BandwidthController.h
@@ -93,6 +93,10 @@
int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
int removeCostlyAlert(const char *costName, int64_t *alertBytes);
+ /*
+ * When false, it will directly use system() instead of logwrap()
+ */
+ static bool useLogwrapCall;
private:
static const char *cleanupCommands[];
diff --git a/NatController.cpp b/NatController.cpp
index 6406b95..c05aa7b 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -41,29 +41,20 @@
}
int NatController::runIptablesCmd(const char *cmd) {
- char buffer[255];
+ char *buffer;
+ size_t len = strnlen(cmd, 255);
+ int res;
- strncpy(buffer, cmd, sizeof(buffer)-1);
-
- const char *args[16];
- char *next = buffer;
- char *tmp;
-
- args[0] = IPTABLES_PATH;
- args[1] = "--verbose";
- int i = 2;
-
- while ((tmp = strsep(&next, " "))) {
- args[i++] = tmp;
- if (i == 16) {
- LOGE("iptables argument overflow");
- errno = E2BIG;
- return -1;
- }
+ if (len == 255) {
+ LOGE("iptables command too long");
+ errno = E2BIG;
+ return -1;
}
- args[i] = NULL;
- return logwrap(i, args, 0);
+ asprintf(&buffer, "%s %s", IPTABLES_PATH, cmd);
+ res = system(buffer);
+ free(buffer);
+ return res;
}
int NatController::setDefaults() {
diff --git a/ThrottleController.cpp b/ThrottleController.cpp
index 41f9939..c7dfad8 100644
--- a/ThrottleController.cpp
+++ b/ThrottleController.cpp
@@ -42,28 +42,20 @@
extern "C" int ifc_down(const char *name);
int ThrottleController::runTcCmd(const char *cmd) {
- char buffer[255];
+ char *buffer;
+ size_t len = strnlen(cmd, 255);
+ int res;
- strncpy(buffer, cmd, sizeof(buffer)-1);
-
- const char *args[32];
- char *next = buffer;
- char *tmp;
-
- args[0] = TC_PATH;
- int i = 1;
-
- while ((tmp = strsep(&next, " "))) {
- args[i++] = tmp;
- if (i == 32) {
- LOGE("tc argument overflow");
- errno = E2BIG;
- return -1;
- }
+ if (len == 255) {
+ LOGE("tc command too long");
+ errno = E2BIG;
+ return -1;
}
- args[i] = NULL;
- return logwrap(i, args, 0);
+ asprintf(&buffer, "%s %s", TC_PATH, cmd);
+ res = system(buffer);
+ free(buffer);
+ return res;
}
int ThrottleController::setInterfaceThrottle(const char *iface, int rxKbps, int txKbps) {