am 823ebc4d: charger: dump the last_kmsg when going into charger mode
* commit '823ebc4d824ea70e5ec7d376adf2fbce50eb9cb2':
charger: dump the last_kmsg when going into charger mode
diff --git a/adb/commandline.c b/adb/commandline.c
index 75f337b..973932f 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -1419,16 +1419,19 @@
if (*argv[i] != '-') {
file_arg = i;
break;
+ } else if (!strcmp(argv[i], "-i")) {
+ // Skip the installer package name.
+ i++;
} else if (!strcmp(argv[i], "-s")) {
where = SD_DEST;
}
}
if (file_arg < 0) {
- fprintf(stderr, "can't find filename in arguments");
+ fprintf(stderr, "can't find filename in arguments\n");
return 1;
} else if (file_arg + 2 < argc) {
- fprintf(stderr, "too many files specified; only takes APK file and verifier file");
+ fprintf(stderr, "too many files specified; only takes APK file and verifier file\n");
return 1;
}
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index a59431b..06f21dd 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -98,7 +98,7 @@
// T & A Mobile Phones' USB Vendor ID
#define VENDOR_ID_T_AND_A 0x1BBB
// LenovoMobile's USB Vendor ID
-#define VENDOR_ID_LENOVOMOBILE 0x2006
+#define VENDOR_ID_LENOVOMOBILE 0x2006
// Lenovo's USB Vendor ID
#define VENDOR_ID_LENOVO 0x17EF
// Vizio's USB Vendor ID
@@ -109,6 +109,8 @@
#define VENDOR_ID_PEGATRON 0x1D4D
// Archos's USB Vendor ID
#define VENDOR_ID_ARCHOS 0x0E79
+// Positivo's USB Vendor ID
+#define VENDOR_ID_POSITIVO 0x1662
/** built-in vendor list */
@@ -150,6 +152,7 @@
VENDOR_ID_K_TOUCH,
VENDOR_ID_PEGATRON,
VENDOR_ID_ARCHOS,
+ VENDOR_ID_POSITIVO,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/charger/Android.mk b/charger/Android.mk
index ba21a9b..5367a98 100644
--- a/charger/Android.mk
+++ b/charger/Android.mk
@@ -1,5 +1,7 @@
# Copyright 2011 The Android Open Source Project
+ifneq ($(BUILD_TINY_ANDROID),true)
+
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@@ -44,3 +46,5 @@
_add-charger-image :=
_img_modules :=
+
+endif
diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h
index 83891cd..cae112b 100644
--- a/include/arch/linux-arm/AndroidConfig.h
+++ b/include/arch/linux-arm/AndroidConfig.h
@@ -190,7 +190,7 @@
* with a memory address. If not defined, stack crawls will not have symbolic
* information.
*/
-#define HAVE_DLADDR 0
+#define HAVE_DLADDR 1
/*
* Defined if we have the cxxabi.h header for demangling C++ symbols. If
diff --git a/include/netutils/ifc.h b/include/netutils/ifc.h
index 575e72e..67a4a45 100644
--- a/include/netutils/ifc.h
+++ b/include/netutils/ifc.h
@@ -38,9 +38,13 @@
extern int ifc_get_addr(const char *name, in_addr_t *addr);
extern int ifc_set_addr(const char *name, in_addr_t addr);
-extern int ifc_get_prefixLength(const char *name, uint32_t *prefixLength);
-extern int ifc_set_prefixLength(const char *name, uint32_t prefixLength);
+extern int ifc_add_address(const char *name, const char *address,
+ int prefixlen);
+extern int ifc_del_address(const char *name, const char *address,
+ int prefixlen);
+extern int ifc_set_prefixLength(const char *name, int prefixLength);
extern int ifc_set_hwaddr(const char *name, const void *ptr);
+extern int ifc_clear_addresses(const char *name);
/* This function is deprecated. Use ifc_add_route instead. */
extern int ifc_add_host_route(const char *name, in_addr_t addr);
@@ -53,9 +57,10 @@
extern int ifc_remove_default_route(const char *ifname);
extern int ifc_add_route(const char *name, const char *addr, int prefix_length,
const char *gw);
-
-extern int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask,
- in_addr_t *flags);
+extern int ifc_remove_route(const char *ifname, const char *dst,
+ int prefix_length, const char *gw);
+extern int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength,
+ unsigned *flags);
extern int ifc_configure(const char *ifname, in_addr_t address,
uint32_t prefixLength, in_addr_t gateway,
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h
index d6bb7d5..7d2b1d6 100644
--- a/include/sysutils/SocketClient.h
+++ b/include/sysutils/SocketClient.h
@@ -8,6 +8,7 @@
class SocketClient {
int mSocket;
+ bool mSocketOwned;
pthread_mutex_t mWriteMutex;
/* Peer process ID */
@@ -24,8 +25,8 @@
int mRefCount;
public:
- SocketClient(int sock);
- virtual ~SocketClient() {}
+ SocketClient(int sock, bool owned);
+ virtual ~SocketClient();
int getSocket() { return mSocket; }
pid_t getPid() const { return mPid; }
diff --git a/init/init.c b/init/init.c
index af88f30..7b4a963 100755
--- a/init/init.c
+++ b/init/init.c
@@ -92,7 +92,7 @@
int add_environment(const char *key, const char *val)
{
int n;
-
+
for (n = 0; n < 31; n++) {
if (!ENV[n]) {
size_t len = strlen(key) + strlen(val) + 2;
@@ -156,7 +156,7 @@
*/
svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET));
svc->time_started = 0;
-
+
/* running processes require no additional work -- if
* they're in the process of exiting, we've ensured
* that they will immediately restart on exit, unless
@@ -381,7 +381,7 @@
svc = service_find_by_name(tmp);
}
-
+
if (svc) {
service_start(svc, args);
} else {
@@ -455,38 +455,6 @@
}
}
-static void import_kernel_cmdline(int in_qemu)
-{
- char cmdline[1024];
- char *ptr;
- int fd;
-
- fd = open("/proc/cmdline", O_RDONLY);
- if (fd >= 0) {
- int n = read(fd, cmdline, 1023);
- if (n < 0) n = 0;
-
- /* get rid of trailing newline, it happens */
- if (n > 0 && cmdline[n-1] == '\n') n--;
-
- cmdline[n] = 0;
- close(fd);
- } else {
- cmdline[0] = 0;
- }
-
- ptr = cmdline;
- while (ptr && *ptr) {
- char *x = strchr(ptr, ' ');
- if (x != 0) *x++ = 0;
- import_kernel_nv(ptr, in_qemu);
- ptr = x;
- }
-
- /* don't expose the raw commandline to nonpriv processes */
- chmod("/proc/cmdline", 0440);
-}
-
static struct command *get_first_command(struct action *act)
{
struct listnode *node;
@@ -609,7 +577,7 @@
char tmp[PROP_VALUE_MAX];
if (qemu[0])
- import_kernel_cmdline(1);
+ import_kernel_cmdline(1, import_kernel_nv);
if (!strcmp(bootmode,"factory"))
property_set("ro.factorytest", "1");
@@ -729,13 +697,14 @@
*/
open_devnull_stdio();
klog_init();
-
+
INFO("reading config file\n");
init_parse_config_file("/init.rc");
/* pull the kernel commandline and ramdisk properties file in */
- import_kernel_cmdline(0);
-
+ import_kernel_cmdline(0, import_kernel_nv);
+ /* don't expose the raw commandline to nonpriv processes */
+ chmod("/proc/cmdline", 0440);
get_hardware_name(hardware, &revision);
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
init_parse_config_file(tmp);
diff --git a/init/ueventd.c b/init/ueventd.c
index ddf42be..ecf3b9b 100644
--- a/init/ueventd.c
+++ b/init/ueventd.c
@@ -33,6 +33,20 @@
static char hardware[32];
static unsigned revision = 0;
+static void import_kernel_nv(char *name, int in_qemu)
+{
+ if (*name != '\0') {
+ char *value = strchr(name, '=');
+ if (value != NULL) {
+ *value++ = 0;
+ if (!strcmp(name,"androidboot.hardware"))
+ {
+ strlcpy(hardware, value, sizeof(hardware));
+ }
+ }
+ }
+}
+
int ueventd_main(int argc, char **argv)
{
struct pollfd ufd;
@@ -51,6 +65,11 @@
INFO("starting ueventd\n");
+ /* Respect hardware passed in through the kernel cmd line. Here we will look
+ * for androidboot.hardware param in kernel cmdline, and save its value in
+ * hardware[]. */
+ import_kernel_cmdline(0, import_kernel_nv);
+
get_hardware_name(hardware, &revision);
ueventd_parse_config_file("/ueventd.rc");
diff --git a/init/util.c b/init/util.c
index fd4bee2..13c9ca2 100755
--- a/init/util.c
+++ b/init/util.c
@@ -399,3 +399,33 @@
}
}
}
+
+void import_kernel_cmdline(int in_qemu,
+ void (*import_kernel_nv)(char *name, int in_qemu))
+{
+ char cmdline[1024];
+ char *ptr;
+ int fd;
+
+ fd = open("/proc/cmdline", O_RDONLY);
+ if (fd >= 0) {
+ int n = read(fd, cmdline, 1023);
+ if (n < 0) n = 0;
+
+ /* get rid of trailing newline, it happens */
+ if (n > 0 && cmdline[n-1] == '\n') n--;
+
+ cmdline[n] = 0;
+ close(fd);
+ } else {
+ cmdline[0] = 0;
+ }
+
+ ptr = cmdline;
+ while (ptr && *ptr) {
+ char *x = strchr(ptr, ' ');
+ if (x != 0) *x++ = 0;
+ import_kernel_nv(ptr, in_qemu);
+ ptr = x;
+ }
+}
diff --git a/init/util.h b/init/util.h
index 2e47369..9247739 100644
--- a/init/util.h
+++ b/init/util.h
@@ -38,4 +38,5 @@
int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);
void get_hardware_name(char *hardware, unsigned int *revision);
+void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu));
#endif
diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk
index 1ef7da9..5f5849f 100644
--- a/libnetutils/Android.mk
+++ b/libnetutils/Android.mk
@@ -6,10 +6,10 @@
dhcpmsg.c \
dhcp_utils.c \
ifc_utils.c \
- packet.c
+ packet.c
LOCAL_SHARED_LIBRARIES := \
- libcutils
+ libcutils
LOCAL_MODULE:= libnetutils
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index c482736..0a2f760 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -26,15 +26,18 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
+#include <netdb.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
-#include <linux/sockios.h>
+#include <linux/netlink.h>
#include <linux/route.h>
#include <linux/ipv6_route.h>
-#include <netdb.h>
-#include <linux/wireless.h>
+#include <linux/rtnetlink.h>
+#include <linux/sockios.h>
+
+#include "netutils/ifc.h"
#ifdef ANDROID
#define LOG_TAG "NetUtils"
@@ -52,6 +55,8 @@
void printerr(char *fmt, ...);
#define DBG 0
+#define INET_ADDRLEN 4
+#define INET6_ADDRLEN 16
in_addr_t prefixLengthToIpv4Netmask(int prefix_length)
{
@@ -88,6 +93,28 @@
return inet_ntoa(in_addr);
}
+int string_to_ip(const char *string, struct sockaddr_storage *ss) {
+ struct addrinfo hints, *ai;
+ int ret;
+
+ if (ss == NULL) {
+ return -EFAULT;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ ret = getaddrinfo(string, NULL, &hints, &ai);
+ if (ret == 0) {
+ memcpy(ss, ai->ai_addr, ai->ai_addrlen);
+ freeaddrinfo(ai);
+ }
+
+ return ret;
+}
+
int ifc_init(void)
{
int ret;
@@ -209,6 +236,185 @@
return ret;
}
+/*
+ * Adds or deletes an IP address on an interface.
+ *
+ * Action is one of:
+ * - RTM_NEWADDR (to add a new address)
+ * - RTM_DELADDR (to delete an existing address)
+ *
+ * Returns zero on success and negative errno on failure.
+ */
+int ifc_act_on_address(int action, const char *name, const char *address,
+ int prefixlen) {
+ int ifindex, s, len, ret;
+ struct sockaddr_storage ss;
+ void *addr;
+ size_t addrlen;
+ struct {
+ struct nlmsghdr n;
+ struct ifaddrmsg r;
+ // Allow for IPv6 address, headers, and padding.
+ char attrbuf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+ NLMSG_ALIGN(sizeof(struct rtattr)) +
+ NLMSG_ALIGN(INET6_ADDRLEN)];
+ } req;
+ struct rtattr *rta;
+ struct nlmsghdr *nh;
+ struct nlmsgerr *err;
+ char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+ NLMSG_ALIGN(sizeof(struct nlmsgerr)) +
+ NLMSG_ALIGN(sizeof(struct nlmsghdr))];
+
+ // Get interface ID.
+ ifindex = if_nametoindex(name);
+ if (ifindex == 0) {
+ return -errno;
+ }
+
+ // Convert string representation to sockaddr_storage.
+ ret = string_to_ip(address, &ss);
+ if (ret) {
+ return ret;
+ }
+
+ // Determine address type and length.
+ if (ss.ss_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
+ addr = &sin->sin_addr;
+ addrlen = INET_ADDRLEN;
+ } else if (ss.ss_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
+ addr = &sin6->sin6_addr;
+ addrlen = INET6_ADDRLEN;
+ } else {
+ return -EAFNOSUPPORT;
+ }
+
+ // Fill in netlink structures.
+ memset(&req, 0, sizeof(req));
+
+ // Netlink message header.
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.r));
+ req.n.nlmsg_type = action;
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.n.nlmsg_pid = getpid();
+
+ // Interface address message header.
+ req.r.ifa_family = ss.ss_family;
+ req.r.ifa_prefixlen = prefixlen;
+ req.r.ifa_index = ifindex;
+
+ // Routing attribute. Contains the actual IP address.
+ rta = (struct rtattr *) (((char *) &req) + NLMSG_ALIGN(req.n.nlmsg_len));
+ rta->rta_type = IFA_LOCAL;
+ rta->rta_len = RTA_LENGTH(addrlen);
+ req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen);
+ memcpy(RTA_DATA(rta), addr, addrlen);
+
+ s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (send(s, &req, req.n.nlmsg_len, 0) < 0) {
+ close(s);
+ return -errno;
+ }
+
+ len = recv(s, buf, sizeof(buf), 0);
+ close(s);
+ if (len < 0) {
+ return -errno;
+ }
+
+ // Parse the acknowledgement to find the return code.
+ nh = (struct nlmsghdr *) buf;
+ if (!NLMSG_OK(nh, (unsigned) len) || nh->nlmsg_type != NLMSG_ERROR) {
+ return -EINVAL;
+ }
+ err = NLMSG_DATA(nh);
+
+ // Return code is negative errno.
+ return err->error;
+}
+
+int ifc_add_address(const char *name, const char *address, int prefixlen) {
+ return ifc_act_on_address(RTM_NEWADDR, name, address, prefixlen);
+}
+
+int ifc_del_address(const char *name, const char * address, int prefixlen) {
+ return ifc_act_on_address(RTM_DELADDR, name, address, prefixlen);
+}
+
+/*
+ * Clears IPv6 addresses on the specified interface.
+ */
+int ifc_clear_ipv6_addresses(const char *name) {
+ char rawaddrstr[INET6_ADDRSTRLEN], addrstr[INET6_ADDRSTRLEN];
+ unsigned int prefixlen;
+ int lasterror = 0, i, j, ret;
+ char ifname[64]; // Currently, IFNAMSIZ = 16.
+ FILE *f = fopen("/proc/net/if_inet6", "r");
+ if (!f) {
+ return -errno;
+ }
+
+ // Format:
+ // 20010db8000a0001fc446aa4b5b347ed 03 40 00 01 wlan0
+ while (fscanf(f, "%32s %*02x %02x %*02x %*02x %63s\n",
+ rawaddrstr, &prefixlen, ifname) == 3) {
+ // Is this the interface we're looking for?
+ if (strcmp(name, ifname)) {
+ continue;
+ }
+
+ // Put the colons back into the address.
+ for (i = 0, j = 0; i < 32; i++, j++) {
+ addrstr[j] = rawaddrstr[i];
+ if (i % 4 == 3) {
+ addrstr[++j] = ':';
+ }
+ }
+ addrstr[j - 1] = '\0';
+
+ // Don't delete the link-local address as well, or it will disable IPv6
+ // on the interface.
+ if (strncmp(addrstr, "fe80:", 5) == 0) {
+ continue;
+ }
+
+ ret = ifc_del_address(ifname, addrstr, prefixlen);
+ if (ret) {
+ LOGE("Deleting address %s/%d on %s: %s", addrstr, prefixlen, ifname,
+ strerror(-ret));
+ lasterror = ret;
+ }
+ }
+
+ fclose(f);
+ return lasterror;
+}
+
+/*
+ * Clears IPv4 addresses on the specified interface.
+ */
+void ifc_clear_ipv4_addresses(const char *name) {
+ unsigned count, addr;
+ ifc_init();
+ for (count=0, addr=1;((addr != 0) && (count < 255)); count++) {
+ if (ifc_get_addr(name, &addr) < 0)
+ break;
+ if (addr)
+ ifc_set_addr(name, 0);
+ }
+ ifc_close();
+}
+
+/*
+ * Clears all IP addresses on the specified interface.
+ */
+int ifc_clear_addresses(const char *name) {
+ ifc_clear_ipv4_addresses(name);
+ return ifc_clear_ipv6_addresses(name);
+}
+
int ifc_set_hwaddr(const char *name, const void *ptr)
{
int r;
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 90ca52e..722dcb2 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -10,8 +10,9 @@
#include <sysutils/SocketClient.h>
-SocketClient::SocketClient(int socket)
+SocketClient::SocketClient(int socket, bool owned)
: mSocket(socket)
+ , mSocketOwned(owned)
, mPid(-1)
, mUid(-1)
, mGid(-1)
@@ -32,6 +33,13 @@
}
}
+SocketClient::~SocketClient()
+{
+ if (mSocketOwned) {
+ close(mSocket);
+ }
+}
+
int SocketClient::sendMsg(int code, const char *msg, bool addErrno) {
char *buf;
const char* arg;
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index fcad624..3f871ea 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -79,7 +79,7 @@
SLOGE("Unable to listen on socket (%s)", strerror(errno));
return -1;
} else if (!mListen)
- mClients->push_back(new SocketClient(mSock));
+ mClients->push_back(new SocketClient(mSock, false));
if (pipe(mCtrlPipe)) {
SLOGE("pipe failed (%s)", strerror(errno));
@@ -191,7 +191,7 @@
continue;
}
pthread_mutex_lock(&mClientsLock);
- mClients->push_back(new SocketClient(c));
+ mClients->push_back(new SocketClient(c, true));
pthread_mutex_unlock(&mClientsLock);
}
@@ -225,12 +225,8 @@
}
}
pthread_mutex_unlock(&mClientsLock);
- /* Destroy the client */
- int socket = c->getSocket();
- if (c->decRef()) {
- // Note: 'c' is deleted memory at this point.
- close(socket);
- }
+ /* Remove our reference to the client */
+ c->decRef();
}
}
}
diff --git a/netcfg/netcfg.c b/netcfg/netcfg.c
index c520075..3738f24 100644
--- a/netcfg/netcfg.c
+++ b/netcfg/netcfg.c
@@ -50,8 +50,9 @@
int dump_interface(const char *name)
{
- unsigned addr, prefixLength, flags;
+ unsigned addr, flags;
unsigned char hwbuf[ETH_ALEN];
+ int prefixLength;
if(ifc_get_info(name, &addr, &prefixLength, &flags)) {
return 0;
diff --git a/rootdir/etc/init.goldfish.rc b/rootdir/etc/init.goldfish.rc
index 1ac09ca..83b7f8a 100644
--- a/rootdir/etc/init.goldfish.rc
+++ b/rootdir/etc/init.goldfish.rc
@@ -52,6 +52,18 @@
group root
oneshot
+# The qemu-props program is used to set various system
+# properties on boot. It must be run early during the boot
+# process to avoid race conditions with other daemons that
+# might read them (e.g. surface flinger), so define it in
+# class 'core'
+#
+service qemu-props /system/bin/qemu-props
+ class core
+ user root
+ group root
+ oneshot
+
service qemud /system/bin/qemud
socket qemud stream 666
oneshot
diff --git a/rootdir/etc/init.goldfish.sh b/rootdir/etc/init.goldfish.sh
index 1156dd7..ece75b4 100755
--- a/rootdir/etc/init.goldfish.sh
+++ b/rootdir/etc/init.goldfish.sh
@@ -57,10 +57,6 @@
;;
esac
-# call 'qemu-props' to set system properties from the emulator.
-#
-/system/bin/qemu-props
-
# set up the second interface (for inter-emulator connections)
# if required
my_ip=`getprop net.shared_net_ip`