Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

system-core: Commit

system/core


Commit MetaInfo

Revision14a57a3a34c111a6afd0ca779e70c44ba7361b18 (tree)
Time2017-10-26 00:43:43
Authormeijjaa <jjmeijer88@gmai...>
Commitermeijjaa

Log Message

Merge remote-tracking branch 'x86/nougat-x86' into cm-14.1-x86

Change Summary

Incremental Difference

--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -51,7 +51,48 @@ ADB_MUTEX_DEFINE(local_transports_lock);
5151 * trying to connect twice to a given local transport.
5252 */
5353 static atransport* local_transports[ ADB_LOCAL_TRANSPORT_MAX ];
54-#endif /* ADB_HOST */
54+#else /* !ADB_HOST */
55+
56+#define WAKE_LOCK_NAME "adb-socket-connection"
57+#define WAKE_LOCK_ACQUIRE "/sys/power/wake_lock"
58+#define WAKE_LOCK_RELEASE "/sys/power/wake_unlock"
59+
60+static int sysfs_write(const char *node, const char *message)
61+{
62+ int fd;
63+ ssize_t to_write;
64+ int ret = 0;
65+
66+ fd = adb_open(node, O_RDWR);
67+ if (!fd) {
68+ D("open '%s' failed: %s", node, strerror(errno));
69+ return -1;
70+ }
71+
72+ to_write = strlen(message);
73+ if (adb_write(fd, message, to_write) != to_write) {
74+ D("write '%s' failed: %s", node, strerror(errno));
75+ ret = -1;
76+ }
77+ adb_close(fd);
78+ return ret;
79+}
80+
81+static void get_wakelock(void)
82+{
83+ if (sysfs_write(WAKE_LOCK_ACQUIRE, WAKE_LOCK_NAME)) {
84+ D("couldn't reserve wakelock for socket connection");
85+ }
86+}
87+
88+static void release_wakelock(void)
89+{
90+ if (sysfs_write(WAKE_LOCK_RELEASE, WAKE_LOCK_NAME)) {
91+ D("couldn't release wakelock for socket connection");
92+ }
93+}
94+
95+#endif /* !ADB_HOST */
5596
5697 static int remote_read(apacket *p, atransport *t)
5798 {
@@ -171,6 +212,9 @@ static void server_socket_thread(void* arg) {
171212 fd = adb_socket_accept(serverfd, addrp, &alen);
172213 if(fd >= 0) {
173214 D("server: new connection on fd %d", fd);
215+#if !ADB_HOST
216+ get_wakelock();
217+#endif
174218 close_on_exec(fd);
175219 disable_tcp_nagle(fd);
176220 register_socket_transport(fd, "host", port, 1);
@@ -340,6 +384,9 @@ static void remote_kick(atransport *t)
340384
341385 static void remote_close(atransport *t)
342386 {
387+#if !ADB_HOST
388+ release_wakelock();
389+#endif
343390 int fd = t->sfd;
344391 if (fd != -1) {
345392 t->sfd = -1;
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -131,8 +131,13 @@ static const char* get_sigcode(int signo, int code) {
131131 #if defined(SEGV_BNDERR)
132132 case SEGV_BNDERR: return "SEGV_BNDERR";
133133 #endif
134+#if defined(SEGV_PKUERR)
135+ case SEGV_PKUERR: return "SEGV_PKUERR";
136+#endif
134137 }
135-#if defined(SEGV_BNDERR)
138+#if defined(SEGV_PKUERR)
139+ static_assert(NSIGSEGV == SEGV_PKUERR, "missing SEGV_* si_code");
140+#elif defined(SEGV_BNDERR)
136141 static_assert(NSIGSEGV == SEGV_BNDERR, "missing SEGV_* si_code");
137142 #else
138143 static_assert(NSIGSEGV == SEGV_ACCERR, "missing SEGV_* si_code");
--- a/fs_mgr/fs_mgr_format.c
+++ b/fs_mgr/fs_mgr_format.c
@@ -36,7 +36,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, long long fs_length)
3636 uint64_t dev_sz;
3737 int fd, rc = 0;
3838
39- if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
39+ if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
4040 ERROR("Cannot open block device. %s\n", strerror(errno));
4141 return -1;
4242 }
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -76,7 +76,7 @@ public:
7676
7777 void store_sid(uint32_t uid, uint64_t sid) {
7878 char filename[21];
79- sprintf(filename, "%u", uid);
79+ snprintf(filename, sizeof(filename), "%u", uid);
8080 int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
8181 if (fd < 0) {
8282 ALOGE("could not open file: %s: %s", filename, strerror(errno));
@@ -102,7 +102,7 @@ public:
102102
103103 void maybe_store_sid(uint32_t uid, uint64_t sid) {
104104 char filename[21];
105- sprintf(filename, "%u", uid);
105+ snprintf(filename, sizeof(filename), "%u", uid);
106106 if (access(filename, F_OK) == -1) {
107107 store_sid(uid, sid);
108108 }
@@ -111,7 +111,7 @@ public:
111111 uint64_t read_sid(uint32_t uid) {
112112 char filename[21];
113113 uint64_t sid;
114- sprintf(filename, "%u", uid);
114+ snprintf(filename, sizeof(filename), "%u", uid);
115115 int fd = open(filename, O_RDONLY);
116116 if (fd < 0) return 0;
117117 read(fd, &sid, sizeof(sid));
@@ -121,7 +121,7 @@ public:
121121
122122 void clear_sid(uint32_t uid) {
123123 char filename[21];
124- sprintf(filename, "%u", uid);
124+ snprintf(filename, sizeof(filename), "%u", uid);
125125 if (remove(filename) < 0) {
126126 ALOGE("%s: could not remove file [%s], attempting 0 write", __func__, strerror(errno));
127127 store_sid(uid, 0);
--- /dev/null
+++ b/include/cutils/probe_module.h
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright (C) 2012 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _LIBS_CUTILS_PROBEMODULE_H
18+#define _LIBS_CUTILS_PROBEMODULE_H
19+
20+#ifdef __cplusplus
21+extern "C" {
22+#endif
23+
24+/* get_default_mod_path() - get the default modules path
25+ * It checks /system/lib/modules/$(uname -r)/ first. If it doesn't exist,
26+ * fall back to /system/lib/modules/.
27+ *
28+ * def_mod_path: The buffer to be filled
29+ *
30+ * return : def_mod_path
31+ */
32+extern char *get_default_mod_path(char *def_mod_path);
33+
34+/* insmod() - load a kernel module (target) from a file
35+ *
36+ * filename : Filename of the target module.
37+ *
38+ * args : A string of target module's parameters. NOTE: we only
39+ * support parameters of the target module.
40+ *
41+ */
42+extern int insmod(const char *filename, const char *args);
43+
44+/* insmod_by_dep() - load a kernel module (target) with its dependency
45+ * The module's dependency must be described in the provided dependency file.
46+ * other modules in the dependency chain will be loaded prior to the target.
47+ *
48+ * module_name: Name of the target module. e.g. name "MyModule" is for
49+ * module file MyModule.ko.
50+ *
51+ * args : A string of target module's parameters. NOTE: we only
52+ * support parameters of the target module.
53+ *
54+ * dep_name : Name of dependency file. If it is NULL, we will look
55+ * up /system/lib/modules/modules.dep by default.
56+ *
57+ * strip : Non-zero values remove paths of modules in dependency.
58+ * before loading them. The final path of a module will be
59+ * base/MyModule.ko. This is for devices which put every
60+ * modules into a single directory.
61+ *
62+ * Passing 0 to strip keeps module paths in dependency file.
63+ * e.g. "kernel/drivers/.../MyModule.ko" in dep file will
64+ * be loaded as base/kernel/drivers/.../MyModule.ko .
65+ *
66+ * base : Base dir, a prefix to be added to module's path prior to
67+ * loading. The last character prior to base string's terminator
68+ * must be a '/'. If it is NULL, we will take
69+ * /system/lib/modules/modules.dep by default.
70+ *
71+ * return : 0 for success; non-zero for any errors.
72+ *
73+ * Note:
74+ * When loading modules, function will not fail for any modules which are
75+ * already in kernel. The module parameters passed to function will not be
76+ * effective in this case if target module is already loaded into kernel.
77+ */
78+extern int insmod_by_dep(
79+ const char *module_name,
80+ const char *args,
81+ const char *dep_name,
82+ int strip,
83+ const char * base);
84+
85+/* rmmod_by_dep() - remove a module (target) from kernel with its dependency
86+ * The module's dependency must be described in the provided dependency file.
87+ * This function will try to remove other modules in the dependency chain too
88+ *
89+ * module_name: Name of the target module. e.g. name "MyModule" is for
90+ * module file MyModule.ko.
91+ *
92+ * dep_name : Name of dependency file. If it is NULL, we will look
93+ * up /system/lib/modules/modules.dep by default.
94+ *
95+ * return : 0 for success; non-zero for any errors.
96+ */
97+extern int rmmod_by_dep(const char *module_name, const char *dep_name);
98+
99+#ifdef __cplusplus
100+}
101+#endif
102+
103+#endif /*_LIBS_CUTILS_PROBEMODULE_H*/
--- a/include/diskconfig/diskconfig.h
+++ b/include/diskconfig/diskconfig.h
@@ -21,6 +21,11 @@
2121 #include <stdint.h>
2222 #include <sys/types.h>
2323
24+#ifdef __APPLE__
25+typedef int64_t loff_t;
26+#define lseek64 lseek
27+#endif
28+
2429 #ifdef __cplusplus
2530 extern "C" {
2631 #endif
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -68,6 +68,7 @@ include $(BUILD_STATIC_LIBRARY)
6868
6969 include $(CLEAR_VARS)
7070 LOCAL_CPPFLAGS := $(init_cflags)
71+LOCAL_CPPFLAGS += -DTARGET_PRODUCT=\"$(TARGET_PRODUCT)\"
7172 LOCAL_SRC_FILES:= \
7273 bootchart.cpp \
7374 builtins.cpp \
@@ -142,6 +143,7 @@ LOCAL_STATIC_LIBRARIES := \
142143
143144 # Create symlinks
144145 LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
146+ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/modprobe; \
145147 ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
146148 ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
147149
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -29,9 +29,6 @@
2929 #include <sys/socket.h>
3030 #include <sys/mount.h>
3131 #include <sys/resource.h>
32-#ifndef NO_FINIT_MODULE
33-#include <sys/syscall.h>
34-#endif
3532 #include <sys/time.h>
3633 #include <sys/types.h>
3734 #include <sys/stat.h>
@@ -51,6 +48,7 @@
5148 #include <bootloader_message/bootloader_message.h>
5249 #include <cutils/partition_utils.h>
5350 #include <cutils/android_reboot.h>
51+#include <cutils/probe_module.h>
5452 #include <logwrap/logwrap.h>
5553 #include <private/android_filesystem_config.h>
5654
@@ -78,29 +76,6 @@ extern "C" int init_module(void *, unsigned long, const char *);
7876
7977 static const int kTerminateServiceDelayMicroSeconds = 50000;
8078
81-static int insmod(const char *filename, const char *options) {
82-#ifndef NO_FINIT_MODULE
83- int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
84- if (fd == -1) {
85- ERROR("insmod: open(\"%s\") failed: %s", filename, strerror(errno));
86-#else
87- std::string module;
88- if (!read_file(filename, &module)) {
89-#endif
90- return -1;
91- }
92-#ifndef NO_FINIT_MODULE
93- int rc = syscall(__NR_finit_module, fd, options, 0);
94- if (rc == -1) {
95- ERROR("finit_module for \"%s\" failed: %s", filename, strerror(errno));
96- }
97- close(fd);
98- return rc;
99-#else
100- return init_module(&module[0], module.size(), options);
101-#endif
102-}
103-
10479 static int __ifupdown(const char *interface, int up) {
10580 struct ifreq ifr;
10681 int s, ret;
@@ -573,9 +548,14 @@ static int mount_fstab(const char* fstabfile, int mount_mode) {
573548 ret = -1;
574549 }
575550 } else if (pid == 0) {
551+ std::string filename_val;
552+ if (!expand_props(fstabfile, &filename_val)) {
553+ ERROR("mount_all: cannot expand '%s'\n", fstabfile);
554+ _exit(-1);
555+ }
576556 /* child, call fs_mgr_mount_all() */
577557 klog_set_level(6); /* So we can see what fs_mgr_mount_all() does */
578- fstab = fs_mgr_read_fstab(fstabfile);
558+ fstab = fs_mgr_read_fstab(filename_val.c_str());
579559 child_ret = fs_mgr_mount_all(fstab, mount_mode);
580560 fs_mgr_free_fstab(fstab);
581561 if (child_ret == -1) {
@@ -649,14 +629,13 @@ static int queue_fs_event(int code) {
649629 * not return.
650630 */
651631 static int do_mount_all(const std::vector<std::string>& args) {
652- std::size_t na = 0;
653632 bool import_rc = true;
654633 bool queue_event = true;
655634 int mount_mode = MOUNT_MODE_DEFAULT;
656635 const char* fstabfile = args[1].c_str();
657636 std::size_t path_arg_end = args.size();
658637
659- for (na = args.size() - 1; na > 1; --na) {
638+ for (std::size_t na = args.size() - 1; na > 1; --na) {
660639 if (args[na] == "--early") {
661640 path_arg_end = na;
662641 queue_event = false;
@@ -834,13 +813,96 @@ static int do_rmdir(const std::vector<std::string>& args) {
834813 return rmdir(args[1].c_str());
835814 }
836815
816+// read persist property from /data/property directly, because it maybe has not loaded
817+// if the file not found, try to call property_get, the default value could be saved
818+// into /default.prop
819+static std::string persist_property_get(const char *name)
820+{
821+ const char *filename_template = "/data/property/%s";
822+ size_t max_file_name_len = strlen(filename_template) + PROP_NAME_MAX;
823+ char filename[max_file_name_len];
824+ snprintf(filename, max_file_name_len, filename_template, name);
825+
826+ if (access(filename, 0) == 0) {
827+ char *line = NULL;
828+ size_t len;
829+ FILE *fp = fopen(filename, "r+");
830+ if (fp == NULL) {
831+ ERROR("failed to read file for property:%s\n", filename);
832+ return 0;
833+ }
834+
835+ std::string result;
836+ if (getline(&line, &len, fp) == -1) {
837+ len = 0;
838+ } else {
839+ for (len = 0; *(line+len) != '\n' && *(line+len) != 0; len++);
840+ *(line + len) = '\0';
841+ result = line;
842+ free(line);
843+ }
844+ fclose(fp);
845+ return result;
846+ }
847+
848+ return property_get(name);
849+}
850+
837851 static int do_sysclktz(const std::vector<std::string>& args) {
838852 struct timezone tz;
853+ struct timeval tv;
854+ struct tm tm;
855+ time_t t;
839856
840857 memset(&tz, 0, sizeof(tz));
841- tz.tz_minuteswest = std::stoi(args[1]);
842- if (settimeofday(NULL, &tz))
858+ memset(&tv, 0, sizeof(tv));
859+ memset(&tm, 0, sizeof(tm));
860+
861+ INFO("sysclktz: the arg %s is ignored, only persist.rtc_local_time matters\n", args[1].c_str());
862+
863+ if (gettimeofday(&tv, NULL)) {
864+ ERROR("sysclktz: failed to call gettimeofday");
843865 return -1;
866+ }
867+
868+ if (persist_property_get("persist.rtc_local_time") == "1") {
869+ /* Notify kernel that hwtime use local time */
870+ write_file("/sys/class/misc/alarm/rtc_local_time", "1");
871+ /*
872+ * If ro.hwtime.mode is local, set system time
873+ * and saved system zone in case of network not
874+ * available and auto syncing time not available.
875+ */
876+
877+ std::string time_zone = persist_property_get("persist.sys.timezone");
878+ if (time_zone.empty()) {
879+ INFO("sysclktz: persist.sys.timezone not found\n");
880+ tz.tz_minuteswest = 0;
881+ } else {
882+ const char *timezone_prop = time_zone.c_str();
883+ INFO("sysclktz: persist.sys.timezone: %s\n", timezone_prop);
884+ // localtime_r need the property, we need to set it
885+ property_set("persist.sys.timezone", timezone_prop);
886+ t = tv.tv_sec;
887+ localtime_r(&t, &tm);
888+ tz.tz_minuteswest = -(tm.tm_gmtoff / 60);
889+ INFO("sysclktz: tz.tz_minuteswest: %d\n", tz.tz_minuteswest);
890+ }
891+
892+ /*
893+ * At this moment, system time should be local
894+ * time too, set it back to utc which linux required.
895+ */
896+ tv.tv_sec += tz.tz_minuteswest * 60;
897+ if (settimeofday(&tv, &tz)) {
898+ ERROR("sysclktz: failed to call settimeofdays\n");
899+ return -1;
900+ }
901+ } else {
902+ tz.tz_minuteswest = std::stoi(args[1]);
903+ return settimeofday(NULL, &tz);
904+ }
905+
844906 return 0;
845907 }
846908
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -42,18 +42,28 @@
4242
4343 #include <android-base/file.h>
4444 #include <cutils/list.h>
45+#include <cutils/probe_module.h>
4546 #include <cutils/uevent.h>
4647
4748 #include "devices.h"
4849 #include "ueventd_parser.h"
4950 #include "util.h"
5051 #include "log.h"
52+#include "parser.h"
5153 #include "property_service.h"
5254
5355 #define SYSFS_PREFIX "/sys"
56+#if defined(__i386__) || defined(__x86_64__)
57+static const char *firmware_dirs[] = { "/system/lib/firmware" };
58+#else
5459 static const char *firmware_dirs[] = { "/etc/firmware",
5560 "/vendor/firmware",
5661 "/firmware/image" };
62+#endif
63+
64+#define MODULES_BLKLST "/system/etc/modules.blacklist"
65+#define READ_MODULES_ALIAS 1
66+#define READ_MODULES_BLKLST 2
5767
5868 extern struct selabel_handle *sehandle;
5969
@@ -68,6 +78,7 @@ struct uevent {
6878 const char *firmware;
6979 const char *partition_name;
7080 const char *device_name;
81+ const char *modalias;
7182 int partition_num;
7283 int major;
7384 int minor;
@@ -95,9 +106,27 @@ struct platform_node {
95106 struct listnode list;
96107 };
97108
109+struct module_alias_node {
110+ char *name;
111+ char *pattern;
112+ struct listnode list;
113+};
114+
115+struct module_blacklist_node {
116+ char *name;
117+ bool deferred;
118+ struct listnode list;
119+};
120+
98121 static list_declare(sys_perms);
99122 static list_declare(dev_perms);
100123 static list_declare(platform_names);
124+static list_declare(modules_aliases_map);
125+static list_declare(modules_blacklist);
126+static list_declare(deferred_module_loading_list);
127+
128+static int read_modules_aliases();
129+static int read_modules_blacklist();
101130
102131 int add_dev_perms(const char *name, const char *attr,
103132 mode_t perm, unsigned int uid, unsigned int gid,
@@ -405,6 +434,7 @@ static void parse_event(const char *msg, struct uevent *uevent)
405434 uevent->partition_name = NULL;
406435 uevent->partition_num = -1;
407436 uevent->device_name = NULL;
437+ uevent->modalias = NULL;
408438
409439 /* currently ignoring SEQNUM */
410440 while(*msg) {
@@ -435,6 +465,9 @@ static void parse_event(const char *msg, struct uevent *uevent)
435465 } else if(!strncmp(msg, "DEVNAME=", 8)) {
436466 msg += 8;
437467 uevent->device_name = msg;
468+ } else if(!strncmp(msg, "MODALIAS=", 9)) {
469+ msg += 9;
470+ uevent->modalias = msg;
438471 }
439472
440473 /* advance to after the next \0 */
@@ -761,7 +794,7 @@ static void handle_generic_device_event(struct uevent *uevent)
761794 return;
762795 mkdir_recursive_for_devpath(devpath);
763796 } else if (!strncmp(uevent->subsystem, "usb", 3)) {
764- if (!strcmp(uevent->subsystem, "usb")) {
797+ if (!strcmp(uevent->subsystem, "usb") || !strcmp(uevent->subsystem, "usbmisc")) {
765798 if (uevent->device_name) {
766799 if (!assemble_devpath(devpath, "/dev", uevent->device_name))
767800 return;
@@ -848,8 +881,186 @@ static void handle_generic_device_event(struct uevent *uevent)
848881 uevent->major, uevent->minor, links);
849882 }
850883
884+static int is_module_blacklisted_or_deferred(const char *name, bool need_deferred)
885+{
886+ struct listnode *blklst_node;
887+ struct module_blacklist_node *blacklist;
888+ int ret = 0;
889+
890+ if (!name) goto out;
891+
892+ /* See if module is blacklisted, skip if it is */
893+ list_for_each(blklst_node, &modules_blacklist) {
894+ blacklist = node_to_item(blklst_node,
895+ struct module_blacklist_node,
896+ list);
897+ if (!strcmp(name, blacklist->name)) {
898+ INFO("modules %s is blacklisted\n", name);
899+ ret = blacklist->deferred ? (need_deferred ? 2 : 0) : 1;
900+ goto out;
901+ }
902+ }
903+
904+out:
905+ return ret;
906+}
907+
908+static int load_module_by_device_modalias(const char *id, bool need_deferred)
909+{
910+ struct listnode *alias_node;
911+ struct module_alias_node *alias;
912+ int ret = -1;
913+
914+ list_for_each(alias_node, &modules_aliases_map) {
915+ alias = node_to_item(alias_node, struct module_alias_node, list);
916+
917+ if (alias && alias->name && alias->pattern) {
918+ if (fnmatch(alias->pattern, id, 0) == 0) {
919+ INFO("trying to load module %s due to uevents\n", alias->name);
920+
921+ ret = is_module_blacklisted_or_deferred(alias->name, need_deferred);
922+ if (ret == 0) {
923+ if ((ret = insmod_by_dep(alias->name, "", NULL, 0, NULL))) {
924+ /* cannot load module. try another one since
925+ * there may be another match.
926+ */
927+ NOTICE("failed to load %s for modalias %s\n",
928+ alias->name, id);
929+ } else {
930+ /* loading was successful */
931+ INFO("loaded module %s due to uevents\n", alias->name);
932+ }
933+ } else {
934+ NOTICE("blacklisted module %s: %d\n", alias->name, ret);
935+ }
936+ }
937+ }
938+ }
939+
940+ return ret;
941+}
942+
943+static void handle_deferred_module_loading()
944+{
945+ /* try to read the module alias mapping if map is empty
946+ * if succeed, loading all the modules in the queue
947+ */
948+ if (!list_empty(&modules_aliases_map)) {
949+ struct listnode *node = NULL;
950+ struct listnode *next = NULL;
951+ struct module_alias_node *alias = NULL;
952+
953+ list_for_each_safe(node, next, &deferred_module_loading_list) {
954+ alias = node_to_item(node, struct module_alias_node, list);
955+
956+ if (alias && alias->pattern) {
957+ INFO("deferred loading of module for %s\n", alias->pattern);
958+ load_module_by_device_modalias(alias->pattern, false);
959+ free(alias->pattern);
960+ list_remove(node);
961+ free(alias);
962+ }
963+ }
964+ }
965+}
966+
967+static int module_probe(int argc, char **argv)
968+{
969+ if (list_empty(&modules_aliases_map)) {
970+ read_modules_aliases();
971+ read_modules_blacklist();
972+ }
973+
974+ // is it a modalias?
975+ int ret = load_module_by_device_modalias(argv[1], false);
976+ if (ret) {
977+ // treat it as a module name
978+ std::string options;
979+ if (argc > 2) {
980+ options = argv[2];
981+ for (int i = 3; i < argc; ++i) {
982+ options += ' ';
983+ options += argv[i];
984+ }
985+ }
986+ ret = insmod_by_dep(argv[1], options.c_str(), NULL, 0, NULL);
987+ }
988+ return ret;
989+}
990+
991+int modprobe_main(int argc, char **argv)
992+{
993+ const char *prog = argv[0];
994+
995+ /* We only accept requests from root user (kernel) */
996+ if (getuid())
997+ return -EPERM;
998+
999+ /* Kernel will launch a user space program specified by
1000+ * /proc/sys/kernel/modprobe to load modules.
1001+ * No deferred loading in this case.
1002+ */
1003+ while (argc > 1 && (!strcmp(argv[1], "-q") || !strcmp(argv[1], "--"))) {
1004+ klog_set_level(KLOG_NOTICE_LEVEL);
1005+ argc--, argv++;
1006+ }
1007+
1008+ if (argc < 2) {
1009+ /* it is called without enough arguments */
1010+ return -EINVAL;
1011+ }
1012+
1013+ NOTICE("%s %s\n", prog, argv[1]);
1014+ return module_probe(argc, argv);
1015+}
1016+
1017+static int is_booting(void)
1018+{
1019+ return access("/dev/.booting", F_OK) == 0;
1020+}
1021+
1022+static void handle_module_loading(const char *modalias)
1023+{
1024+ struct module_alias_node *node;
1025+
1026+ /* once modules.alias can be read,
1027+ * we load all the deferred ones
1028+ */
1029+ if (list_empty(&modules_aliases_map)) {
1030+ if (read_modules_aliases() == 0) {
1031+ read_modules_blacklist();
1032+ }
1033+ }
1034+
1035+ if (!modalias) return;
1036+
1037+ if (list_empty(&modules_aliases_map) ||
1038+ load_module_by_device_modalias(modalias, is_booting()) == 2) {
1039+ /* if module alias mapping is empty,
1040+ * queue it for loading later
1041+ */
1042+ node = (module_alias_node *) calloc(1, sizeof(*node));
1043+ if (node) {
1044+ node->pattern = strdup(modalias);
1045+ if (!node->pattern) {
1046+ free(node);
1047+ } else {
1048+ list_add_tail(&deferred_module_loading_list, &node->list);
1049+ INFO("add to queue for deferred module loading: %s",
1050+ node->pattern);
1051+ }
1052+ } else {
1053+ ERROR("failed to allocate memory to store device id for deferred module loading.\n");
1054+ }
1055+ }
1056+}
1057+
8511058 static void handle_device_event(struct uevent *uevent)
8521059 {
1060+ if (!strcmp(uevent->action,"add")) {
1061+ handle_module_loading(uevent->modalias);
1062+ }
1063+
8531064 if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change") || !strcmp(uevent->action, "online"))
8541065 fixup_sys_perms(uevent->path);
8551066
@@ -915,11 +1126,6 @@ static int load_firmware(int fw_fd, int loading_fd, int data_fd)
9151126 return ret;
9161127 }
9171128
918-static int is_booting(void)
919-{
920- return access("/dev/.booting", F_OK) == 0;
921-}
922-
9231129 static void process_firmware_event(struct uevent *uevent)
9241130 {
9251131 char *root, *loading, *data;
@@ -927,7 +1133,7 @@ static void process_firmware_event(struct uevent *uevent)
9271133 size_t i;
9281134 int booting = is_booting();
9291135
930- INFO("firmware: loading '%s' for '%s'\n",
1136+ NOTICE("firmware: loading '%s' for '%s'\n",
9311137 uevent->firmware, uevent->path);
9321138
9331139 l = asprintf(&root, SYSFS_PREFIX"%s/", uevent->path);
@@ -995,26 +1201,162 @@ root_free_out:
9951201
9961202 static void handle_firmware_event(struct uevent *uevent)
9971203 {
998- pid_t pid;
999-
10001204 if(strcmp(uevent->subsystem, "firmware"))
10011205 return;
10021206
10031207 if(strcmp(uevent->action, "add"))
10041208 return;
10051209
1006- /* we fork, to avoid making large memory allocations in init proper */
1007- pid = fork();
1008- if (!pid) {
1009- process_firmware_event(uevent);
1010- _exit(EXIT_SUCCESS);
1011- } else if (pid < 0) {
1012- ERROR("could not fork to process firmware event: %s\n", strerror(errno));
1210+ process_firmware_event(uevent);
1211+}
1212+
1213+static void parse_line_module_alias(struct parse_state *state, int nargs, char **args)
1214+{
1215+ struct module_alias_node *node;
1216+
1217+ if (!args ||
1218+ (nargs != 3) ||
1219+ !args[0] || !args[1] || !args[2]) {
1220+ /* empty line or not enough arguments */
1221+ return;
1222+ }
1223+
1224+ node = (module_alias_node *) calloc(1, sizeof(*node));
1225+ if (!node) return;
1226+
1227+ node->name = strdup(args[2]);
1228+ if (!node->name) {
1229+ free(node);
1230+ return;
1231+ }
1232+
1233+ node->pattern = strdup(args[1]);
1234+ if (!node->pattern) {
1235+ free(node->name);
1236+ free(node);
1237+ return;
1238+ }
1239+
1240+ list_add_tail(&modules_aliases_map, &node->list);
1241+}
1242+
1243+static void parse_line_module_blacklist(struct parse_state *state, int nargs, char **args)
1244+{
1245+ struct module_blacklist_node *node;
1246+ bool deferred;
1247+
1248+ if (!args ||
1249+ (nargs != 2) ||
1250+ !args[0] || !args[1]) {
1251+ /* empty line or not enough arguments */
1252+ return;
1253+ }
1254+
1255+ /* this line does not being with "blacklist" or "deferred" */
1256+ if (!strncmp(args[0], "blacklist", 9))
1257+ deferred = false;
1258+ else if (!strncmp(args[0], "deferred", 8))
1259+ deferred = true;
1260+ else
1261+ return;
1262+
1263+ node = (module_blacklist_node *) calloc(1, sizeof(*node));
1264+ if (!node) return;
1265+
1266+ node->name = strdup(args[1]);
1267+ if (!node->name) {
1268+ free(node);
1269+ return;
1270+ }
1271+ node->deferred = deferred;
1272+
1273+ list_add_tail(&modules_blacklist, &node->list);
1274+}
1275+
1276+static int __read_modules_desc_file(int mode)
1277+{
1278+ struct parse_state state;
1279+ char *args[3];
1280+ int nargs;
1281+ char fn[PATH_MAX];
1282+ int fd = -1;
1283+ int ret = -1;
1284+ int args_to_read = 0;
1285+ std::string data;
1286+
1287+ if (mode == READ_MODULES_ALIAS) {
1288+ /* read modules.alias */
1289+ strcat(get_default_mod_path(fn), "modules.alias");
1290+ } else if (mode == READ_MODULES_BLKLST) {
1291+ /* read modules.blacklist */
1292+ strcpy(fn, MODULES_BLKLST);
1293+ } else {
1294+ /* unknown mode */
1295+ goto out;
1296+ }
1297+
1298+ fd = open(fn, O_RDONLY);
1299+ if (fd == -1) {
1300+ goto out;
1301+ }
1302+
1303+ /* read the whole file */
1304+ if (!read_file(fn, &data)) {
1305+ goto out;
1306+ }
1307+
1308+ /* invoke tokenizer */
1309+ nargs = 0;
1310+ state.filename = fn;
1311+ state.line = 1;
1312+ state.ptr = &data[0];
1313+ state.nexttoken = 0;
1314+ if (mode == READ_MODULES_ALIAS) {
1315+ state.parse_line = parse_line_module_alias;
1316+ args_to_read = 3;
1317+ } else if (mode == READ_MODULES_BLKLST) {
1318+ state.parse_line = parse_line_module_blacklist;
1319+ args_to_read = 2;
1320+ }
1321+ for (;;) {
1322+ int token = next_token(&state);
1323+ switch (token) {
1324+ case T_EOF:
1325+ state.parse_line(&state, 0, 0);
1326+ ret = 0;
1327+ goto out;
1328+ case T_NEWLINE:
1329+ if (nargs) {
1330+ state.parse_line(&state, nargs, args);
1331+ nargs = 0;
1332+ }
1333+ break;
1334+ case T_TEXT:
1335+ if (nargs < args_to_read) {
1336+ args[nargs++] = state.text;
1337+ }
1338+ break;
1339+ }
1340+ }
1341+ ret = 0;
1342+
1343+out:
1344+ if (fd != -1) {
1345+ close(fd);
10131346 }
1347+ return ret;
1348+}
1349+
1350+static int read_modules_aliases() {
1351+ return __read_modules_desc_file(READ_MODULES_ALIAS);
1352+}
1353+
1354+static int read_modules_blacklist() {
1355+ return __read_modules_desc_file(READ_MODULES_BLKLST);
10141356 }
10151357
10161358 #define UEVENT_MSG_LEN 2048
1017-void handle_device_fd()
1359+void handle_device_fd(bool child)
10181360 {
10191361 char msg[UEVENT_MSG_LEN+2];
10201362 int n;
@@ -1037,8 +1379,11 @@ void handle_device_fd()
10371379 }
10381380 }
10391381
1040- handle_device_event(&uevent);
1041- handle_firmware_event(&uevent);
1382+ if (child) {
1383+ handle_firmware_event(&uevent);
1384+ } else {
1385+ handle_device_event(&uevent);
1386+ }
10421387 }
10431388 }
10441389
@@ -1094,17 +1439,21 @@ static void coldboot(const char *path)
10941439 }
10951440 }
10961441
1097-void device_init() {
1442+void device_init(bool child)
1443+{
10981444 sehandle = selinux_android_file_context_handle();
10991445 selinux_status_open(true);
11001446
1101- /* is 256K enough? udev uses 16MB! */
1102- device_fd = uevent_open_socket(256*1024, true);
1447+ /* is 8MB enough? udev uses 16MB! */
1448+ device_fd = uevent_open_socket(8 * 1024 * 1024, true);
11031449 if (device_fd == -1) {
11041450 return;
11051451 }
11061452 fcntl(device_fd, F_SETFL, O_NONBLOCK);
11071453
1454+ if (child) {
1455+ return; // don't do coldboot in child
1456+ }
11081457 if (access(COLDBOOT_DONE, F_OK) == 0) {
11091458 NOTICE("Skipping coldboot, already done!\n");
11101459 return;
@@ -1114,6 +1463,7 @@ void device_init() {
11141463 coldboot("/sys/class");
11151464 coldboot("/sys/block");
11161465 coldboot("/sys/devices");
1466+ handle_deferred_module_loading();
11171467 close(open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000));
11181468 NOTICE("Coldboot took %.2fs.\n", t.duration());
11191469 }
--- a/init/devices.h
+++ b/init/devices.h
@@ -19,8 +19,9 @@
1919
2020 #include <sys/stat.h>
2121
22-extern void handle_device_fd();
23-extern void device_init(void);
22+extern void handle_device_fd(bool = false);
23+extern void device_init(bool);
24+extern int modprobe_main(int argc, char **argv);
2425 extern int add_dev_perms(const char *name, const char *attr,
2526 mode_t perm, unsigned int uid,
2627 unsigned int gid, unsigned short prefix,
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -177,10 +177,10 @@ static int wait_for_coldboot_done_action(const std::vector<std::string>& args) {
177177 timeout = 5;
178178 #endif
179179 NOTICE("Waiting for %s...\n", COLDBOOT_DONE);
180- // Any longer than 1s is an unreasonable length of time to delay booting.
180+ // Any longer than 10s is an unreasonable length of time to delay booting.
181181 // If you're hitting this timeout, check that you didn't make your
182182 // sepolicy regular expressions too expensive (http://b/19899875).
183- if (wait_for_file(COLDBOOT_DONE, timeout)) {
183+ if (wait_for_file(COLDBOOT_DONE, 10)) {
184184 ERROR("Timed out waiting for %s\n", COLDBOOT_DONE);
185185 }
186186 NOTICE("Waiting for %s took %.2fs.\n", COLDBOOT_DONE, t.duration());
@@ -300,8 +300,8 @@ static int console_init_action(const std::vector<std::string>& args)
300300
301301 fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
302302 if (fd >= 0) {
303- const char *msg;
304- msg = "\n"
303+ const char *msg =
304+ "\033[9;0]\n"
305305 "\n"
306306 "\n"
307307 "\n"
@@ -366,7 +366,7 @@ static void export_kernel_boot_props() {
366366 { "ro.boot.mode", "ro.bootmode", "unknown", },
367367 { "ro.boot.baseband", "ro.baseband", "unknown", },
368368 { "ro.boot.bootloader", "ro.bootloader", "unknown", },
369- { "ro.boot.hardware", "ro.hardware", "unknown", },
369+ { "ro.boot.hardware", "ro.hardware", TARGET_PRODUCT, },
370370 #ifndef IGNORE_RO_BOOT_REVISION
371371 { "ro.boot.revision", "ro.revision", "0", },
372372 #endif
@@ -558,6 +558,10 @@ static int charging_mode_booting(void) {
558558 }
559559
560560 int main(int argc, char** argv) {
561+ if (strstr(argv[0], "modprobe")) {
562+ return modprobe_main(argc, argv);
563+ }
564+
561565 if (!strcmp(basename(argv[0]), "ueventd")) {
562566 return ueventd_main(argc, argv);
563567 }
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -12,7 +12,7 @@ void parse_error(struct parse_state *state, const char *fmt, ...)
1212 char buf[128];
1313 int off;
1414
15- snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
15+ snprintf(buf, sizeof(buf), "%s: %d: ", state->filename, state->line);
1616 buf[127] = 0;
1717 off = strlen(buf);
1818
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -373,9 +373,11 @@ bool Service::Start() {
373373 }
374374 if (rc == 0 && scon == mycon) {
375375 ERROR("Service %s does not have a SELinux domain defined.\n", name_.c_str());
376+#if 0
376377 free(mycon);
377378 free(fcon);
378379 return false;
380+#endif
379381 }
380382 free(mycon);
381383 free(fcon);
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -15,12 +15,14 @@
1515 */
1616
1717 #include <ctype.h>
18+#include <errno.h>
1819 #include <fcntl.h>
1920 #include <poll.h>
2021 #include <signal.h>
2122 #include <stdio.h>
2223 #include <stdlib.h>
2324 #include <string.h>
25+#include <unistd.h>
2426
2527 #include <android-base/stringprintf.h>
2628 #include <private/android_filesystem_config.h>
@@ -66,10 +68,12 @@ int ueventd_main(int argc, char **argv)
6668 ueventd_parse_config_file("/ueventd.rc");
6769 ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware.c_str()).c_str());
6870
69- boot_device = property_get("ro.boot.bootdevice");
70-
71- device_init();
71+ pid_t pid = fork();
72+ if (pid < 0) {
73+ ERROR("could not fork to process firmware event: %s\n", strerror(errno));
74+ }
7275
76+ device_init(pid == 0);
7377 pollfd ufd;
7478 ufd.events = POLLIN;
7579 ufd.fd = get_device_fd();
@@ -81,7 +85,7 @@ int ueventd_main(int argc, char **argv)
8185 continue;
8286 }
8387 if (ufd.revents & POLLIN) {
84- handle_device_fd();
88+ handle_device_fd(pid == 0);
8589 }
8690 }
8791
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -113,7 +113,7 @@ static void *parse_subsystem(parse_state* state, int /*nargs*/, char** args) {
113113 parse_error(state, "out of memory\n");
114114 return 0;
115115 }
116- s->name = args[1];
116+ s->name = strdup(args[1]);
117117 s->dirname = "/dev";
118118 list_add_tail(&subsystem_list, &s->slist);
119119 return s;
@@ -142,7 +142,7 @@ static void parse_line_subsystem(struct parse_state *state, int nargs,
142142
143143 case K_dirname:
144144 if (args[1][0] == '/')
145- s->dirname = args[1];
145+ s->dirname = strdup(args[1]);
146146 else
147147 parse_error(state, "dirname '%s' does not start with '/'\n",
148148 args[1]);
@@ -191,7 +191,7 @@ static void parse_line(struct parse_state *state, char **args, int nargs)
191191 }
192192 }
193193
194-static void parse_config(const char *fn, const std::string& data)
194+static void parse_config(const char *fn, std::string& data)
195195 {
196196 char *args[UEVENTD_PARSER_MAXARGS];
197197
@@ -199,7 +199,7 @@ static void parse_config(const char *fn, const std::string& data)
199199 parse_state state;
200200 state.filename = fn;
201201 state.line = 1;
202- state.ptr = strdup(data.c_str()); // TODO: fix this code!
202+ state.ptr = &data[0];
203203 state.nexttoken = 0;
204204 state.parse_line = parse_line_no_op;
205205 for (;;) {
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -98,6 +98,7 @@ LOCAL_SRC_FILES := $(libcutils_common_sources) \
9898 debugger.c \
9999 klog.c \
100100 partition_utils.c \
101+ probe_module.c \
101102 properties.c \
102103 qtaguid.c \
103104 trace-dev.c \
--- /dev/null
+++ b/libcutils/probe_module.c
@@ -0,0 +1,387 @@
1+/*
2+ * Copyright (C) 2012 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdio.h>
18+#include <stdlib.h>
19+#include <string.h>
20+#include <limits.h>
21+#include <errno.h>
22+#include <fcntl.h>
23+#include <cutils/misc.h>
24+#include <sys/syscall.h>
25+#include <sys/utsname.h>
26+
27+#define LOG_TAG "ProbeModule"
28+#include <cutils/log.h>
29+
30+#define LDM_DEFAULT_MOD_PATH "/system/lib/modules/"
31+
32+extern int delete_module(const char *, unsigned int);
33+
34+/* get_default_mod_path() interface to outside,
35+ * refer to its description in probe_module.h
36+ */
37+char *get_default_mod_path(char *def_mod_path)
38+{
39+ int len;
40+ struct utsname buf;
41+ uname(&buf);
42+ len = snprintf(def_mod_path, PATH_MAX, "%s", LDM_DEFAULT_MOD_PATH);
43+ strcpy(def_mod_path + len, buf.release);
44+ if (access(def_mod_path, F_OK))
45+ def_mod_path[len] = '\0';
46+ else
47+ strcat(def_mod_path, "/");
48+ return def_mod_path;
49+}
50+
51+int insmod(const char *filename, const char *options)
52+{
53+ int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
54+ if (fd == -1) {
55+ ALOGE("insmod: open(\"%s\") failed: %s", filename, strerror(errno));
56+ return -1;
57+ }
58+ int rc = syscall(__NR_finit_module, fd, options, 0);
59+ if (rc == -1) {
60+ if (errno == EEXIST) {
61+ rc = 0;
62+ } else {
63+ ALOGE("finit_module for \"%s\" failed: %s", filename, strerror(errno));
64+ }
65+ }
66+ close(fd);
67+ return rc;
68+}
69+
70+static char *strip_path(char *str)
71+{
72+ char *ptr = strrchr(str, '/');
73+ return ptr ? ptr + 1 : str;
74+}
75+
76+static void hyphen_to_underscore(char *str)
77+{
78+ while (str && *str != '\0') {
79+ if (*str == '-')
80+ *str = '_';
81+ str++;
82+ }
83+}
84+
85+/* Compare module names, but don't differentiate '_' and '-'.
86+ * return: 0 when s1 is matched to s2 or size is zero.
87+ * non-zero in any other cases.
88+ */
89+static int match_name(const char *s1, const char *s2, const size_t size)
90+{
91+ size_t i;
92+
93+ if (!size)
94+ return 0;
95+
96+ for (i = 0; i < size; i++, s1++, s2++) {
97+
98+ if ((*s1 == '_' || *s1 == '-') && (*s2 == '_' || *s2 == '-'))
99+ continue;
100+
101+ if (*s1 != *s2)
102+ return -1;
103+
104+ if (*s1 == '\0')
105+ return 0;
106+ }
107+
108+ return 0;
109+}
110+
111+/* check if a line in dep file is target module's dependency.
112+ * return 1 when it is, otherwise 0 in any other cases.
113+ */
114+static int is_target_module(char *line, const char *target)
115+{
116+ char *token;
117+ char name[PATH_MAX];
118+ const char *delimiter = ":";
119+ int ret = 0;
120+
121+ /* search token */
122+ token = strstr(line, delimiter);
123+
124+ if (!token) {
125+ ALOGE("invalid line: no token");
126+ return 0;
127+ }
128+
129+ /* only take stuff before the token */
130+ *token = '\0';
131+
132+ /* use "module.ko" in comparision */
133+ strcat(strcpy(name, target), ".ko");
134+
135+ ret = !match_name(strip_path(line), name, strlen(name));
136+
137+ /* restore [single] token, keep line unchanged until we parse it later */
138+ *token = *delimiter;
139+
140+ return ret;
141+
142+}
143+
144+/* turn a single string into an array of dependency.
145+ *
146+ * return: dependency array's address if it succeeded. Caller
147+ * is responsible to free the array's memory.
148+ * NULL when any error happens.
149+ */
150+static char **setup_dep(char *line)
151+{
152+ char *tmp = line;
153+ char *brk;
154+ int i;
155+ char **dep;
156+
157+ for (i = 2; (tmp = strchr(tmp, ' ')); i++)
158+ tmp++;
159+
160+ dep = malloc(sizeof(char *) * i);
161+ if (dep) {
162+ i = 0;
163+ do {
164+ tmp = strtok_r(i ? NULL : line, ": ", &brk);
165+ } while ((dep[i++] = tmp));
166+ }
167+
168+ return dep;
169+}
170+
171+/* install all modules in the dependency chain
172+ * deps : A array of module file names, must be terminated by a NULL pointer
173+ * args : The module parameters for target module.
174+ * strip : Non-zero to strip out path info in the file name;
175+ * 0 to keep path info when loading modules.
176+ * base : a prefix to module path, it will NOT be affected by strip flag.
177+ * return : 0 for success or nothing to do; non-zero when any error occurs.
178+ */
179+static int insmod_s(char *dep[], const char *args, int strip, const char *base)
180+{
181+ char *name;
182+ int cnt;
183+ size_t len;
184+ int ret = 0;
185+ char path_name[PATH_MAX];
186+ char def_mod_path[PATH_MAX];
187+ const char *base_dir;
188+
189+ if (base && strlen(base))
190+ base_dir = base;
191+ else
192+ base_dir = get_default_mod_path(def_mod_path);
193+
194+ /* load modules in reversed order */
195+ for (cnt = 0; dep[cnt]; cnt++)
196+ ;
197+
198+ len = strlen(strcpy(path_name, base_dir));
199+
200+ while (!ret && cnt--) {
201+
202+ name = strip ? strip_path(dep[cnt]) : dep[cnt];
203+
204+ strcpy(path_name + len, name);
205+
206+ ret = insmod(path_name, cnt ? "" : args);
207+ }
208+
209+ return ret;
210+}
211+
212+/* remove all modules in a dependency chain
213+ * NOTE: We assume module name in kernel is same as the file name without .ko
214+ */
215+static int rmmod_s(char *dep[], int flags)
216+{
217+ int i;
218+ int ret = 0;
219+
220+ for (i = 0; dep[i]; i++) {
221+ char *mod_name = strip_path(dep[i]);
222+ size_t len = strlen(mod_name);
223+
224+ if (len > 3 && strstr(mod_name, ".ko") == (mod_name + len - 3)) {
225+ mod_name[len - 3] = '\0';
226+
227+ hyphen_to_underscore(mod_name);
228+
229+ ret = delete_module(mod_name, flags);
230+
231+ if (ret) {
232+ ALOGE("%s: Failed to remove module [%s] error (%s)",
233+ __FUNCTION__, mod_name, strerror(errno));
234+ break;
235+
236+ }
237+ }
238+ }
239+
240+ return ret;
241+}
242+
243+/* look_up_dep() find and setup target module's dependency in modules.dep
244+ *
245+ * dep_file: a pointer to module's dep file loaded in memory, its content
246+ * will be CHANGED during parsing.
247+ *
248+ * return: a pointer to an array which holds the dependency strings and
249+ * terminated by a NULL pointer. Caller is responsible to free the
250+ * array's memory.
251+ *
252+ * non-zero in any other cases. Content of dep array is invalid.
253+ */
254+static char **look_up_dep(const char *module_name, void *dep_file)
255+{
256+ char *line;
257+ char *saved_pos;
258+ char *start;
259+ char **dep = NULL;
260+
261+ if (!dep_file || !module_name || *module_name == '\0')
262+ return NULL;
263+
264+ start = (char *)dep_file;
265+
266+ /* We expect modules.dep file has a new line char before EOF. */
267+ while ((line = strtok_r(start, "\n", &saved_pos)) != NULL) {
268+
269+ start = NULL;
270+
271+ if (is_target_module(line, module_name)) {
272+
273+ dep = setup_dep(line);
274+ /* job done */
275+ break;
276+ }
277+ }
278+
279+ return dep;
280+}
281+
282+/* load_dep_file() load a dep file (usually it is modules.dep)
283+ * into memory. Caller is responsible to free the memory.
284+ *
285+ * file_name: dep file's name, if it is NULL or an empty string,
286+ * This function will try to load a dep file in the
287+ * default path defined in LDM_DEFAULT_DEP_FILE
288+ *
289+ * return: a pointer to the allocated mem which holds all
290+ * content of the depfile. a zero pointer will be
291+ * returned for any errors.
292+ * */
293+static void *load_dep_file(const char *file_name)
294+{
295+ unsigned int len;
296+ char def_mod_path[PATH_MAX];
297+ if (!file_name || *file_name == '\0') {
298+ file_name = get_default_mod_path(def_mod_path);
299+ strcat(def_mod_path, "modules.dep");
300+ }
301+
302+ return load_file(file_name, &len);
303+}
304+
305+/* insmod_by_dep() interface to outside,
306+ * refer to its description in probe_module.h
307+ */
308+int insmod_by_dep(const char *module_name,
309+ const char *args,
310+ const char *dep_name,
311+ int strip,
312+ const char *base)
313+{
314+ void *dep_file;
315+ char **dep = NULL;
316+ int ret = -1;
317+
318+ if (!module_name || *module_name == '\0') {
319+ ALOGE("need valid module name");
320+ return ret;
321+ }
322+
323+ dep_file = load_dep_file(dep_name);
324+
325+ if (!dep_file) {
326+ ALOGE("cannot load dep file : %s", dep_name);
327+ return ret;
328+ }
329+
330+ dep = look_up_dep(module_name, dep_file);
331+
332+ if (!dep) {
333+ ALOGE("%s: cannot load module: [%s]", __FUNCTION__, module_name);
334+ goto free_file;
335+ }
336+
337+ ret = insmod_s(dep, args, strip, base);
338+
339+ free(dep);
340+
341+free_file:
342+ free(dep_file);
343+
344+ return ret;
345+
346+}
347+
348+/* rmmod_by_dep() interface to outside,
349+ * refer to its description in probe_module.h
350+ */
351+int rmmod_by_dep(const char *module_name,
352+ const char *dep_name)
353+{
354+ void *dep_file;
355+ char **dep = NULL;
356+ int ret = -1;
357+
358+ if (!module_name || *module_name == '\0') {
359+ ALOGE("need valid module name");
360+ return ret;
361+ }
362+
363+ dep_file = load_dep_file(dep_name);
364+
365+ if (!dep_file) {
366+ ALOGE("cannot load dep file : %s", dep_name);
367+ return ret;
368+ }
369+
370+ dep = look_up_dep(module_name, dep_file);
371+
372+ if (!dep) {
373+ ALOGE("%s: cannot remove module: [%s]", __FUNCTION__, module_name);
374+ goto free_file;
375+ }
376+
377+ ret = rmmod_s(dep, O_NONBLOCK);
378+
379+ free(dep);
380+
381+free_file:
382+ free(dep_file);
383+
384+ return ret;
385+}
386+
387+/* end of file */
--- a/libdiskconfig/Android.mk
+++ b/libdiskconfig/Android.mk
@@ -27,6 +27,6 @@ include $(CLEAR_VARS)
2727 LOCAL_SRC_FILES := $(commonSources)
2828 LOCAL_MODULE := libdiskconfig_host
2929 LOCAL_MODULE_TAGS := optional
30-LOCAL_CFLAGS := -O2 -g -W -Wall -Werror -D_LARGEFILE64_SOURCE
30+LOCAL_CFLAGS := -O2 -g -W -Wall -Werror -D_LARGEFILE64_SOURCE -DHOST_BUILD
3131 include $(BUILD_HOST_STATIC_LIBRARY)
32-endif # HOST_OS == linux
32+endif
--- a/libdiskconfig/config_mbr.c
+++ b/libdiskconfig/config_mbr.c
@@ -260,11 +260,11 @@ config_mbr(struct disk_info *dinfo)
260260 }
261261
262262 /* if extended, need 1 lba for ebr */
263- if ((cur_lba + extended) >= dinfo->num_lba)
263+ if (dinfo->num_lba && (cur_lba + extended) >= dinfo->num_lba)
264264 goto nospace;
265265 else if (pinfo->len_kb != (uint32_t)-1) {
266266 uint32_t sz_lba = (pinfo->len_kb / dinfo->sect_size) * 1024;
267- if ((cur_lba + sz_lba + extended) > dinfo->num_lba)
267+ if (dinfo->num_lba && (cur_lba + sz_lba + extended) > dinfo->num_lba)
268268 goto nospace;
269269 }
270270
--- a/libdiskconfig/diskconfig.c
+++ b/libdiskconfig/diskconfig.c
@@ -27,7 +27,9 @@
2727 #include <sys/ioctl.h>
2828 #include <sys/stat.h>
2929
30+#ifndef HOST_BUILD
3031 #include <linux/fs.h>
32+#endif
3133
3234 #include <cutils/config_utils.h>
3335 #include <log/log.h>
@@ -76,7 +78,7 @@ parse_len(const char *str, uint64_t *plen)
7678 }
7779 } else {
7880 /* convert len to kilobytes */
79- if (multiple > 1024)
81+ if (multiple >= 1024)
8082 multiple >>= 10;
8183 *plen *= multiple;
8284
@@ -236,6 +238,7 @@ fail:
236238 return NULL;
237239 }
238240
241+#ifndef HOST_BUILD
239242 static int
240243 sync_ptable(int fd)
241244 {
@@ -256,6 +259,13 @@ sync_ptable(int fd)
256259
257260 return 0;
258261 }
262+#else
263+static int sync_ptable(int fd)
264+{
265+ (void)fd;
266+ return 0;
267+}
268+#endif
259269
260270 /* This function verifies that the disk info provided is valid, and if so,
261271 * returns an open file descriptor.
@@ -272,7 +282,6 @@ static int
272282 validate(struct disk_info *dinfo)
273283 {
274284 int fd;
275- int sect_sz;
276285 uint64_t disk_size;
277286 uint64_t total_size;
278287 int cnt;
@@ -298,6 +307,12 @@ validate(struct disk_info *dinfo)
298307 /* Verify that we can operate on the device that was requested.
299308 * We presently only support block devices and regular file images. */
300309 if (S_ISBLK(stat.st_mode)) {
310+#ifdef HOST_BUILD
311+ ALOGE("Block device manipulation on host forbidden");
312+ goto fail;
313+#else
314+ int sect_sz;
315+
301316 /* get the sector size and make sure we agree */
302317 if (ioctl(fd, BLKSSZGET, &sect_sz) < 0) {
303318 ALOGE("Cannot get sector size (errno=%d)", errno);
@@ -319,6 +334,7 @@ validate(struct disk_info *dinfo)
319334 dinfo->num_lba = (uint32_t)(disk_size / (uint64_t)dinfo->sect_size);
320335 } else
321336 disk_size = (uint64_t)dinfo->num_lba * (uint64_t)dinfo->sect_size;
337+#endif
322338 } else if (S_ISREG(stat.st_mode)) {
323339 ALOGI("Requesting operation on a regular file, not block device.");
324340 if (!dinfo->sect_size) {
--- a/libdiskconfig/diskutils.c
+++ b/libdiskconfig/diskutils.c
@@ -36,6 +36,7 @@ write_raw_image(const char *dst, const char *src, loff_t offset, int test)
3636 int dst_fd = -1;
3737 int src_fd = -1;
3838 uint8_t buffer[2048];
39+ ssize_t buf_offset;
3940 ssize_t nr_bytes;
4041 ssize_t tmp;
4142 int done = 0;
@@ -80,8 +81,9 @@ write_raw_image(const char *dst, const char *src, loff_t offset, int test)
8081 if (test)
8182 nr_bytes = 0;
8283
84+ buf_offset = 0;
8385 while (nr_bytes > 0) {
84- if ((tmp = write(dst_fd, buffer, nr_bytes)) < 0) {
86+ if ((tmp = write(dst_fd, &buffer[buf_offset], nr_bytes)) < 0) {
8587 /* XXX: Should we not even bother with EINTR? */
8688 if (errno == EINTR)
8789 continue;
@@ -91,6 +93,7 @@ write_raw_image(const char *dst, const char *src, loff_t offset, int test)
9193 if (!tmp)
9294 continue;
9395 nr_bytes -= tmp;
96+ buf_offset += tmp;
9497 }
9598 }
9699
--- a/libpixelflinger/tests/codegen/Android.mk
+++ b/libpixelflinger/tests/codegen/Android.mk
@@ -1,7 +1,7 @@
11 LOCAL_PATH:= $(call my-dir)
22 include $(CLEAR_VARS)
33
4-ifeq ($(TARGET_ARCH),x86)
4+ifneq ($(filter x86%,$(TARGET_ARCH)),)
55 LOCAL_SRC_FILES:= \
66 codegen.cpp
77 else
@@ -16,7 +16,7 @@ LOCAL_SHARED_LIBRARIES := \
1616 LOCAL_C_INCLUDES := \
1717 $(LOCAL_PATH)/../..
1818
19-ifeq ($(TARGET_ARCH),x86)
19+ifneq ($(filter x86%,$(TARGET_ARCH)),)
2020 LOCAL_STATIC_LIBRARIES := libenc
2121 endif
2222
--- a/libsuspend/autosuspend.c
+++ b/libsuspend/autosuspend.c
@@ -14,26 +14,38 @@
1414 * limitations under the License.
1515 */
1616
17+#include <errno.h>
18+#include <fcntl.h>
1719 #include <stdbool.h>
20+#include <string.h>
1821
1922 #define LOG_TAG "libsuspend"
2023 #include <cutils/log.h>
24+#include <cutils/properties.h>
2125
2226 #include <suspend/autosuspend.h>
2327
2428 #include "autosuspend_ops.h"
2529
30+static const char *default_sleep_state = "mem";
31+static const char *fallback_sleep_state = "freeze";
32+
2633 static struct autosuspend_ops *autosuspend_ops;
2734 static bool autosuspend_enabled;
2835 static bool autosuspend_inited;
2936
3037 static int autosuspend_init(void)
3138 {
39+ char buf[PROPERTY_VALUE_MAX];
40+
3241 if (autosuspend_inited) {
3342 return 0;
3443 }
3544
36- autosuspend_ops = autosuspend_earlysuspend_init();
45+ property_get("sleep.earlysuspend", buf, "0");
46+ if (buf[0] == '1') {
47+ autosuspend_ops = autosuspend_earlysuspend_init();
48+ }
3749 if (autosuspend_ops) {
3850 goto out;
3951 }
@@ -110,3 +122,34 @@ int autosuspend_disable(void)
110122 autosuspend_enabled = false;
111123 return 0;
112124 }
125+
126+static bool sleep_state_available(const char *state)
127+{
128+ char buf[64];
129+ int fd = TEMP_FAILURE_RETRY(open(SYS_POWER_STATE, O_RDONLY));
130+ if (fd < 0) {
131+ ALOGE("Error reading power state: %s", SYS_POWER_STATE);
132+ return false;
133+ }
134+ TEMP_FAILURE_RETRY(read(fd, buf, 64));
135+ close(fd);
136+ return !!strstr(buf, state);
137+}
138+
139+const char *get_sleep_state()
140+{
141+ static char sleep_state[PROPERTY_VALUE_MAX] = "";
142+
143+ if (!sleep_state[0]) {
144+ if (property_get("sleep.state", sleep_state, NULL) > 0) {
145+ ALOGD("autosuspend using sleep.state property (%s)", sleep_state);
146+ } else if (sleep_state_available(default_sleep_state)) {
147+ ALOGD("autosuspend using default sleep_state (%s)", default_sleep_state);
148+ strncpy(sleep_state, default_sleep_state, PROPERTY_VALUE_MAX);
149+ } else {
150+ ALOGW("autosuspend \"%s\" unavailable, using fallback sleep.state (%s)", default_sleep_state, fallback_sleep_state);
151+ strncpy(sleep_state, fallback_sleep_state, PROPERTY_VALUE_MAX);
152+ }
153+ }
154+ return sleep_state;
155+}
--- a/libsuspend/autosuspend_earlysuspend.c
+++ b/libsuspend/autosuspend_earlysuspend.c
@@ -29,12 +29,10 @@
2929
3030 #include "autosuspend_ops.h"
3131
32-#define EARLYSUSPEND_SYS_POWER_STATE "/sys/power/state"
3332 #define EARLYSUSPEND_WAIT_FOR_FB_SLEEP "/sys/power/wait_for_fb_sleep"
3433 #define EARLYSUSPEND_WAIT_FOR_FB_WAKE "/sys/power/wait_for_fb_wake"
3534
3635 static int sPowerStatefd;
37-static const char *pwr_state_mem = "mem";
3836 static const char *pwr_state_on = "on";
3937 static pthread_t earlysuspend_thread;
4038 static pthread_mutex_t earlysuspend_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -45,37 +43,58 @@ static enum {
4543 EARLYSUSPEND_MEM,
4644 } earlysuspend_state = EARLYSUSPEND_ON;
4745
48-int wait_for_fb_wake(void)
46+static void log_err(const char *fmt, ...)
4947 {
50- int err = 0;
51- char buf;
52- int fd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_WAIT_FOR_FB_WAKE, O_RDONLY, 0));
48+ char err[80];
49+ char buf[512];
50+
51+ strerror_r(errno, err, sizeof(err));
52+
53+ va_list ap;
54+ va_start(ap, fmt);
55+ vsnprintf(buf, sizeof(buf), fmt, ap);
56+ va_end(ap);
57+ ALOGE("Error %s: %s", buf, err);
58+}
59+
60+static int open_file(const char *file, char *buf, size_t sz, int *fd)
61+{
62+ int err;
63+ int f = TEMP_FAILURE_RETRY(open(file, fd ? O_RDWR : O_RDONLY, 0));
5364 // if the file doesn't exist, the error will be caught in read() below
54- err = TEMP_FAILURE_RETRY(read(fd, &buf, 1));
55- ALOGE_IF(err < 0,
56- "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
57- close(fd);
58- return err < 0 ? err : 0;
65+ err = TEMP_FAILURE_RETRY(read(f, buf, sz));
66+
67+ if (err < 0) {
68+ log_err("opening %s", file);
69+ } else {
70+ err = 0;
71+ }
72+
73+ if (fd == NULL) {
74+ close(f);
75+ } else {
76+ *fd = f;
77+ }
78+ return err;
79+}
80+
81+static int wait_for_fb_wake(void)
82+{
83+ char buf;
84+ return open_file(EARLYSUSPEND_WAIT_FOR_FB_WAKE, &buf, 1, NULL);
5985 }
6086
6187 static int wait_for_fb_sleep(void)
6288 {
63- int err = 0;
6489 char buf;
65- int fd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, O_RDONLY, 0));
66- // if the file doesn't exist, the error will be caught in read() below
67- err = TEMP_FAILURE_RETRY(read(fd, &buf, 1));
68- ALOGE_IF(err < 0,
69- "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
70- close(fd);
71- return err < 0 ? err : 0;
90+ return open_file(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, &buf, 1, NULL);
7291 }
7392
7493 static void *earlysuspend_thread_func(void __unused *arg)
7594 {
7695 while (1) {
7796 if (wait_for_fb_sleep()) {
78- ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread\n");
97+ ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread");
7998 return NULL;
8099 }
81100 pthread_mutex_lock(&earlysuspend_mutex);
@@ -84,7 +103,7 @@ static void *earlysuspend_thread_func(void __unused *arg)
84103 pthread_mutex_unlock(&earlysuspend_mutex);
85104
86105 if (wait_for_fb_wake()) {
87- ALOGE("Failed reading wait_for_fb_wake, exiting earlysuspend thread\n");
106+ ALOGE("Failed reading wait_for_fb_wake, exiting earlysuspend thread");
88107 return NULL;
89108 }
90109 pthread_mutex_lock(&earlysuspend_mutex);
@@ -95,16 +114,15 @@ static void *earlysuspend_thread_func(void __unused *arg)
95114 }
96115 static int autosuspend_earlysuspend_enable(void)
97116 {
98- char buf[80];
99117 int ret;
118+ const char *sleep_state = get_sleep_state();
100119
101- ALOGV("autosuspend_earlysuspend_enable\n");
120+ ALOGI("autosuspend_earlysuspend_enable");
102121
103- ret = write(sPowerStatefd, pwr_state_mem, strlen(pwr_state_mem));
122+ ret = TEMP_FAILURE_RETRY(write(sPowerStatefd, sleep_state, strlen(sleep_state)));
104123 if (ret < 0) {
105- strerror_r(errno, buf, sizeof(buf));
106- ALOGE("Error writing to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
107- goto err;
124+ log_err("writing %s to %s", sleep_state, SYS_POWER_STATE);
125+ return ret;
108126 }
109127
110128 if (wait_for_earlysuspend) {
@@ -115,26 +133,22 @@ static int autosuspend_earlysuspend_enable(void)
115133 pthread_mutex_unlock(&earlysuspend_mutex);
116134 }
117135
118- ALOGV("autosuspend_earlysuspend_enable done\n");
136+ ALOGD("autosuspend_earlysuspend_enable done");
119137
120138 return 0;
121-
122-err:
123- return ret;
124139 }
125140
126141 static int autosuspend_earlysuspend_disable(void)
127142 {
128- char buf[80];
129143 int ret;
130144
131- ALOGV("autosuspend_earlysuspend_disable\n");
145+ ALOGI("autosuspend_earlysuspend_disable");
132146
133147 ret = TEMP_FAILURE_RETRY(write(sPowerStatefd, pwr_state_on, strlen(pwr_state_on)));
134148 if (ret < 0) {
135- strerror_r(errno, buf, sizeof(buf));
136- ALOGE("Error writing to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
137- goto err;
149+#if DEBUG
150+ log_err("writing %s to %s", pwr_state_on, SYS_POWER_STATE);
151+#endif
138152 }
139153
140154 if (wait_for_earlysuspend) {
@@ -145,12 +159,9 @@ static int autosuspend_earlysuspend_disable(void)
145159 pthread_mutex_unlock(&earlysuspend_mutex);
146160 }
147161
148- ALOGV("autosuspend_earlysuspend_disable done\n");
162+ ALOGD("autosuspend_earlysuspend_disable done");
149163
150164 return 0;
151-
152-err:
153- return ret;
154165 }
155166
156167 struct autosuspend_ops autosuspend_earlysuspend_ops = {
@@ -160,26 +171,26 @@ struct autosuspend_ops autosuspend_earlysuspend_ops = {
160171
161172 void start_earlysuspend_thread(void)
162173 {
163- char buf[80];
164174 int ret;
165175
166176 ret = access(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, F_OK);
167177 if (ret < 0) {
178+ log_err("accessing %s", EARLYSUSPEND_WAIT_FOR_FB_SLEEP);
168179 return;
169180 }
170181
171182 ret = access(EARLYSUSPEND_WAIT_FOR_FB_WAKE, F_OK);
172183 if (ret < 0) {
184+ log_err("accessing %s", EARLYSUSPEND_WAIT_FOR_FB_WAKE);
173185 return;
174186 }
175187
176188 wait_for_fb_wake();
177189
178- ALOGI("Starting early suspend unblocker thread\n");
190+ ALOGI("Starting early suspend unblocker thread");
179191 ret = pthread_create(&earlysuspend_thread, NULL, earlysuspend_thread_func, NULL);
180192 if (ret) {
181- strerror_r(errno, buf, sizeof(buf));
182- ALOGE("Error creating thread: %s\n", buf);
193+ log_err("creating thread");
183194 return;
184195 }
185196
@@ -188,31 +199,18 @@ void start_earlysuspend_thread(void)
188199
189200 struct autosuspend_ops *autosuspend_earlysuspend_init(void)
190201 {
191- char buf[80];
192202 int ret;
203+ char pwr_st[128];
193204
194- sPowerStatefd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR));
195-
196- if (sPowerStatefd < 0) {
197- strerror_r(errno, buf, sizeof(buf));
198- ALOGW("Error opening %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
199- return NULL;
200- }
201-
202- ret = TEMP_FAILURE_RETRY(write(sPowerStatefd, "on", 2));
205+ ret = open_file(SYS_POWER_STATE, pwr_st, sizeof(pwr_st), &sPowerStatefd);
203206 if (ret < 0) {
204- strerror_r(errno, buf, sizeof(buf));
205- ALOGW("Error writing 'on' to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
206- goto err_write;
207+ close(sPowerStatefd);
208+ return NULL;
207209 }
208210
209- ALOGI("Selected early suspend\n");
211+ ALOGI("Selected early suspend");
210212
211213 start_earlysuspend_thread();
212214
213215 return &autosuspend_earlysuspend_ops;
214-
215-err_write:
216- close(sPowerStatefd);
217- return NULL;
218216 }
--- a/libsuspend/autosuspend_ops.h
+++ b/libsuspend/autosuspend_ops.h
@@ -17,6 +17,8 @@
1717 #ifndef _LIBSUSPEND_AUTOSUSPEND_OPS_H_
1818 #define _LIBSUSPEND_AUTOSUSPEND_OPS_H_
1919
20+#define SYS_POWER_STATE "/sys/power/state"
21+
2022 struct autosuspend_ops {
2123 int (*enable)(void);
2224 int (*disable)(void);
@@ -26,4 +28,6 @@ struct autosuspend_ops *autosuspend_autosleep_init(void);
2628 struct autosuspend_ops *autosuspend_earlysuspend_init(void);
2729 struct autosuspend_ops *autosuspend_wakeup_count_init(void);
2830
31+const char *get_sleep_state();
32+
2933 #endif
--- a/libsuspend/autosuspend_wakeup_count.c
+++ b/libsuspend/autosuspend_wakeup_count.c
@@ -29,18 +29,165 @@
2929 //#define LOG_NDEBUG 0
3030 #include <cutils/log.h>
3131
32+#include <cutils/properties.h>
33+#include <linux/uinput.h>
34+#include <dirent.h>
35+#include <poll.h>
36+
3237 #include "autosuspend_ops.h"
3338
34-#define SYS_POWER_STATE "/sys/power/state"
3539 #define SYS_POWER_WAKEUP_COUNT "/sys/power/wakeup_count"
40+#define MAX_POWERBTNS 3
3641
42+static int uinput_fd = -1;
3743 static int state_fd;
3844 static int wakeup_count_fd;
3945 static pthread_t suspend_thread;
4046 static sem_t suspend_lockout;
41-static const char *sleep_state = "mem";
4247 static void (*wakeup_func)(bool success) = NULL;
4348
49+static void emit_key(int ufd, int key_code, int val)
50+{
51+ struct input_event iev;
52+ iev.type = EV_KEY;
53+ iev.code = key_code;
54+ iev.value = val;
55+ iev.time.tv_sec = 0;
56+ iev.time.tv_usec = 0;
57+ write(ufd, &iev, sizeof(iev));
58+ iev.type = EV_SYN;
59+ iev.code = SYN_REPORT;
60+ iev.value = 0;
61+ write(ufd, &iev, sizeof(iev));
62+ ALOGD("send key %d (%d) on fd %d", key_code, val, ufd);
63+}
64+
65+static void send_key_wakeup(int ufd)
66+{
67+ emit_key(ufd, KEY_WAKEUP, 1);
68+ emit_key(ufd, KEY_WAKEUP, 0);
69+}
70+
71+static void send_key_power(int ufd, bool longpress)
72+{
73+ emit_key(ufd, KEY_POWER, 1);
74+ if (longpress) sleep(2);
75+ emit_key(ufd, KEY_POWER, 0);
76+}
77+
78+static int openfds(struct pollfd pfds[])
79+{
80+ int cnt = 0;
81+ const char *dirname = "/dev/input";
82+ struct dirent *de;
83+ DIR *dir;
84+
85+ if ((dir = opendir(dirname))) {
86+ while ((cnt < MAX_POWERBTNS) && (de = readdir(dir))) {
87+ int fd;
88+ char name[PATH_MAX];
89+ if (de->d_name[0] != 'e') /* eventX */
90+ continue;
91+ snprintf(name, PATH_MAX, "%s/%s", dirname, de->d_name);
92+ fd = open(name, O_RDWR | O_NONBLOCK);
93+ if (fd < 0) {
94+ ALOGE("could not open %s, %s", name, strerror(errno));
95+ continue;
96+ }
97+ name[sizeof(name) - 1] = '\0';
98+ if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
99+ ALOGE("could not get device name for %s, %s", name, strerror(errno));
100+ name[0] = '\0';
101+ }
102+ // TODO: parse /etc/excluded-input-devices.xml
103+ if (strcmp(name, "Power Button")) {
104+ close(fd);
105+ continue;
106+ }
107+
108+ ALOGI("open %s(%s) ok fd=%d", de->d_name, name, fd);
109+ pfds[cnt].events = POLLIN;
110+ pfds[cnt++].fd = fd;
111+ }
112+ closedir(dir);
113+ }
114+
115+ return cnt;
116+}
117+
118+static void *powerbtnd_thread_func(void *arg __attribute__((unused)))
119+{
120+ int cnt, timeout, pollres;
121+ bool longpress = true;
122+ bool doubleclick = property_get_bool("poweroff.doubleclick", 0);
123+ struct pollfd pfds[MAX_POWERBTNS];
124+
125+ timeout = -1;
126+ cnt = openfds(pfds);
127+
128+ while (cnt > 0 && (pollres = poll(pfds, cnt, timeout)) >= 0) {
129+ ALOGV("pollres=%d %d\n", pollres, timeout);
130+ if (pollres == 0) {
131+ ALOGI("timeout, send one power key");
132+ send_key_power(uinput_fd, 0);
133+ timeout = -1;
134+ longpress = true;
135+ continue;
136+ }
137+ for (int i = 0; i < cnt; ++i) {
138+ if (pfds[i].revents & POLLIN) {
139+ struct input_event iev;
140+ size_t res = read(pfds[i].fd, &iev, sizeof(iev));
141+ if (res < sizeof(iev)) {
142+ ALOGW("insufficient input data(%zd)? fd=%d", res, pfds[i].fd);
143+ continue;
144+ }
145+ ALOGD("type=%d code=%d value=%d from fd=%d", iev.type, iev.code, iev.value, pfds[i].fd);
146+ if (iev.type == EV_KEY && iev.code == KEY_POWER && !iev.value) {
147+ if (!doubleclick || timeout > 0) {
148+ send_key_power(uinput_fd, longpress);
149+ timeout = -1;
150+ } else {
151+ timeout = 1000; // one second
152+ }
153+ } else if (iev.type == EV_SYN && iev.code == SYN_REPORT && iev.value) {
154+ ALOGI("got a resuming event");
155+ longpress = false;
156+ timeout = 1000; // one second
157+ }
158+ }
159+ }
160+ }
161+
162+ ALOGE_IF(cnt, "poll error: %s", strerror(errno));
163+ return NULL;
164+}
165+
166+static void init_android_power_button()
167+{
168+ static pthread_t powerbtnd_thread;
169+ struct uinput_user_dev ud;
170+
171+ if (uinput_fd >= 0) return;
172+
173+ uinput_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
174+ if (uinput_fd < 0) {
175+ ALOGE("could not open uinput device: %s", strerror(errno));
176+ return;
177+ }
178+
179+ memset(&ud, 0, sizeof(ud));
180+ strcpy(ud.name, "Android Power Button");
181+ write(uinput_fd, &ud, sizeof(ud));
182+ ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
183+ ioctl(uinput_fd, UI_SET_KEYBIT, KEY_POWER);
184+ ioctl(uinput_fd, UI_SET_KEYBIT, KEY_WAKEUP);
185+ ioctl(uinput_fd, UI_DEV_CREATE, 0);
186+
187+ pthread_create(&powerbtnd_thread, NULL, powerbtnd_thread_func, NULL);
188+ pthread_setname_np(powerbtnd_thread, "powerbtnd");
189+}
190+
44191 static void *suspend_thread_func(void *arg __attribute__((unused)))
45192 {
46193 char buf[80];
@@ -81,10 +228,13 @@ static void *suspend_thread_func(void *arg __attribute__((unused)))
81228 strerror_r(errno, buf, sizeof(buf));
82229 ALOGE("Error writing to %s: %s\n", SYS_POWER_WAKEUP_COUNT, buf);
83230 } else {
231+ const char *sleep_state = get_sleep_state();
84232 ALOGV("%s: write %s to %s\n", __func__, sleep_state, SYS_POWER_STATE);
85233 ret = TEMP_FAILURE_RETRY(write(state_fd, sleep_state, strlen(sleep_state)));
86234 if (ret < 0) {
87235 success = false;
236+ } else {
237+ send_key_wakeup(uinput_fd);
88238 }
89239 void (*func)(bool success) = wakeup_func;
90240 if (func != NULL) {
@@ -159,6 +309,8 @@ struct autosuspend_ops *autosuspend_wakeup_count_init(void)
159309 int ret;
160310 char buf[80];
161311
312+ init_android_power_button();
313+
162314 state_fd = TEMP_FAILURE_RETRY(open(SYS_POWER_STATE, O_RDWR));
163315 if (state_fd < 0) {
164316 strerror_r(errno, buf, sizeof(buf));
--- a/libsync/Android.mk
+++ b/libsync/Android.mk
@@ -4,17 +4,27 @@ include $(CLEAR_VARS)
44 LOCAL_SRC_FILES := sync.c
55 LOCAL_MODULE := libsync
66 LOCAL_MODULE_TAGS := optional
7-LOCAL_SHARED_LIBRARIES := liblog
87 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
98 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
109 LOCAL_CFLAGS := -Werror
1110 include $(BUILD_SHARED_LIBRARY)
1211
12+# libsync_recovery is only intended for the recovery binary.
13+# Future versions of the kernel WILL require an updated libsync, and will break
14+# anything statically linked against the current libsync.
15+include $(CLEAR_VARS)
16+LOCAL_SRC_FILES := sync.c
17+LOCAL_MODULE := libsync_recovery
18+LOCAL_MODULE_TAGS := optional
19+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
20+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
21+LOCAL_CFLAGS := -Werror
22+include $(BUILD_STATIC_LIBRARY)
23+
1324 include $(CLEAR_VARS)
1425 LOCAL_SRC_FILES := sync.c sync_test.c
1526 LOCAL_MODULE := sync_test
1627 LOCAL_MODULE_TAGS := optional tests
17-LOCAL_SHARED_LIBRARIES := liblog
1828 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
1929 LOCAL_CFLAGS := -Werror
2030 include $(BUILD_EXECUTABLE)
--- a/libsync/include/sync/sync.h
+++ b/libsync/include/sync/sync.h
@@ -22,9 +22,16 @@
2222 #include <sys/cdefs.h>
2323 #include <stdint.h>
2424
25+#include <linux/types.h>
26+
2527 __BEGIN_DECLS
2628
27-// XXX: These structs are copied from the header "linux/sync.h".
29+struct sync_legacy_merge_data {
30+ int32_t fd2;
31+ char name[32];
32+ int32_t fence;
33+};
34+
2835 struct sync_fence_info_data {
2936 uint32_t len;
3037 char name[32];
@@ -41,6 +48,108 @@ struct sync_pt_info {
4148 uint8_t driver_data[0];
4249 };
4350
51+#define SYNC_IOC_MAGIC '>'
52+
53+/**
54+ * DOC: SYNC_IOC_LEGACY_WAIT - wait for a fence to signal
55+ *
56+ * pass timeout in milliseconds. Waits indefinitely timeout < 0.
57+ *
58+ * This is the legacy version of the Sync API before the de-stage that happened
59+ * on Linux kernel 4.7.
60+ */
61+#define SYNC_IOC_LEGACY_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
62+
63+/**
64+ * DOC: SYNC_IOC_MERGE - merge two fences
65+ *
66+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
67+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
68+ * new fence's fd in sync_merge_data.fence
69+ *
70+ * This is the legacy version of the Sync API before the de-stage that happened
71+ * on Linux kernel 4.7.
72+ */
73+#define SYNC_IOC_LEGACY_MERGE _IOWR(SYNC_IOC_MAGIC, 1, \
74+ struct sync_legacy_merge_data)
75+
76+/**
77+ * DOC: SYNC_IOC_LEGACY_FENCE_INFO - get detailed information on a fence
78+ *
79+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
80+ * Caller should write the size of the buffer into len. On return, len is
81+ * updated to reflect the total size of the sync_fence_info_data including
82+ * pt_info.
83+ *
84+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
85+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
86+ *
87+ * This is the legacy version of the Sync API before the de-stage that happened
88+ * on Linux kernel 4.7.
89+ */
90+#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\
91+ struct sync_fence_info_data)
92+
93+struct sync_merge_data {
94+ char name[32];
95+ int32_t fd2;
96+ int32_t fence;
97+ uint32_t flags;
98+ uint32_t pad;
99+};
100+
101+struct sync_file_info {
102+ char name[32];
103+ int32_t status;
104+ uint32_t flags;
105+ uint32_t num_fences;
106+ uint32_t pad;
107+
108+ uint64_t sync_fence_info;
109+};
110+
111+struct sync_fence_info {
112+ char obj_name[32];
113+ char driver_name[32];
114+ int32_t status;
115+ uint32_t flags;
116+ uint64_t timestamp_ns;
117+};
118+
119+/**
120+ * Mainline API:
121+ *
122+ * Opcodes 0, 1 and 2 were burned during a API change to avoid users of the
123+ * old API to get weird errors when trying to handling sync_files. The API
124+ * change happened during the de-stage of the Sync Framework when there was
125+ * no upstream users available.
126+ */
127+
128+/**
129+ * DOC: SYNC_IOC_MERGE - merge two fences
130+ *
131+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
132+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
133+ * new fence's fd in sync_merge_data.fence
134+ *
135+ * This is the new version of the Sync API after the de-stage that happened
136+ * on Linux kernel 4.7.
137+ */
138+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
139+
140+/**
141+ * DOC: SYNC_IOC_FILE_INFO - get detailed information on a sync_file
142+ *
143+ * Takes a struct sync_file_info. If num_fences is 0, the field is updated
144+ * with the actual number of fences. If num_fences is > 0, the system will
145+ * use the pointer provided on sync_fence_info to return up to num_fences of
146+ * struct sync_fence_info, with detailed fence information.
147+ *
148+ * This is the new version of the Sync API after the de-stage that happened
149+ * on Linux kernel 4.7.
150+ */
151+#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
152+
44153 /* timeout in msecs */
45154 int sync_wait(int fd, int timeout);
46155 int sync_merge(const char *name, int fd1, int fd2);
--- a/libsync/sync.c
+++ b/libsync/sync.c
@@ -20,53 +20,155 @@
2020 #include <malloc.h>
2121 #include <stdint.h>
2222 #include <string.h>
23-
24-#include <linux/sync.h>
25-#include <linux/sw_sync.h>
23+#include <errno.h>
24+#include <poll.h>
2625
2726 #include <sys/ioctl.h>
2827 #include <sys/stat.h>
2928 #include <sys/types.h>
3029
30+#include <sync/sync.h>
31+
32+
33+struct sw_sync_create_fence_data {
34+ __u32 value;
35+ char name[32];
36+ __s32 fence;
37+};
38+
39+#define SW_SYNC_IOC_MAGIC 'W'
40+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0, struct sw_sync_create_fence_data)
41+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
42+
3143 int sync_wait(int fd, int timeout)
3244 {
33- __s32 to = timeout;
45+ struct pollfd fds;
46+ int ret;
47+
48+ if (fd < 0) {
49+ errno = EINVAL;
50+ return -1;
51+ }
3452
35- return ioctl(fd, SYNC_IOC_WAIT, &to);
53+ fds.fd = fd;
54+ fds.events = POLLIN;
55+
56+ do {
57+ ret = poll(&fds, 1, timeout);
58+ if (ret > 0) {
59+ if (fds.revents & (POLLERR | POLLNVAL)) {
60+ errno = EINVAL;
61+ return -1;
62+ }
63+ return 0;
64+ } else if (ret == 0) {
65+ errno = ETIME;
66+ return -1;
67+ }
68+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
69+
70+ return ret;
3671 }
3772
3873 int sync_merge(const char *name, int fd1, int fd2)
3974 {
75+ struct sync_legacy_merge_data legacy_data;
4076 struct sync_merge_data data;
41- int err;
77+ int ret;
4278
4379 data.fd2 = fd2;
4480 strlcpy(data.name, name, sizeof(data.name));
81+ data.flags = 0;
82+ data.pad = 0;
4583
46- err = ioctl(fd1, SYNC_IOC_MERGE, &data);
47- if (err < 0)
48- return err;
84+ ret = ioctl(fd1, SYNC_IOC_MERGE, &data);
85+ if (ret < 0 && errno == ENOTTY) {
86+ legacy_data.fd2 = fd2;
87+ strlcpy(legacy_data.name, name, sizeof(legacy_data.name));
88+
89+ ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &legacy_data);
90+ if (ret < 0)
91+ return ret;
92+
93+ return legacy_data.fence;
94+ } else if (ret < 0) {
95+ return ret;
96+ }
4997
5098 return data.fence;
5199 }
52100
53101 struct sync_fence_info_data *sync_fence_info(int fd)
54102 {
55- struct sync_fence_info_data *info;
56- int err;
57-
58- info = malloc(4096);
59- if (info == NULL)
103+ struct sync_fence_info_data *legacy_info;
104+ struct sync_pt_info *legacy_pt_info;
105+ struct sync_file_info *info;
106+ struct sync_fence_info *fence_info;
107+ int err, num_fences, i;
108+
109+ legacy_info = malloc(4096);
110+ if (legacy_info == NULL)
60111 return NULL;
61112
62- info->len = 4096;
63- err = ioctl(fd, SYNC_IOC_FENCE_INFO, info);
64- if (err < 0) {
65- free(info);
113+ legacy_info->len = 4096;
114+ err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, legacy_info);
115+ if (err < 0 && errno != ENOTTY) {
116+ free(legacy_info);
66117 return NULL;
118+ } else if (err == 0) {
119+ return legacy_info;
120+ }
121+
122+ info = calloc(1, sizeof(*info));
123+ if (info == NULL)
124+ goto free;
125+
126+ err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
127+ if (err < 0)
128+ goto free;
129+
130+ num_fences = info->num_fences;
131+
132+ if (num_fences) {
133+ info->flags = 0;
134+ info->num_fences = num_fences;
135+ info->sync_fence_info = (uint64_t) calloc(num_fences,
136+ sizeof(struct sync_fence_info));
137+ if ((void *)info->sync_fence_info == NULL)
138+ goto free;
139+
140+ err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
141+ if (err < 0) {
142+ free((void *)info->sync_fence_info);
143+ goto free;
144+ }
67145 }
68146
69- return info;
147+ legacy_info->len = sizeof(*legacy_info) +
148+ num_fences * sizeof(struct sync_fence_info);
149+ strlcpy(legacy_info->name, info->name, sizeof(legacy_info->name));
150+ legacy_info->status = info->status;
151+
152+ legacy_pt_info = (struct sync_pt_info *)legacy_info->pt_info;
153+ fence_info = (struct sync_fence_info *)info->sync_fence_info;
154+ for (i = 0 ; i < num_fences ; i++) {
155+ legacy_pt_info[i].len = sizeof(*legacy_pt_info);
156+ strlcpy(legacy_pt_info[i].obj_name, fence_info[i].obj_name,
157+ sizeof(legacy_pt_info->obj_name));
158+ strlcpy(legacy_pt_info[i].driver_name, fence_info[i].driver_name,
159+ sizeof(legacy_pt_info->driver_name));
160+ legacy_pt_info[i].status = fence_info[i].status;
161+ legacy_pt_info[i].timestamp_ns = fence_info[i].timestamp_ns;
162+ }
163+
164+ free((void *)info->sync_fence_info);
165+ free(info);
166+ return legacy_info;
167+
168+free:
169+ free(legacy_info);
170+ free(info);
171+ return NULL;
70172 }
71173
72174 struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info,
@@ -91,7 +193,13 @@ void sync_fence_info_free(struct sync_fence_info_data *info)
91193
92194 int sw_sync_timeline_create(void)
93195 {
94- return open("/dev/sw_sync", O_RDWR);
196+ int ret;
197+
198+ ret = open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
199+ if (ret < 0)
200+ ret = open("/dev/sw_sync", O_RDWR);
201+
202+ return ret;
95203 }
96204
97205 int sw_sync_timeline_inc(int fd, unsigned count)
--- a/libsync/sync_test.c
+++ b/libsync/sync_test.c
@@ -92,7 +92,7 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
9292
9393 for (j = 0; j < 2; j++) {
9494 unsigned val = i + j * 3 + 1;
95- sprintf(str, "test_fence%d-%d", i, j);
95+ snprintf(str, sizeof(str), "test_fence%d-%d", i, j);
9696 int fd = sw_sync_fence_create(sync_timeline_fd, str, val);
9797 if (fd < 0) {
9898 printf("can't create sync pt %d: %s", val, strerror(errno));
@@ -106,7 +106,7 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
106106
107107 sync_data[3].thread_no = 3;
108108 for (j = 0; j < 2; j++) {
109- sprintf(str, "merged_fence%d", j);
109+ snprintf(str, sizeof(str), "merged_fence%d", j);
110110 sync_data[3].fd[j] = sync_merge(str, sync_data[0].fd[j], sync_data[1].fd[j]);
111111 if (sync_data[3].fd[j] < 0) {
112112 printf("can't merge sync pts %d and %d: %s\n",
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -251,17 +251,22 @@ public:
251251 {
252252 Mutex::Autolock _l(mMutex);
253253 char buf[128];
254- sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
254+ snprintf(buf, sizeof(buf),
255+ "Strong references on RefBase %p (weakref_type %p):\n",
256+ mBase, this);
255257 text.append(buf);
256258 printRefsLocked(&text, mStrongRefs);
257- sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
259+ snprintf(buf, sizeof(buf),
260+ "Weak references on RefBase %p (weakref_type %p):\n",
261+ mBase, this);
258262 text.append(buf);
259263 printRefsLocked(&text, mWeakRefs);
260264 }
261265
262266 {
263267 char name[100];
264- snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH "/%p.stack", this);
268+ snprintf(name, sizeof(name), DEBUG_REFS_CALLSTACK_PATH "/%p.stack",
269+ this);
265270 int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
266271 if (rc >= 0) {
267272 write(rc, text.string(), text.length());
@@ -354,8 +359,8 @@ private:
354359 char buf[128];
355360 while (refs) {
356361 char inc = refs->ref >= 0 ? '+' : '-';
357- sprintf(buf, "\t%c ID %p (ref %d):\n",
358- inc, refs->id, refs->ref);
362+ snprintf(buf, sizeof(buf), "\t%c ID %p (ref %d):\n",
363+ inc, refs->id, refs->ref);
359364 out->append(buf);
360365 #if DEBUG_REFS_CALLSTACK_ENABLED
361366 out->append(refs->stack.toString("\t\t"));
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -129,7 +129,7 @@ size_t strnlen32(const char32_t *s, size_t maxlen)
129129
130130 static inline int32_t utf32_at_internal(const char* cur, size_t *num_read)
131131 {
132- const char first_char = *cur;
132+ const unsigned char first_char = *cur;
133133 if ((first_char & 0x80) == 0) { // ASCII
134134 *num_read = 1;
135135 return *cur;
@@ -391,7 +391,7 @@ ssize_t utf8_length(const char *src)
391391 const char *cur = src;
392392 size_t ret = 0;
393393 while (*cur != '\0') {
394- const char first_char = *cur++;
394+ const unsigned char first_char = *cur++;
395395 if ((first_char & 0x80) == 0) { // ASCII
396396 ret += 1;
397397 continue;
@@ -482,7 +482,7 @@ size_t utf8_to_utf32_length(const char *src, size_t src_len)
482482 for (cur = src, end = src + src_len, num_to_skip = 1;
483483 cur < end;
484484 cur += num_to_skip, ret++) {
485- const char first_char = *cur;
485+ const unsigned char first_char = *cur;
486486 num_to_skip = 1;
487487 if ((first_char & 0x80) == 0) { // ASCII
488488 continue;
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -30,6 +30,11 @@ on early-init
3030 # Set the security context of /postinstall if present.
3131 restorecon /postinstall
3232
33+ mount debugfs /sys/kernel/debug /sys/kernel/debug mode=755
34+
35+ # for /lib/firmware
36+ symlink system/lib /lib
37+
3338 start ueventd
3439
3540 on init
@@ -148,6 +153,7 @@ on init
148153 mkdir /dev/cpuctl
149154 mount cgroup none /dev/cpuctl cpu
150155 chown system system /dev/cpuctl
156+ chmod 0660 /dev/cpuctl
151157 chown system system /dev/cpuctl/tasks
152158 chmod 0666 /dev/cpuctl/tasks
153159 write /dev/cpuctl/cpu.rt_period_us 1000000
@@ -662,7 +668,7 @@ service console /system/bin/sh
662668 class core
663669 console
664670 disabled
665- user shell
671+# user shell
666672 group shell log readproc
667673 seclabel u:r:shell:s0
668674
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -78,9 +78,6 @@ subsystem adf
7878 /dev/htc-acoustic 0660 system audio
7979 /dev/vdec 0660 system audio
8080 /dev/q6venc 0660 system audio
81-/dev/snd/dsp 0660 system audio
82-/dev/snd/dsp1 0660 system audio
83-/dev/snd/mixer 0660 system audio
8481 /dev/smd0 0640 radio radio
8582 /dev/qmi 0640 radio radio
8683 /dev/qmi0 0640 radio radio
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -2071,7 +2071,7 @@ static bool should_use_sdcardfs(void) {
20712071 }
20722072
20732073 // Fall back to device opinion about state
2074- if (property_get_bool(PROP_SDCARDFS_DEVICE, false)) {
2074+ if (property_get_bool(PROP_SDCARDFS_DEVICE, true)) {
20752075 ALOGW("Device explicitly enabled sdcardfs");
20762076 return supports_sdcardfs();
20772077 } else {
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -249,7 +249,7 @@ int newfs_msdos_main(int argc, char *argv[])
249249 char buf[MAXPATHLEN];
250250 struct stat sb;
251251 struct timeval tv;
252- struct bpb bpb;
252+ struct bpb bpb, tempbpb;
253253 struct tm *tm;
254254 struct bs *bs;
255255 struct bsbpb *bsbpb;
@@ -553,6 +553,7 @@ int newfs_msdos_main(int argc, char *argv[])
553553 set_spf = !bpb.bspf;
554554 set_spc = !bpb.spc;
555555 tempx = x;
556+ memset(&tempbpb, 0, sizeof(bpb));
556557 /*
557558 * Attempt to align if opt_A is set. This is done by increasing the number
558559 * of reserved blocks. This can cause other factors to change, which can in
@@ -600,10 +601,14 @@ int newfs_msdos_main(int argc, char *argv[])
600601 alignment = (bpb.res + bpb.bspf * bpb.nft) % bpb.spc;
601602 extra_res += bpb.spc - alignment;
602603 }
603- attempts++;
604+ if (++attempts == 1)
605+ memcpy(&tempbpb, &bpb, sizeof(bpb));
604606 } while(opt_A && alignment != 0 && attempts < 2);
605- if (alignment != 0)
607+ if (alignment != 0) {
606608 warnx("warning: Alignment failed.");
609+ /* return to data from first iteration */
610+ memcpy(&bpb, &tempbpb, sizeof(bpb));
611+ }
607612
608613 cls = (bpb.bsec - x1) / bpb.spc;
609614 x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (fat / BPN) - RESFTE;
@@ -695,7 +700,7 @@ int newfs_msdos_main(int argc, char *argv[])
695700 (u_int)tm->tm_min));
696701 mk4(bsx->volid, x);
697702 mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
698- sprintf(buf, "FAT%u", fat);
703+ snprintf(buf, sizeof(buf), "FAT%u", fat);
699704 setstr(bsx->type, buf, sizeof(bsx->type));
700705 if (!opt_B) {
701706 x1 += sizeof(struct bsx);
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -57,16 +57,16 @@ static int ps_line(int pid, int tid)
5757 int prio, nice, rtprio, sched, psr;
5858 struct passwd *pw;
5959
60- sprintf(statline, "/proc/%d", tid ? tid : pid);
60+ snprintf(statline, sizeof(statline), "/proc/%d", tid ? tid : pid);
6161 stat(statline, &stats);
6262
6363 if(tid) {
64- sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
64+ snprintf(statline, sizeof(statline), "/proc/%d/task/%d/stat", pid, tid);
6565 cmdline[0] = 0;
6666 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
6767 } else {
68- sprintf(statline, "/proc/%d/stat", pid);
69- sprintf(cmdline, "/proc/%d/cmdline", pid);
68+ snprintf(statline, sizeof(statline), "/proc/%d/stat", pid);
69+ snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
7070 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
7171 int fd = open(cmdline, O_RDONLY);
7272 if(fd == 0) {
@@ -149,7 +149,7 @@ static int ps_line(int pid, int tid)
149149
150150 pw = getpwuid(stats.st_uid);
151151 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
152- sprintf(user,"%d",(int)stats.st_uid);
152+ snprintf(user,sizeof(user),"%d",(int)stats.st_uid);
153153 } else {
154154 strcpy(user,pw->pw_name);
155155 }
@@ -208,7 +208,7 @@ static void print_exe_abi(int pid)
208208 int fd, r;
209209 char exeline[1024];
210210
211- sprintf(exeline, "/proc/%d/exe", pid);
211+ snprintf(exeline, sizeof(exeline), "/proc/%d/exe", pid);
212212 fd = open(exeline, O_RDONLY);
213213 if(fd == 0) {
214214 printf(" ");
@@ -243,7 +243,7 @@ void ps_threads(int pid)
243243 DIR *d;
244244 struct dirent *de;
245245
246- sprintf(tmp,"/proc/%d/task",pid);
246+ snprintf(tmp,sizeof(tmp),"/proc/%d/task",pid);
247247 d = opendir(tmp);
248248 if(d == 0) return;
249249
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -265,29 +265,29 @@ static void read_procs(void) {
265265
266266 proc->pid = proc->tid = pid;
267267
268- sprintf(filename, "/proc/%d/stat", pid);
268+ snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
269269 read_stat(filename, proc);
270270
271- sprintf(filename, "/proc/%d/cmdline", pid);
271+ snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
272272 read_cmdline(filename, proc);
273273
274- sprintf(filename, "/proc/%d/status", pid);
274+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
275275 read_status(filename, proc);
276276
277277 read_policy(pid, proc);
278278
279279 proc->num_threads = 0;
280280 } else {
281- sprintf(filename, "/proc/%d/cmdline", pid);
281+ snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
282282 read_cmdline(filename, &cur_proc);
283283
284- sprintf(filename, "/proc/%d/status", pid);
284+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
285285 read_status(filename, &cur_proc);
286286
287287 proc = NULL;
288288 }
289289
290- sprintf(filename, "/proc/%d/task", pid);
290+ snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
291291 task_dir = opendir(filename);
292292 if (!task_dir) continue;
293293
@@ -302,7 +302,7 @@ static void read_procs(void) {
302302
303303 proc->pid = pid; proc->tid = tid;
304304
305- sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
305+ snprintf(filename, sizeof(filename), "/proc/%d/task/%d/stat", pid, tid);
306306 read_stat(filename, proc);
307307
308308 read_policy(tid, proc);
@@ -491,7 +491,7 @@ static void print_procs(void) {
491491 if (user && user->pw_name) {
492492 user_str = user->pw_name;
493493 } else {
494- snprintf(user_buf, 20, "%d", proc->uid);
494+ snprintf(user_buf, sizeof(user_buf), "%d", proc->uid);
495495 user_str = user_buf;
496496 }
497497 if (!threads) {
Show on old repository browser