Merge "Revert "Remove -d option from logwrapper""
diff --git a/adb/Android.mk b/adb/Android.mk
index d6b0146..1fca684 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -17,6 +17,7 @@
   USB_SRCS := usb_linux.c
   EXTRA_SRCS := get_my_path_linux.c
   LOCAL_LDLIBS += -lrt -lncurses -lpthread
+  LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
 endif
 
 ifeq ($(HOST_OS),darwin)
diff --git a/adb/adb.c b/adb/adb.c
index 4c3364f..8be5765 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -983,6 +983,33 @@
 #endif
 
 #if ADB_HOST
+
+#ifdef WORKAROUND_BUG6558362
+#include <sched.h>
+#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362"
+void adb_set_affinity(void)
+{
+   cpu_set_t cpu_set;
+   const char* cpunum_str = getenv(AFFINITY_ENVVAR);
+   char* strtol_res;
+   int cpu_num;
+
+   if (!cpunum_str || !*cpunum_str)
+       return;
+   cpu_num = strtol(cpunum_str, &strtol_res, 0);
+   if (*strtol_res != '\0')
+     fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR);
+
+   sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+   D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+   CPU_ZERO(&cpu_set);
+   CPU_SET(cpu_num, &cpu_set);
+   sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+   sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+   D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+}
+#endif
+
 int launch_server(int server_port)
 {
 #ifdef HAVE_WIN32_PROC
@@ -1186,6 +1213,10 @@
 
 #if ADB_HOST
     HOST = 1;
+
+#ifdef WORKAROUND_BUG6558362
+    if(is_daemon) adb_set_affinity();
+#endif
     usb_vendors_init();
     usb_init();
     local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h
index 1b3b762..eb44236 100644
--- a/include/cutils/bitops.h
+++ b/include/cutils/bitops.h
@@ -17,10 +17,79 @@
 #ifndef __CUTILS_BITOPS_H
 #define __CUTILS_BITOPS_H
 
+#include <stdbool.h>
+#include <string.h>
+#include <strings.h>
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
+/*
+ * Bitmask Operations
+ *
+ * Note this doesn't provide any locking/exclusion, and isn't atomic.
+ * Additionally no bounds checking is done on the bitmask array.
+ *
+ * Example:
+ *
+ * int num_resources;
+ * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
+ * bitmask_init(resource_bits, num_resources);
+ * ...
+ * int bit = bitmask_ffz(resource_bits, num_resources);
+ * bitmask_set(resource_bits, bit);
+ * ...
+ * if (bitmask_test(resource_bits, bit)) { ... }
+ * ...
+ * bitmask_clear(resource_bits, bit);
+ *
+ */
+
+#define BITS_PER_WORD    (sizeof(unsigned int) * 8)
+#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
+#define BIT_IN_WORD(x)   ((x) % BITS_PER_WORD)
+#define BIT_WORD(x)      ((x) / BITS_PER_WORD)
+#define BIT_MASK(x)      (1 << BIT_IN_WORD(x))
+
+static inline void bitmask_init(unsigned int *bitmask, int num_bits)
+{
+    memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
+}
+
+static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
+{
+    int bit, result;
+    unsigned int i;
+
+    for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
+        bit = ffs(~bitmask[i]);
+        if (bit) {
+            // ffs is 1-indexed, return 0-indexed result
+            bit--;
+            result = BITS_PER_WORD * i + bit;
+            if (result >= num_bits)
+                return -1;
+            return result;
+        }
+    }
+    return -1;
+}
+
+static inline void bitmask_set(unsigned int *bitmask, int bit)
+{
+    bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
+}
+
+static inline void bitmask_clear(unsigned int *bitmask, int bit)
+{
+    bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
+}
+
+static inline bool bitmask_test(unsigned int *bitmask, int bit)
+{
+    return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
+}
+
 static inline int popcount(unsigned int x)
 {
     return __builtin_popcount(x);
diff --git a/init/devices.c b/init/devices.c
index dd875d6..b07a1a6 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -881,8 +881,8 @@
         sehandle = selinux_android_file_context_handle();
     }
 
-    /* is 64K enough? udev uses 16MB! */
-    device_fd = uevent_open_socket(64*1024, true);
+    /* is 256K enough? udev uses 16MB! */
+    device_fd = uevent_open_socket(256*1024, true);
     if(device_fd < 0)
         return;
 
diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c
index a59de0d..d0f1315 100644
--- a/libnetutils/dhcp_utils.c
+++ b/libnetutils/dhcp_utils.c
@@ -217,7 +217,7 @@
                  p2p_interface, DHCP_CONFIG_PATH, prop_value, interface);
     else
         snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s %s", DAEMON_NAME,
-                 DHCP_CONFIG_PATH, p2p_interface, interface);
+                 p2p_interface, DHCP_CONFIG_PATH, interface);
     memset(prop_value, '\0', PROPERTY_VALUE_MAX);
     property_set(ctrl_prop, daemon_cmd);
     if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d4baab4..bee0729 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -120,6 +120,12 @@
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000
 
+# qtaguid will limit access to specific data based on group memberships.
+#   net_bw_acct grants impersonation of socket owners.
+#   net_bw_stats grants access to other apps' detailed tagged-socket stats.
+    chown root net_bw_acct /proc/net/xt_qtaguid/ctrl
+    chown root net_bw_stats /proc/net/xt_qtaguid/stats
+
 # Allow everybody to read the xt_qtaguid resource tracking misc dev.
 # This is needed by any process that uses socket tagging.
     chmod 0644 /dev/xt_qtaguid