Merge "Support 4 dns servers, up from 2"
diff --git a/adb/Android.mk b/adb/Android.mk
index d6b0146..a803978 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -16,7 +16,8 @@
ifeq ($(HOST_OS),linux)
USB_SRCS := usb_linux.c
EXTRA_SRCS := get_my_path_linux.c
- LOCAL_LDLIBS += -lrt -lncurses -lpthread
+ LOCAL_LDLIBS += -lrt -ldl -lpthread
+ LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
endif
ifeq ($(HOST_OS),darwin)
@@ -140,7 +141,7 @@
ifneq ($(SDK_ONLY),true)
include $(CLEAR_VARS)
-LOCAL_LDLIBS := -lrt -lncurses -lpthread
+LOCAL_LDLIBS := -lrt -ldl -lpthread
LOCAL_SRC_FILES := \
adb.c \
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/aref.h b/include/cutils/aref.h
new file mode 100644
index 0000000..460ac02
--- /dev/null
+++ b/include/cutils/aref.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CUTILS_AREF_H_
+#define _CUTILS_AREF_H_
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+
+#ifdef ANDROID_SMP
+#include <cutils/atomic-inline.h>
+#else
+#include <cutils/atomic.h>
+#endif
+
+__BEGIN_DECLS
+
+#define AREF_TO_ITEM(aref, container, member) \
+ (container *) (((char*) (aref)) - offsetof(container, member))
+
+struct aref
+{
+ volatile int32_t count;
+};
+
+static inline void aref_init(struct aref *r)
+{
+ r->count = 1;
+}
+
+static inline int32_t aref_count(struct aref *r)
+{
+ return r->count;
+}
+
+static inline void aref_get(struct aref *r)
+{
+ android_atomic_inc(&r->count);
+}
+
+static inline void aref_put(struct aref *r, void (*release)(struct aref *))
+{
+ if (android_atomic_dec(&r->count) == 1)
+ release(r);
+}
+
+__END_DECLS
+
+#endif // _CUTILS_AREF_H_
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 2f5fdd3..bd48eff 100644
--- a/libnetutils/dhcp_utils.c
+++ b/libnetutils/dhcp_utils.c
@@ -216,7 +216,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/logwrapper/logwrapper.c b/logwrapper/logwrapper.c
index 3b876d4..dd777c0 100644
--- a/logwrapper/logwrapper.c
+++ b/logwrapper/logwrapper.c
@@ -35,14 +35,17 @@
void usage() {
fatal(
- "Usage: logwrapper BINARY [ARGS ...]\n"
+ "Usage: logwrapper [-d] BINARY [ARGS ...]\n"
"\n"
"Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
"the Android logging system. Tag is set to BINARY, priority is\n"
- "always LOG_INFO.\n");
+ "always LOG_INFO.\n"
+ "\n"
+ "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n"
+ " fault address is set to the status of wait()\n");
}
-void parent(const char *tag, int parent_read) {
+void parent(const char *tag, int seg_fault_on_exit, int parent_read) {
int status;
char buffer[4096];
@@ -102,6 +105,8 @@
} else
ALOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag,
strerror(errno), errno);
+ if (seg_fault_on_exit)
+ *(int *)status = 0; // causes SIGSEGV with fault_address = status
}
void child(int argc, char* argv[]) {
@@ -119,6 +124,7 @@
int main(int argc, char* argv[]) {
pid_t pid;
+ int seg_fault_on_exit = 0;
int parent_ptty;
int child_ptty;
@@ -128,6 +134,16 @@
usage();
}
+ if (strncmp(argv[1], "-d", 2) == 0) {
+ seg_fault_on_exit = 1;
+ argc--;
+ argv++;
+ }
+
+ if (argc < 2) {
+ usage();
+ }
+
/* Use ptty instead of socketpair so that STDOUT is not buffered */
parent_ptty = open("/dev/ptmx", O_RDWR);
if (parent_ptty < 0) {
@@ -163,7 +179,7 @@
setgid(AID_LOG);
setuid(AID_LOG);
- parent(argv[1], parent_ptty);
+ parent(argv[1], seg_fault_on_exit, parent_ptty);
}
return 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