Merge "Add caching of build id in MapInfo object."
diff --git a/adb/client/adb_client.cpp b/adb/client/adb_client.cpp
index eda4b77..9a25d10 100644
--- a/adb/client/adb_client.cpp
+++ b/adb/client/adb_client.cpp
@@ -144,53 +144,51 @@
}
std::string reason;
- int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
- if (fd < 0) {
+ unique_fd fd;
+ if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
*error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
__adb_server_socket_spec, reason.c_str());
return -2;
}
- if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd, error)) {
+ if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd.get(), error)) {
return -1;
}
- if (!SendProtocolString(fd, service)) {
+ if (!SendProtocolString(fd.get(), service)) {
*error = perror_str("write failure during connection");
- adb_close(fd);
return -1;
}
- if (!adb_status(fd, error)) {
- adb_close(fd);
+ if (!adb_status(fd.get(), error)) {
return -1;
}
- D("_adb_connect: return fd %d", fd);
- return fd;
+ D("_adb_connect: return fd %d", fd.get());
+ return fd.release();
}
bool adb_kill_server() {
D("adb_kill_server");
std::string reason;
- int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
- if (fd < 0) {
+ unique_fd fd;
+ if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
reason.c_str());
return true;
}
- if (!SendProtocolString(fd, "host:kill")) {
+ if (!SendProtocolString(fd.get(), "host:kill")) {
fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
return false;
}
// The server might send OKAY, so consume that.
char buf[4];
- ReadFdExactly(fd, buf, 4);
+ ReadFdExactly(fd.get(), buf, 4);
// Now that no more data is expected, wait for socket orderly shutdown or error, indicating
// server death.
- ReadOrderlyShutdown(fd);
+ ReadOrderlyShutdown(fd.get());
return true;
}
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 9bc42e1..e963e3d 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -762,6 +762,17 @@
}
static int adb_abb(int argc, const char** argv) {
+ FeatureSet features;
+ std::string error_message;
+ if (!adb_get_feature_set(&features, &error_message)) {
+ fprintf(stderr, "error: %s\n", error_message.c_str());
+ return 1;
+ }
+
+ if (!CanUseFeature(features, kFeatureAbb)) {
+ error_exit("abb is not supported by the device");
+ }
+
// Defaults.
constexpr char escape_char = '~'; // -e
constexpr bool use_shell_protocol = true;
diff --git a/adb/fastdeploy/Android.bp b/adb/fastdeploy/Android.bp
index 400b12f..1ba0de0 100644
--- a/adb/fastdeploy/Android.bp
+++ b/adb/fastdeploy/Android.bp
@@ -22,6 +22,9 @@
wrapper: "deployagent/deployagent.sh",
proto: {
type: "lite",
+ },
+ dex_preopt: {
+ enabled: false,
}
}
diff --git a/adb/services.cpp b/adb/services.cpp
index 8636657..73fed09 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -72,24 +72,23 @@
}
int service_to_fd(std::string_view name, atransport* transport) {
- int ret = -1;
+ unique_fd ret;
if (is_socket_spec(name)) {
std::string error;
- ret = socket_spec_connect(name, &error);
- if (ret < 0) {
+ if (!socket_spec_connect(&ret, name, nullptr, nullptr, &error)) {
LOG(ERROR) << "failed to connect to socket '" << name << "': " << error;
}
} else {
#if !ADB_HOST
- ret = daemon_service_to_fd(name, transport).release();
+ ret = daemon_service_to_fd(name, transport);
#endif
}
if (ret >= 0) {
close_on_exec(ret);
}
- return ret;
+ return ret.release();
}
#if ADB_HOST
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index 4cddc84..cc67b6b 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -67,7 +67,7 @@
});
bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
- std::string* error) {
+ std::string* serial, std::string* error) {
if (!spec.starts_with("tcp:")) {
*error = "specification is not tcp: ";
*error += spec;
@@ -92,7 +92,7 @@
// FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
// on an address that isn't 'localhost' is unsupported.
- if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, nullptr, error)) {
+ if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, serial, error)) {
return false;
}
@@ -139,63 +139,68 @@
std::string error;
std::string hostname;
- if (!parse_tcp_socket_spec(spec, &hostname, nullptr, &error)) {
+ if (!parse_tcp_socket_spec(spec, &hostname, nullptr, nullptr, &error)) {
return false;
}
return tcp_host_is_local(hostname);
}
-int socket_spec_connect(std::string_view spec, std::string* error) {
- if (spec.starts_with("tcp:")) {
+bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
+ std::string* error) {
+ if (address.starts_with("tcp:")) {
std::string hostname;
- int port;
- if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
- return -1;
+ int port_value = port ? *port : 0;
+ if (!parse_tcp_socket_spec(address, &hostname, &port_value, serial, error)) {
+ return false;
}
- int result;
if (tcp_host_is_local(hostname)) {
- result = network_loopback_client(port, SOCK_STREAM, error);
+ fd->reset(network_loopback_client(port_value, SOCK_STREAM, error));
} else {
#if ADB_HOST
- result = network_connect(hostname, port, SOCK_STREAM, 0, error);
+ fd->reset(network_connect(hostname, port_value, SOCK_STREAM, 0, error));
#else
// Disallow arbitrary connections in adbd.
*error = "adbd does not support arbitrary tcp connections";
- return -1;
+ return false;
#endif
}
- if (result >= 0) {
- disable_tcp_nagle(result);
+ if (fd->get() > 0) {
+ disable_tcp_nagle(fd->get());
+ if (port) {
+ *port = port_value;
+ }
+ return true;
}
- return result;
+ return false;
}
for (const auto& it : kLocalSocketTypes) {
std::string prefix = it.first + ":";
- if (spec.starts_with(prefix)) {
+ if (address.starts_with(prefix)) {
if (!it.second.available) {
*error = StringPrintf("socket type %s is unavailable on this platform",
it.first.c_str());
- return -1;
+ return false;
}
- return network_local_client(&spec[prefix.length()], it.second.socket_namespace,
- SOCK_STREAM, error);
+ fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace,
+ SOCK_STREAM, error));
+ return true;
}
}
*error = "unknown socket specification: ";
- *error += spec;
- return -1;
+ *error += address;
+ return false;
}
int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) {
if (spec.starts_with("tcp:")) {
std::string hostname;
int port;
- if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
+ if (!parse_tcp_socket_spec(spec, &hostname, &port, nullptr, error)) {
return -1;
}
diff --git a/adb/socket_spec.h b/adb/socket_spec.h
index 5b06973..687d751 100644
--- a/adb/socket_spec.h
+++ b/adb/socket_spec.h
@@ -17,14 +17,18 @@
#pragma once
#include <string>
+#include <tuple>
+
+#include "adb_unique_fd.h"
// Returns true if the argument starts with a plausible socket prefix.
bool is_socket_spec(std::string_view spec);
bool is_local_socket_spec(std::string_view spec);
-int socket_spec_connect(std::string_view spec, std::string* error);
+bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
+ std::string* error);
int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr);
// Exposed for testing.
bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
- std::string* error);
+ std::string* serial, std::string* error);
diff --git a/adb/socket_spec_test.cpp b/adb/socket_spec_test.cpp
index 40ce21c..f5ec0f1 100644
--- a/adb/socket_spec_test.cpp
+++ b/adb/socket_spec_test.cpp
@@ -21,34 +21,37 @@
#include <gtest/gtest.h>
TEST(socket_spec, parse_tcp_socket_spec) {
- std::string hostname, error;
+ std::string hostname, error, serial;
int port;
- EXPECT_TRUE(parse_tcp_socket_spec("tcp:5037", &hostname, &port, &error));
+ EXPECT_TRUE(parse_tcp_socket_spec("tcp:5037", &hostname, &port, &serial, &error));
EXPECT_EQ("", hostname);
EXPECT_EQ(5037, port);
+ EXPECT_EQ("", serial);
// Bad ports:
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:-1", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:65536", &hostname, &port, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:-1", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:65536", &hostname, &port, &serial, &error));
- EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost:1234", &hostname, &port, &error));
+ EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost:1234", &hostname, &port, &serial, &error));
EXPECT_EQ("localhost", hostname);
EXPECT_EQ(1234, port);
+ EXPECT_EQ("localhost:1234", serial);
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:-1", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:65536", &hostname, &port, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:-1", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:65536", &hostname, &port, &serial, &error));
// IPv6:
- EXPECT_TRUE(parse_tcp_socket_spec("tcp:[::1]:1234", &hostname, &port, &error));
+ EXPECT_TRUE(parse_tcp_socket_spec("tcp:[::1]:1234", &hostname, &port, &serial, &error));
EXPECT_EQ("::1", hostname);
EXPECT_EQ(1234, port);
+ EXPECT_EQ("[::1]:1234", serial);
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:-1", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1", &hostname, &port, &error));
- EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1:1234", &hostname, &port, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:-1", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1", &hostname, &port, &serial, &error));
+ EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1:1234", &hostname, &port, &serial, &error));
}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index f59a135..ae53597 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -68,6 +68,7 @@
const char* const kFeaturePushSync = "push_sync";
const char* const kFeatureApex = "apex";
const char* const kFeatureFixedPushMkdir = "fixed_push_mkdir";
+const char* const kFeatureAbb = "abb";
namespace {
@@ -1013,7 +1014,8 @@
const FeatureSet& supported_features() {
// Local static allocation to avoid global non-POD variables.
static const FeatureSet* features = new FeatureSet{
- kFeatureShell2, kFeatureCmd, kFeatureStat2, kFeatureFixedPushMkdir, kFeatureApex
+ kFeatureShell2, kFeatureCmd, kFeatureStat2,
+ kFeatureFixedPushMkdir, kFeatureApex, kFeatureAbb,
// Increment ADB_SERVER_VERSION when adding a feature that adbd needs
// to know about. Otherwise, the client can be stuck running an old
// version of the server even after upgrading their copy of adb.
diff --git a/adb/transport.h b/adb/transport.h
index 790004f..6f53e6ec 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -64,6 +64,8 @@
extern const char* const kFeatureApex;
// adbd has b/110953234 fixed.
extern const char* const kFeatureFixedPushMkdir;
+// adbd supports android binder bridge (abb).
+extern const char* const kFeatureAbb;
TransportId NextTransportId();
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index dc87ac7..b384085 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -45,6 +45,7 @@
#include "adb_io.h"
#include "adb_unique_fd.h"
#include "adb_utils.h"
+#include "socket_spec.h"
#include "sysdeps/chrono.h"
#if ADB_HOST
@@ -70,32 +71,17 @@
std::tuple<unique_fd, int, std::string> tcp_connect(const std::string& address,
std::string* response) {
- std::string serial;
- std::string host;
+ unique_fd fd;
int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
- if (!android::base::ParseNetAddress(address, &host, &port, &serial, response)) {
- D("failed to parse address: '%s'", address.c_str());
- return std::make_tuple(unique_fd(), port, serial);
- }
-
- std::string error;
- unique_fd fd(network_connect(host.c_str(), port, SOCK_STREAM, 10, &error));
- if (fd == -1) {
- *response = android::base::StringPrintf("unable to connect to %s: %s",
- serial.c_str(), error.c_str());
+ std::string serial;
+ if (socket_spec_connect(&fd, "tcp:" + address, &port, &serial, response)) {
+ close_on_exec(fd);
+ if (!set_tcp_keepalive(fd, 1)) {
+ D("warning: failed to configure TCP keepalives (%s)", strerror(errno));
+ }
return std::make_tuple(std::move(fd), port, serial);
}
-
- D("client: connected %s remote on fd %d", serial.c_str(), fd.get());
- close_on_exec(fd);
- disable_tcp_nagle(fd);
-
- // Send a TCP keepalive ping to the device every second so we can detect disconnects.
- if (!set_tcp_keepalive(fd, 1)) {
- D("warning: failed to configure TCP keepalives (%s)", strerror(errno));
- }
-
- return std::make_tuple(std::move(fd), port, serial);
+ return std::make_tuple(unique_fd(), 0, "");
}
void connect_device(const std::string& address, std::string* response) {
@@ -251,8 +237,9 @@
adb_thread_setname("server socket");
D("transport: server_socket_thread() starting");
while (serverfd == -1) {
+ std::string spec = android::base::StringPrintf("tcp:%d", port);
std::string error;
- serverfd.reset(network_inaddr_any_server(port, SOCK_STREAM, &error));
+ serverfd.reset(socket_spec_listen(spec, &error));
if (serverfd < 0) {
D("server: cannot bind socket yet: %s", error.c_str());
std::this_thread::sleep_for(1s);
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index ead2105..716fe95 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -132,6 +132,7 @@
"libext2_uuid",
"libext4_utils",
"libfs_mgr",
+ "libgsi",
"libhidlbase",
"libhidltransport",
"libhwbinder",
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 81f0560..8a72627 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -33,6 +33,7 @@
#define FB_CMD_RESIZE_PARTITION "resize-logical-partition"
#define FB_CMD_UPDATE_SUPER "update-super"
#define FB_CMD_OEM "oem"
+#define FB_CMD_GSI "gsi"
#define RESPONSE_OKAY "OKAY"
#define RESPONSE_FAIL "FAIL"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index e91598d..a2336bf 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -28,6 +28,7 @@
#include <cutils/android_reboot.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>
+#include <libgsi/libgsi.h>
#include <liblp/builder.h>
#include <liblp/liblp.h>
#include <uuid/uuid.h>
@@ -460,3 +461,22 @@
bool wipe = (args.size() >= 3 && args[2] == "wipe");
return UpdateSuper(device, args[1], wipe);
}
+
+bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (!android::gsi::IsGsiInstalled()) {
+ return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
+ }
+ if (args.size() != 2) {
+ return device->WriteFail("Invalid arguments");
+ }
+ if (args[1] == "wipe") {
+ if (!android::gsi::UninstallGsi()) {
+ return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
+ }
+ } else if (args[1] == "disable") {
+ if (!android::gsi::DisableGsi()) {
+ return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
+ }
+ }
+ return device->WriteStatus(FastbootResult::OKAY, "Success");
+}
diff --git a/fastboot/device/commands.h b/fastboot/device/commands.h
index bb1f988..afd6d08 100644
--- a/fastboot/device/commands.h
+++ b/fastboot/device/commands.h
@@ -48,3 +48,4 @@
bool ResizePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool OemCmdHandler(FastbootDevice* device, const std::vector<std::string>& args);
+bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args);
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 7be721a..56fafab 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -53,6 +53,7 @@
{FB_CMD_RESIZE_PARTITION, ResizePartitionHandler},
{FB_CMD_UPDATE_SUPER, UpdateSuperHandler},
{FB_CMD_OEM, OemCmdHandler},
+ {FB_CMD_GSI, GsiHandler},
}),
transport_(std::make_unique<ClientUsbTransport>()),
boot_control_hal_(IBootControl::getService()),
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 0b8d9b2..d753f0f 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -387,6 +387,7 @@
" Format a flash partition.\n"
" set_active SLOT Set the active slot.\n"
" oem [COMMAND...] Execute OEM-specific command.\n"
+ " gsi wipe|disable Wipe or disable a GSI installation (fastbootd only).\n"
"\n"
"boot image:\n"
" boot KERNEL [RAMDISK [SECOND]]\n"
@@ -1926,6 +1927,16 @@
std::string partition = next_arg(&args);
std::string size = next_arg(&args);
fb->ResizePartition(partition, size);
+ } else if (command == "gsi") {
+ if (args.empty()) {
+ syntax_error("missing 'wipe' or 'disable' argument");
+ } else if (args.size() == 1 && args[0] == "wipe") {
+ fb->RawCommand("gsi:wipe", "wiping GSI");
+ } else if (args.size() == 1 && args[0] == "disable") {
+ fb->RawCommand("gsi:disable", "disabling GSI");
+ } else {
+ syntax_error("expected 'wipe' or 'disable'");
+ }
} else {
syntax_error("unknown command %s", command.c_str());
}
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index d9f2837..974e13e 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -59,6 +59,7 @@
"libfs_avb",
"libfstab",
"libdm",
+ "libgsi",
],
export_static_lib_headers: [
"libfs_avb",
@@ -105,5 +106,8 @@
},
},
export_include_dirs: ["include_fstab"],
- header_libs: ["libbase_headers"],
+ header_libs: [
+ "libbase_headers",
+ "libgsi_headers",
+ ],
}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 19445c8..70a1045 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -79,6 +79,7 @@
#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
#define ZRAM_CONF_MCS "/sys/block/zram0/max_comp_streams"
+#define ZRAM_BACK_DEV "/sys/block/zram0/backing_dev"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -1373,6 +1374,70 @@
return 0;
}
+static bool InstallZramDevice(const std::string& device) {
+ if (!android::base::WriteStringToFile(device, ZRAM_BACK_DEV)) {
+ PERROR << "Cannot write " << device << " in: " << ZRAM_BACK_DEV;
+ return false;
+ }
+ LINFO << "Success to set " << device << " to " << ZRAM_BACK_DEV;
+ return true;
+}
+
+static bool PrepareZramDevice(const std::string& loop, off64_t size, const std::string& bdev) {
+ if (loop.empty() && bdev.empty()) return true;
+
+ if (bdev.length()) {
+ return InstallZramDevice(bdev);
+ }
+
+ // Get free loopback
+ unique_fd loop_fd(TEMP_FAILURE_RETRY(open("/dev/loop-control", O_RDWR | O_CLOEXEC)));
+ if (loop_fd.get() == -1) {
+ PERROR << "Cannot open loop-control";
+ return false;
+ }
+
+ int num = ioctl(loop_fd.get(), LOOP_CTL_GET_FREE);
+ if (num == -1) {
+ PERROR << "Cannot get free loop slot";
+ return false;
+ }
+
+ // Prepare target path
+ unique_fd target_fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0664)));
+ if (target_fd.get() == -1) {
+ PERROR << "Cannot open target path: " << loop;
+ return false;
+ }
+ if (fallocate(target_fd.get(), 0, 0, size) < 0) {
+ PERROR << "Cannot truncate target path: " << loop;
+ return false;
+ }
+
+ // Connect loopback (device_fd) to target path (target_fd)
+ std::string device = android::base::StringPrintf("/dev/block/loop%d", num);
+ unique_fd device_fd(TEMP_FAILURE_RETRY(open(device.c_str(), O_RDWR | O_CLOEXEC)));
+ if (device_fd.get() == -1) {
+ PERROR << "Cannot open /dev/block/loop" << num;
+ return false;
+ }
+
+ if (ioctl(device_fd.get(), LOOP_SET_FD, target_fd.get())) {
+ PERROR << "Cannot set loopback to target path";
+ return false;
+ }
+
+ // set block size & direct IO
+ if (ioctl(device_fd.get(), LOOP_SET_BLOCK_SIZE, 4096)) {
+ PWARNING << "Cannot set 4KB blocksize to /dev/block/loop" << num;
+ }
+ if (ioctl(device_fd.get(), LOOP_SET_DIRECT_IO, 1)) {
+ PWARNING << "Cannot set direct_io to /dev/block/loop" << num;
+ }
+
+ return InstallZramDevice(device);
+}
+
bool fs_mgr_swapon_all(const Fstab& fstab) {
bool ret = true;
for (const auto& entry : fstab) {
@@ -1381,6 +1446,10 @@
continue;
}
+ if (!PrepareZramDevice(entry.zram_loopback_path, entry.zram_loopback_size, entry.zram_backing_dev_path)) {
+ LERROR << "Skipping losetup for '" << entry.blk_device << "'";
+ }
+
if (entry.zram_size > 0) {
// A zram_size was specified, so we need to configure the
// device. There is no point in having multiple zram devices
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 53b47be..c9f34a7 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -28,8 +28,10 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <libgsi/libgsi.h>
#include "fs_mgr_priv.h"
@@ -43,6 +45,9 @@
std::string key_dir;
std::string verity_loc;
std::string sysfs_path;
+ std::string zram_loopback_path;
+ uint64_t zram_loopback_size = 512 * 1024 * 1024; // 512MB by default
+ std::string zram_backing_dev_path;
off64_t part_length = 0;
std::string label;
int partnum = -1;
@@ -117,6 +122,9 @@
{"checkpoint=block", MF_CHECKPOINT_BLK},
{"checkpoint=fs", MF_CHECKPOINT_FS},
{"slotselect_other", MF_SLOTSELECT_OTHER},
+ {"zram_loopback_path=", MF_ZRAM_LOOPBACK_PATH},
+ {"zram_loopback_size=", MF_ZRAM_LOOPBACK_SIZE},
+ {"zram_backing_dev_path=", MF_ZRAM_BACKING_DEV_PATH},
{0, 0},
};
@@ -344,6 +352,16 @@
} else if (flag == MF_SYSFS) {
/* The path to trigger device gc by idle-maint of vold. */
flag_vals->sysfs_path = arg;
+ } else if (flag == MF_ZRAM_LOOPBACK_PATH) {
+ /* The path to use loopback for zram. */
+ flag_vals->zram_loopback_path = arg;
+ } else if (flag == MF_ZRAM_LOOPBACK_SIZE) {
+ if (!android::base::ParseByteCount(arg, &flag_vals->zram_loopback_size)) {
+ LERROR << "Warning: zram_loopback_size = flag malformed";
+ }
+ } else if (flag == MF_ZRAM_BACKING_DEV_PATH) {
+ /* The path to use loopback for zram. */
+ flag_vals->zram_backing_dev_path = arg;
}
break;
}
@@ -569,6 +587,9 @@
entry.logical_blk_size = flag_vals.logical_blk_size;
entry.sysfs_path = std::move(flag_vals.sysfs_path);
entry.vbmeta_partition = std::move(flag_vals.vbmeta_partition);
+ entry.zram_loopback_path = std::move(flag_vals.zram_loopback_path);
+ entry.zram_loopback_size = std::move(flag_vals.zram_loopback_size);
+ entry.zram_backing_dev_path = std::move(flag_vals.zram_backing_dev_path);
if (entry.fs_mgr_flags.logical) {
entry.logical_partition_name = entry.blk_device;
}
@@ -638,6 +659,35 @@
return boot_devices;
}
+static void EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
+ auto iter = std::remove_if(fstab->begin(), fstab->end(),
+ [&](const auto& entry) { return entry.mount_point == mount_point; });
+ fstab->erase(iter, fstab->end());
+}
+
+static void TransformFstabForGsi(Fstab* fstab) {
+ EraseFstabEntry(fstab, "/system");
+ EraseFstabEntry(fstab, "/data");
+
+ fstab->emplace_back(BuildGsiSystemFstabEntry());
+
+ constexpr uint32_t kFlags = MS_NOATIME | MS_NOSUID | MS_NODEV;
+
+ FstabEntry userdata = {
+ .blk_device = "userdata_gsi",
+ .mount_point = "/data",
+ .fs_type = "ext4",
+ .flags = kFlags,
+ .reserved_size = 128 * 1024 * 1024,
+ };
+ userdata.fs_mgr_flags.wait = true;
+ userdata.fs_mgr_flags.check = true;
+ userdata.fs_mgr_flags.logical = true;
+ userdata.fs_mgr_flags.quota = true;
+ userdata.fs_mgr_flags.late_mount = true;
+ fstab->emplace_back(userdata);
+}
+
bool ReadFstabFromFile(const std::string& path, Fstab* fstab) {
auto fstab_file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
if (!fstab_file) {
@@ -645,10 +695,15 @@
return false;
}
- if (!fs_mgr_read_fstab_file(fstab_file.get(), path == "/proc/mounts", fstab)) {
+ bool is_proc_mounts = path == "/proc/mounts";
+
+ if (!fs_mgr_read_fstab_file(fstab_file.get(), is_proc_mounts, fstab)) {
LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'";
return false;
}
+ if (!is_proc_mounts && !access(android::gsi::kGsiBootedIndicatorFile, F_OK)) {
+ TransformFstabForGsi(fstab);
+ }
return true;
}
@@ -776,6 +831,8 @@
free(fstab->recs[i].key_dir);
free(fstab->recs[i].label);
free(fstab->recs[i].sysfs_path);
+ free(fstab->recs[i].zram_loopback_path);
+ free(fstab->recs[i].zram_backing_dev_path);
}
/* Free the fstab_recs array created by calloc(3) */
@@ -873,6 +930,9 @@
entry.erase_blk_size = fstab_rec->erase_blk_size;
entry.logical_blk_size = fstab_rec->logical_blk_size;
entry.sysfs_path = fstab_rec->sysfs_path;
+ entry.zram_loopback_path = fstab_rec->zram_loopback_path;
+ entry.zram_loopback_size = fstab_rec->zram_loopback_size;
+ entry.zram_backing_dev_path = fstab_rec->zram_backing_dev_path;
return entry;
}
@@ -916,6 +976,9 @@
legacy_fstab->recs[i].erase_blk_size = fstab[i].erase_blk_size;
legacy_fstab->recs[i].logical_blk_size = fstab[i].logical_blk_size;
legacy_fstab->recs[i].sysfs_path = strdup(fstab[i].sysfs_path.c_str());
+ legacy_fstab->recs[i].zram_loopback_path = strdup(fstab[i].zram_loopback_path.c_str());
+ legacy_fstab->recs[i].zram_loopback_size = fstab[i].zram_loopback_size;
+ legacy_fstab->recs[i].zram_backing_dev_path = strdup(fstab[i].zram_backing_dev_path.c_str());
}
return legacy_fstab;
}
@@ -1023,3 +1086,17 @@
int fs_mgr_is_checkpoint_blk(const struct fstab_rec* fstab) {
return fstab->fs_mgr_flags & MF_CHECKPOINT_BLK;
}
+
+FstabEntry BuildGsiSystemFstabEntry() {
+ FstabEntry system = {
+ .blk_device = "system_gsi",
+ .mount_point = "/system",
+ .fs_type = "ext4",
+ .flags = MS_RDONLY,
+ .fs_options = "barrier=1",
+ };
+ system.fs_mgr_flags.wait = true;
+ system.fs_mgr_flags.logical = true;
+ system.fs_mgr_flags.first_stage_mount = true;
+ return system;
+}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 6364ca9..0f89467 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -48,6 +48,7 @@
#include <fs_mgr_overlayfs.h>
#include <fstab/fstab.h>
#include <libdm/dm.h>
+#include <libgsi/libgsi.h>
#include <liblp/builder.h>
#include <liblp/liblp.h>
@@ -802,8 +803,9 @@
bool fs_mgr_overlayfs_invalid() {
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true;
- // in recovery or fastbootd mode, not allowed!
+ // in recovery, fastbootd, or gsi mode, not allowed!
if (fs_mgr_access("/system/bin/recovery")) return true;
+ if (android::gsi::IsGsiRunning()) return true;
return false;
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 7842ca2..39ceff7 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -122,6 +122,12 @@
0x80000000
#define MF_SLOTSELECT_OTHER \
0x100000000
+#define MF_ZRAM_LOOPBACK_PATH \
+ 0x200000000
+#define MF_ZRAM_LOOPBACK_SIZE \
+ 0x400000000
+#define MF_ZRAM_BACKING_DEV_PATH \
+ 0x800000000
// clang-format on
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 0997254..5d8496d 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -59,6 +59,9 @@
off64_t erase_blk_size;
off64_t logical_blk_size;
char* sysfs_path;
+ char* zram_loopback_path;
+ uint64_t zram_loopback_size;
+ char* zram_backing_dev_path;
};
struct fstab* fs_mgr_read_fstab_default();
@@ -119,6 +122,9 @@
off64_t logical_blk_size = 0;
std::string sysfs_path;
std::string vbmeta_partition;
+ std::string zram_loopback_path;
+ uint64_t zram_loopback_size;
+ std::string zram_backing_dev_path;
// TODO: Remove this union once fstab_rec is deprecated. It only serves as a
// convenient way to convert between fstab_rec::fs_mgr_flags and these bools.
@@ -187,3 +193,6 @@
FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec);
Fstab LegacyFstabToFstab(const struct fstab* legacy_fstab);
fstab* FstabToLegacyFstab(const Fstab& fstab);
+
+// Helper method to build a GSI fstab entry for mounting /system.
+FstabEntry BuildGsiSystemFstabEntry();
diff --git a/fs_mgr/libfiemap_writer/fiemap_writer.cpp b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
index 4a0d4b5..71b39a9 100644
--- a/fs_mgr/libfiemap_writer/fiemap_writer.cpp
+++ b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
@@ -304,7 +304,6 @@
return true;
}
-#if 0
static bool IsFilePinned(int file_fd, const std::string& file_path, uint32_t fs_type) {
if (fs_type == EXT4_SUPER_MAGIC) {
// No pinning necessary for ext4. The blocks, once allocated, are expected
@@ -345,7 +344,6 @@
}
return moved_blocks_nr == 0;
}
-#endif
static void LogExtent(uint32_t num, const struct fiemap_extent& ext) {
LOG(INFO) << "Extent #" << num;
@@ -477,13 +475,15 @@
if (create) {
if (!AllocateFile(file_fd, abs_path, blocksz, file_size)) {
+ LOG(ERROR) << "Failed to allocate file: " << abs_path << " of size: " << file_size
+ << " bytes";
cleanup(abs_path, create);
return nullptr;
}
}
// f2fs may move the file blocks around.
- if (!PinFile(file_fd, file_path, fs_type)) {
+ if (!PinFile(file_fd, abs_path, fs_type)) {
cleanup(abs_path, create);
LOG(ERROR) << "Failed to pin the file in storage";
return nullptr;
@@ -538,13 +538,11 @@
return false;
}
-#if 0
- // TODO(b/122138114): check why this fails.
if (!IsFilePinned(file_fd_, file_path_, fs_type_)) {
LOG(ERROR) << "Failed write: file " << file_path_ << " is not pinned";
return false;
}
-#endif
+
// find extents that must be written to and then write one at a time.
uint32_t num_extent = 1;
uint32_t buffer_offset = 0;
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 825109f..0765f04 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -164,12 +164,26 @@
Returns: true if device in root state" ]
adb_root() {
+ [ `adb_sh echo '${USER}'` != root ] || return 0
adb root >/dev/null </dev/null 2>/dev/null
sleep 2
adb_wait 2m &&
[ `adb_sh echo '${USER}'` = root ]
}
+[ "USAGE: adb_unroot
+
+NB: This can be flakey on devices due to USB state
+
+Returns: true if device in un root state" ]
+adb_unroot() {
+ [ `adb_sh echo '${USER}'` = root ] || return 0
+ adb unroot >/dev/null </dev/null 2>/dev/null
+ sleep 2
+ adb_wait 2m &&
+ [ `adb_sh echo '${USER}'` != root ]
+}
+
[ "USAGE: fastboot_getvar var expected
Returns: true if var output matches expected" ]
@@ -194,6 +208,15 @@
echo ${O} >&2
}
+[ "USAGE: cleanup
+
+Do nothing: should be redefined when necessary
+
+Returns: cleans up any latent resources, reverses configurations" ]
+cleanup () {
+ :
+}
+
[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
If -d, or -t <epoch> argument is supplied, dump logcat.
@@ -212,6 +235,7 @@
shift 2
fi
echo "${RED}[ FAILED ]${NORMAL} ${@}" >&2
+ cleanup
exit 1
}
@@ -558,6 +582,7 @@
echo "${GREEN}[ OK ]${NORMAL} /system content remains after reboot" >&2
# Only root can read vendor if sepolicy permissions are as expected
if ${enforcing}; then
+ adb_unroot
B="`adb_cat /vendor/hello`" &&
die "re-read /vendor/hello after reboot w/o root"
check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
diff --git a/init/Android.bp b/init/Android.bp
index c920dc2..9f5d17d 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -19,7 +19,6 @@
cpp_std: "experimental",
sanitize: {
misc_undefined: ["signed-integer-overflow"],
- address: false, // TODO(b/120561310): Fix ASAN to work without /proc mounted and re-enable.
},
cflags: [
"-DLOG_UEVENTS=0",
@@ -77,6 +76,7 @@
"libext4_utils",
"libfs_mgr",
"libfscrypt",
+ "libgsi",
"libhidl-gen-utils",
"libkeyutils",
"liblog",
diff --git a/init/Android.mk b/init/Android.mk
index bdd0301..69c63e1 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -91,6 +91,7 @@
libz \
libselinux \
libcap \
+ libgsi \
LOCAL_SANITIZE := signed-integer-overflow
# First stage init is weird: it may start without stdout/stderr, and no /proc.
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 43a520f..169edbe 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -54,6 +54,7 @@
#include <fs_mgr.h>
#include <fscrypt/fscrypt.h>
#include <fscrypt/fscrypt_init_extensions.h>
+#include <libgsi/libgsi.h>
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
@@ -520,6 +521,9 @@
return Success();
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
+ if (android::gsi::IsGsiRunning()) {
+ return Error() << "cannot wipe within GSI";
+ }
PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
return reboot_into_recovery(options);
@@ -1022,7 +1026,8 @@
}
service->AddReapCallback([reboot_reason](const siginfo_t& siginfo) {
if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) {
- if (fscrypt_is_native()) {
+ // TODO (b/122850122): support this in gsi
+ if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) {
LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason;
if (auto result = reboot_into_recovery(
{"--prompt_and_wipe_data", "--reason="s + reboot_reason});
@@ -1093,86 +1098,6 @@
}
}
-static Result<Success> bind_mount_file(const char* source, const char* mount_point,
- bool remount_private) {
- if (remount_private && mount(nullptr, mount_point, nullptr, MS_PRIVATE, nullptr) == -1) {
- return ErrnoError() << "Could not change " << mount_point << " to a private mount point";
- }
- if (mount(source, mount_point, nullptr, MS_BIND, nullptr) == -1) {
- return ErrnoError() << "Could not bind-mount " << source << " to " << mount_point;
- }
- return Success();
-}
-
-static Result<Success> bind_mount_bionic(const char* linker_source, const char* lib_dir_source,
- const char* linker_mount_point, const char* lib_mount_dir,
- bool remount_private) {
- if (access(linker_source, F_OK) != 0) {
- return Success();
- }
- if (auto result = bind_mount_file(linker_source, linker_mount_point, remount_private);
- !result) {
- return result;
- }
- for (auto libname : kBionicLibFileNames) {
- std::string mount_point = lib_mount_dir + libname;
- std::string source = lib_dir_source + libname;
- if (auto result = bind_mount_file(source.c_str(), mount_point.c_str(), remount_private);
- !result) {
- return result;
- }
- }
- return Success();
-}
-
-// The bootstrap bionic libs and the bootstrap linker are bind-mounted to
-// the mount points for pre-apexd processes.
-static Result<Success> do_prepare_bootstrap_bionic(const BuiltinArguments& args) {
- static bool prepare_bootstrap_bionic_done = false;
- if (prepare_bootstrap_bionic_done) {
- return Error() << "prepare_bootstrap_bionic was already executed. Cannot be executed again";
- }
- if (auto result = bind_mount_bionic(kBootstrapLinkerPath, kBootstrapBionicLibsDir,
- kLinkerMountPoint, kBionicLibsMountPointDir, false);
- !result) {
- return result;
- }
- if (auto result = bind_mount_bionic(kBootstrapLinkerPath64, kBootstrapBionicLibsDir64,
- kLinkerMountPoint64, kBionicLibsMountPointDir64, false);
- !result) {
- return result;
- }
-
- LOG(INFO) << "prepare_bootstrap_bionic done";
- prepare_bootstrap_bionic_done = true;
- return Success();
-}
-
-// The bionic libs and the dynamic linker from the runtime APEX are bind-mounted
-// to the mount points. As a result, the previous mounts done by
-// prepare_bootstrap_bionic become hidden.
-static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) {
- static bool setup_runtime_bionic_done = false;
- if (setup_runtime_bionic_done) {
- return Error() << "setup_runtime_bionic was already executed. Cannot be executed again";
- }
- if (auto result = bind_mount_bionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir,
- kLinkerMountPoint, kBionicLibsMountPointDir, true);
- !result) {
- return result;
- }
- if (auto result = bind_mount_bionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64,
- kLinkerMountPoint64, kBionicLibsMountPointDir64, true);
- !result) {
- return result;
- }
-
- ServiceList::GetInstance().MarkRuntimeAvailable();
- LOG(INFO) << "setup_runtime_bionic done";
- setup_runtime_bionic_done = true;
- return Success();
-}
-
// Builtin-function-map start
const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@@ -1211,7 +1136,6 @@
{"mount_all", {1, kMax, {false, do_mount_all}}},
{"mount", {3, kMax, {false, do_mount}}},
{"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}},
- {"prepare_bootstrap_bionic",{0, 0, {false, do_prepare_bootstrap_bionic}}},
{"umount", {1, 1, {false, do_umount}}},
{"readahead", {1, 2, {true, do_readahead}}},
{"restart", {1, 1, {false, do_restart}}},
@@ -1220,7 +1144,6 @@
{"rm", {1, 1, {true, do_rm}}},
{"rmdir", {1, 1, {true, do_rmdir}}},
{"setprop", {2, 2, {true, do_setprop}}},
- {"setup_runtime_bionic", {0, 0, {false, do_setup_runtime_bionic}}},
{"setrlimit", {3, 3, {false, do_setrlimit}}},
{"start", {1, 1, {false, do_start}}},
{"stop", {1, 1, {false, do_stop}}},
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 71fe401..affa39e 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -34,6 +34,7 @@
#include <fs_mgr.h>
#include <fs_mgr_dm_linear.h>
#include <fs_mgr_overlayfs.h>
+#include <libgsi/libgsi.h>
#include <liblp/liblp.h>
#include "devices.h"
@@ -79,6 +80,7 @@
bool IsDmLinearEnabled();
bool GetDmLinearMetadataDevice();
bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata);
+ void UseGsiIfPresent();
ListenerAction UeventCallback(const Uevent& uevent);
@@ -207,6 +209,8 @@
}
required_devices_partition_names_.emplace(super_partition_name_);
+ // When booting from live GSI images, userdata is the super device.
+ required_devices_partition_names_.emplace("userdata");
return true;
}
@@ -410,6 +414,16 @@
// this case, we mount system first then pivot to it. From that point on,
// we are effectively identical to a system-as-root device.
bool FirstStageMount::TrySwitchSystemAsRoot() {
+ auto metadata_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
+ return entry.mount_point == "/metadata";
+ });
+ if (metadata_partition != fstab_.end()) {
+ if (MountPartition(&(*metadata_partition))) {
+ fstab_.erase(metadata_partition);
+ UseGsiIfPresent();
+ }
+ }
+
auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
return entry.mount_point == "/system";
});
@@ -513,6 +527,40 @@
return true;
}
+void FirstStageMount::UseGsiIfPresent() {
+ std::string metadata_file, error;
+
+ if (!android::gsi::CanBootIntoGsi(&metadata_file, &error)) {
+ LOG(INFO) << "GSI " << error << ", proceeding with normal boot";
+ return;
+ }
+
+ auto metadata = android::fs_mgr::ReadFromImageFile(metadata_file.c_str());
+ if (!metadata) {
+ LOG(ERROR) << "GSI partition layout could not be read";
+ return;
+ }
+
+ if (!android::fs_mgr::CreateLogicalPartitions(*metadata.get(), "/dev/block/by-name/userdata")) {
+ LOG(ERROR) << "GSI partition layout could not be instantiated";
+ return;
+ }
+
+ if (!android::gsi::MarkSystemAsGsi()) {
+ PLOG(ERROR) << "GSI indicator file could not be written";
+ return;
+ }
+
+ // Replace the existing system fstab entry.
+ auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
+ return entry.mount_point == "/system";
+ });
+ if (system_partition != fstab_.end()) {
+ fstab_.erase(system_partition);
+ }
+ fstab_.emplace_back(BuildGsiSystemFstabEntry());
+}
+
bool FirstStageMountVBootV1::GetDmVerityDevices() {
std::string verity_loc_device;
need_dm_verity_ = false;
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 008a868..0aa7810 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -20,9 +20,11 @@
#include <fcntl.h>
#include <linux/fs.h>
#include <mntent.h>
+#include <linux/loop.h>
#include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
+#include <sys/swap.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
@@ -58,6 +60,7 @@
using android::base::Split;
using android::base::StringPrintf;
using android::base::Timer;
+using android::base::unique_fd;
namespace android {
namespace init {
@@ -193,7 +196,7 @@
return true;
}
-static void DumpUmountDebuggingInfo(bool dump_all) {
+static void DumpUmountDebuggingInfo() {
int status;
if (!security_getenforce()) {
LOG(INFO) << "Run lsof";
@@ -202,10 +205,9 @@
true, nullptr, nullptr, 0);
}
FindPartitionsToUmount(nullptr, nullptr, true);
- if (dump_all) {
- // dump current tasks, this log can be lengthy, so only dump with dump_all
- android::base::WriteStringToFile("t", "/proc/sysrq-trigger");
- }
+ // dump current CPU stack traces and uninterruptible tasks
+ android::base::WriteStringToFile("l", "/proc/sysrq-trigger");
+ android::base::WriteStringToFile("w", "/proc/sysrq-trigger");
}
static UmountStat UmountPartitions(std::chrono::milliseconds timeout) {
@@ -268,11 +270,11 @@
UmountStat stat = UmountPartitions(timeout - t.duration());
if (stat != UMOUNT_STAT_SUCCESS) {
LOG(INFO) << "umount timeout, last resort, kill all and try";
- if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(true);
+ if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
KillAllProcesses();
// even if it succeeds, still it is timeout and do not run fsck with all processes killed
UmountStat st = UmountPartitions(0ms);
- if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(false);
+ if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
}
if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
@@ -285,6 +287,48 @@
return stat;
}
+// zram is able to use backing device on top of a loopback device.
+// In order to unmount /data successfully, we have to kill the loopback device first
+#define ZRAM_DEVICE "/dev/block/zram0"
+#define ZRAM_RESET "/sys/block/zram0/reset"
+#define ZRAM_BACK_DEV "/sys/block/zram0/backing_dev"
+static void KillZramBackingDevice() {
+ std::string backing_dev;
+ if (!android::base::ReadFileToString(ZRAM_BACK_DEV, &backing_dev)) return;
+
+ if (!android::base::StartsWith(backing_dev, "/dev/block/loop")) return;
+
+ // cut the last "\n"
+ backing_dev.erase(backing_dev.length() - 1);
+
+ // shutdown zram handle
+ Timer swap_timer;
+ LOG(INFO) << "swapoff() start...";
+ if (swapoff(ZRAM_DEVICE) == -1) {
+ LOG(ERROR) << "zram_backing_dev: swapoff (" << backing_dev << ")" << " failed";
+ return;
+ }
+ LOG(INFO) << "swapoff() took " << swap_timer;;
+
+ if (!android::base::WriteStringToFile("1", ZRAM_RESET)) {
+ LOG(ERROR) << "zram_backing_dev: reset (" << backing_dev << ")" << " failed";
+ return;
+ }
+
+ // clear loopback device
+ unique_fd loop(TEMP_FAILURE_RETRY(open(backing_dev.c_str(), O_RDWR | O_CLOEXEC)));
+ if (loop.get() < 0) {
+ LOG(ERROR) << "zram_backing_dev: open(" << backing_dev << ")" << " failed";
+ return;
+ }
+
+ if (ioctl(loop.get(), LOOP_CLR_FD, 0) < 0) {
+ LOG(ERROR) << "zram_backing_dev: loop_clear (" << backing_dev << ")" << " failed";
+ return;
+ }
+ LOG(INFO) << "zram_backing_dev: `" << backing_dev << "` is cleared successfully.";
+}
+
//* Reboot / shutdown the system.
// cmd ANDROID_RB_* as defined in android_reboot.h
// reason Reason string like "reboot", "shutdown,userrequested"
@@ -427,6 +471,9 @@
sync();
LOG(INFO) << "sync() before umount took" << sync_timer;
}
+ // 5. drop caches and disable zram backing device, if exist
+ KillZramBackingDevice();
+
UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
// Follow what linux shutdown is doing: one more sync with little bit delay
{
diff --git a/init/selinux.cpp b/init/selinux.cpp
index e4da52c..c0fc3ce 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -434,12 +434,6 @@
selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE);
selinux_android_restorecon("/dev/device-mapper", 0);
-
- selinux_android_restorecon("/sbin/mke2fs_static", 0);
- selinux_android_restorecon("/sbin/e2fsdroid_static", 0);
-
- selinux_android_restorecon("/sbin/mkfs.f2fs", 0);
- selinux_android_restorecon("/sbin/sload.f2fs", 0);
}
int SelinuxKlogCallback(int type, const char* fmt, ...) {
diff --git a/init/service.cpp b/init/service.cpp
index f3eafe4..272809f 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -140,43 +140,6 @@
return Success();
}
-Result<Success> Service::SetUpPreApexdMounts() const {
- // If a pre-apexd service is 're' launched after the runtime APEX is
- // available, unmount the linker and bionic libs which are currently
- // bind mounted to the files in the runtime APEX. This will reveal
- // the hidden mount points (targetting the bootstrap ones in the
- // system partition) which were setup before the runtime APEX was
- // started. Note that these unmounts are done in a separate mount namespace
- // for the process. It does not affect other processes including the init.
- if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
- if (access(kLinkerMountPoint, F_OK) == 0) {
- if (umount(kLinkerMountPoint) == -1) {
- return ErrnoError() << "Could not umount " << kLinkerMountPoint;
- }
- for (const auto& libname : kBionicLibFileNames) {
- std::string mount_point = kBionicLibsMountPointDir + libname;
- if (umount(mount_point.c_str()) == -1) {
- return ErrnoError() << "Could not umount " << mount_point;
- }
- }
- }
-
- if (access(kLinkerMountPoint64, F_OK) == 0) {
- if (umount(kLinkerMountPoint64) == -1) {
- return ErrnoError() << "Could not umount " << kLinkerMountPoint64;
- }
- for (const auto& libname : kBionicLibFileNames) {
- std::string mount_point = kBionicLibsMountPointDir64 + libname;
- std::string source = kBootstrapBionicLibsDir64 + libname;
- if (umount(mount_point.c_str()) == -1) {
- return ErrnoError() << "Could not umount " << mount_point;
- }
- }
- }
- }
- return Success();
-}
-
Result<Success> Service::SetUpPidNamespace() const {
if (prctl(PR_SET_NAME, name_.c_str()) == -1) {
return ErrnoError() << "Could not set name";
@@ -406,7 +369,7 @@
// If we crash > 4 times in 4 minutes, reboot into bootloader or set crashing property
boot_clock::time_point now = boot_clock::now();
- if (((flags_ & SVC_CRITICAL) || !pre_apexd_) && !(flags_ & SVC_RESTART)) {
+ if (((flags_ & SVC_CRITICAL) || classnames_.count("updatable")) && !(flags_ & SVC_RESTART)) {
if (now < time_crashed_ + 4min) {
if (++crash_count_ > 4) {
if (flags_ & SVC_CRITICAL) {
@@ -966,14 +929,6 @@
scon = *result;
}
- if (!ServiceList::GetInstance().IsRuntimeAvailable() && !pre_apexd_) {
- // If this service is started before the runtime APEX gets available,
- // mark it as pre-apexd one. Note that this marking is permanent. So
- // for example, if the service is re-launched (e.g., due to crash),
- // it is still recognized as pre-apexd... for consistency.
- pre_apexd_ = true;
- }
-
LOG(INFO) << "starting service '" << name_ << "'...";
pid_t pid = -1;
@@ -990,37 +945,6 @@
LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
}
- // b/122559956: mount namespace is not cloned for the devices that don't support
- // the update of bionic libraries via APEX. In that case, because the bionic
- // libraries in the runtime APEX and the bootstrap bionic libraries are
- // identical, it doesn't matter which libs are used. This is also to avoid the
- // bug in sdcardfs which is triggered when we have multiple mount namespaces
- // across vold and the others. BIONIC_UPDATABLE shall be true only for the
- // devices where kernel has the fix for the sdcardfs bug (see the commit message
- // for the fix).
- static bool bionic_updatable =
- android::base::GetBoolProperty("ro.apex.bionic_updatable", false);
-
- if (bionic_updatable && pre_apexd_) {
- // pre-apexd process gets a private copy of the mount namespace.
- // However, this does not mean that mount/unmount events are not
- // shared across pre-apexd processes and post-apexd processes.
- // *Most* of the events are still shared because the propagation
- // type of / is set to 'shared'. (see `mount rootfs rootfs /shared
- // rec` in init.rc)
- //
- // This unsharing is required to not propagate the mount events
- // under /system/lib/{libc|libdl|libm}.so and /system/bin/linker(64)
- // whose propagation type is set to private. With this,
- // bind-mounting the bionic libs and the dynamic linker from the
- // runtime APEX to the mount points does not affect pre-apexd
- // processes which should use the bootstrap ones.
- if (unshare(CLONE_NEWNS) != 0) {
- LOG(FATAL) << "Creating a new mount namespace for service"
- << " '" << name_ << "' failed: " << strerror(errno);
- }
- }
-
if (namespace_flags_ & CLONE_NEWNS) {
if (auto result = SetUpMountNamespace(); !result) {
LOG(FATAL) << "Service '" << name_
@@ -1028,14 +952,6 @@
}
}
- // b/122559956: same as above
- if (bionic_updatable && pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
- if (auto result = SetUpPreApexdMounts(); !result) {
- LOG(FATAL) << "Pre-apexd service '" << name_
- << "' could not setup the mount points: " << result.error();
- }
- }
-
if (namespace_flags_ & CLONE_NEWPID) {
// This will fork again to run an init process inside the PID
// namespace.
@@ -1408,10 +1324,6 @@
delayed_service_names_.clear();
}
-void ServiceList::MarkRuntimeAvailable() {
- runtime_available_ = true;
-}
-
void ServiceList::DelayService(const Service& service) {
if (services_update_finished_) {
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
diff --git a/init/service.h b/init/service.h
index 676111f..56e75b0 100644
--- a/init/service.h
+++ b/init/service.h
@@ -62,24 +62,6 @@
namespace android {
namespace init {
-static constexpr const char* kLinkerMountPoint = "/system/bin/linker";
-static constexpr const char* kBootstrapLinkerPath = "/system/bin/linker";
-static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker";
-
-static constexpr const char* kBionicLibsMountPointDir = "/system/lib/";
-static constexpr const char* kBootstrapBionicLibsDir = "/system/lib/";
-static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/";
-
-static constexpr const char* kLinkerMountPoint64 = "/system/bin/linker64";
-static constexpr const char* kBootstrapLinkerPath64 = "/system/bin/linker64";
-static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64";
-
-static constexpr const char* kBionicLibsMountPointDir64 = "/system/lib64/";
-static constexpr const char* kBootstrapBionicLibsDir64 = "/system/lib64/";
-static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/";
-
-static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"};
-
class Service {
public:
Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
@@ -142,7 +124,6 @@
std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; }
const std::vector<std::string>& args() const { return args_; }
bool is_updatable() const { return updatable_; }
- bool is_pre_apexd() const { return pre_apexd_; }
private:
using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
@@ -151,7 +132,6 @@
Result<Success> SetUpMountNamespace() const;
Result<Success> SetUpPidNamespace() const;
Result<Success> EnterNamespaces() const;
- Result<Success> SetUpPreApexdMounts() const;
void NotifyStateChange(const std::string& new_state) const;
void StopOrReset(int how);
void ZapStdio() const;
@@ -262,8 +242,6 @@
std::vector<std::string> args_;
std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
-
- bool pre_apexd_ = false;
};
class ServiceList {
@@ -306,16 +284,13 @@
const std::vector<Service*> services_in_shutdown_order() const;
void MarkServicesUpdate();
- void MarkRuntimeAvailable();
bool IsServicesUpdated() const { return services_update_finished_; }
- bool IsRuntimeAvailable() const { return runtime_available_; }
void DelayService(const Service& service);
private:
std::vector<std::unique_ptr<Service>> services_;
bool services_update_finished_ = false;
- bool runtime_available_ = false;
std::vector<std::string> delayed_service_names_;
};
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 0723612..03edfb5 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -190,7 +190,8 @@
*/
#define AID_OVERFLOWUID 65534 /* unmapped user in the user namespace */
-#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
+/* use the ranges below to determine whether a process is isolated */
+#define AID_ISOLATED_START 90000 /* start of uids for fully isolated sandboxed processes */
#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
#define AID_USER 100000 /* TODO: switch users over to AID_USER_OFFSET */
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 5c6ee59..4fd36f5 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -85,7 +85,6 @@
ldflags: ["-Wl,--hash-style=both"],
},
windows: {
- srcs: ["uio.cpp"],
enabled: true,
},
not_windows: {
diff --git a/liblog/fake_log_device.cpp b/liblog/fake_log_device.cpp
index 4f3a230..5daae41 100644
--- a/liblog/fake_log_device.cpp
+++ b/liblog/fake_log_device.cpp
@@ -33,7 +33,6 @@
#include <time.h>
#include <android/log.h>
-#include <log/uio.h>
#include "log_portability.h"
diff --git a/liblog/fake_log_device.h b/liblog/fake_log_device.h
index 74d434e..ef0beb6 100644
--- a/liblog/fake_log_device.h
+++ b/liblog/fake_log_device.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include "log_portability.h"
+#include "uio.h"
struct iovec;
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index f63f480..5928649 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -34,7 +34,6 @@
#include <log/log_safetynet.h>
#include <log/log_system.h>
#include <log/log_time.h>
-#include <log/uio.h> /* helper to define iovec for portability */
#ifdef __cplusplus
extern "C" {
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
index b376504..636d417 100644
--- a/liblog/include/log/log_event_list.h
+++ b/liblog/include/log/log_event_list.h
@@ -109,8 +109,6 @@
/* android_log_list C++ helpers */
extern "C++" {
class android_log_event_list {
- friend class __android_log_event_list;
-
private:
android_log_context ctx;
int ret;
@@ -122,10 +120,6 @@
explicit android_log_event_list(int tag) : ret(0) {
ctx = create_android_logger(static_cast<uint32_t>(tag));
}
- explicit android_log_event_list(log_msg& log_msg) : ret(0) {
- ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
- log_msg.entry.len - sizeof(uint32_t));
- }
~android_log_event_list() {
android_log_destroy(&ctx);
}
@@ -283,13 +277,6 @@
if (retval < 0) ret = retval;
return ret >= 0;
}
-
- android_log_list_element read() {
- return android_log_read_next(ctx);
- }
- android_log_list_element peek() {
- return android_log_peek_next(ctx);
- }
};
}
#endif
diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h
index 830f651..5e04148 100644
--- a/liblog/include/private/android_logger.h
+++ b/liblog/include/private/android_logger.h
@@ -150,37 +150,6 @@
/* Retrieve the composed event buffer */
int android_log_write_list_buffer(android_log_context ctx, const char** msg);
-#ifdef __cplusplus
-#ifdef __class_android_log_event_list_defined
-#ifndef __class_android_log_event_list_private_defined
-#define __class_android_log_event_list_private_defined
-/* android_log_context C++ helpers */
-extern "C++" {
-class __android_log_event_list : public android_log_event_list {
- __android_log_event_list(const android_log_event_list&) = delete;
- void operator=(const __android_log_event_list&) = delete;
-
- public:
- explicit __android_log_event_list(int tag) : android_log_event_list(tag) {
- }
- explicit __android_log_event_list(log_msg& log_msg)
- : android_log_event_list(log_msg) {
- }
-
- operator std::string() {
- if (ret) return std::string("");
- const char* cp = nullptr;
- ssize_t len = android_log_write_list_buffer(ctx, &cp);
- if (len < 0) ret = len;
- if (!cp || (len <= 0)) return std::string("");
- return std::string(cp, len);
- }
-};
-}
-#endif
-#endif
-#endif
-
#if defined(__cplusplus)
}
#endif
diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp
index 4731487..ed906b3 100644
--- a/liblog/logd_writer.cpp
+++ b/liblog/logd_writer.cpp
@@ -38,6 +38,7 @@
#include "config_write.h"
#include "log_portability.h"
#include "logger.h"
+#include "uio.h"
/* branchless on many architectures. */
#define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
diff --git a/liblog/logger.h b/liblog/logger.h
index 25ee065..b2479d2 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -21,9 +21,9 @@
#include <cutils/list.h>
#include <log/log.h>
-#include <log/uio.h>
#include "log_portability.h"
+#include "uio.h"
__BEGIN_DECLS
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index fbe6874..af8cb2d 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -33,6 +33,7 @@
#include "config_write.h"
#include "log_portability.h"
#include "logger.h"
+#include "uio.h"
#define LOG_BUF_SIZE 1024
@@ -524,11 +525,8 @@
// Log assertion failures to stderr for the benefit of "adb shell" users
// and gtests (http://b/23675822).
- struct iovec iov[2] = {
- {buf, strlen(buf)},
- {(char*)"\n", 1},
- };
- TEMP_FAILURE_RETRY(writev(2, iov, 2));
+ TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
+ TEMP_FAILURE_RETRY(write(2, "\n", 1));
__android_log_write(ANDROID_LOG_FATAL, tag, buf);
abort(); /* abort so we have a chance to debug the situation */
diff --git a/liblog/pmsg_writer.cpp b/liblog/pmsg_writer.cpp
index c50c7f7..b2fc6d0 100644
--- a/liblog/pmsg_writer.cpp
+++ b/liblog/pmsg_writer.cpp
@@ -33,6 +33,7 @@
#include "config_write.h"
#include "log_portability.h"
#include "logger.h"
+#include "uio.h"
static int pmsgOpen();
static void pmsgClose();
diff --git a/liblog/stderr_write.cpp b/liblog/stderr_write.cpp
index f9cb37d..28195aa 100644
--- a/liblog/stderr_write.cpp
+++ b/liblog/stderr_write.cpp
@@ -37,10 +37,10 @@
#include <log/event_tag_map.h>
#include <log/log.h>
#include <log/logprint.h>
-#include <log/uio.h>
#include "log_portability.h"
#include "logger.h"
+#include "uio.h"
static int stderrOpen();
static void stderrClose();
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index c2f3f83..c8ac321 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -21,6 +21,7 @@
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <unistd.h>
#include <unordered_set>
diff --git a/liblog/uio.cpp b/liblog/uio.cpp
deleted file mode 100644
index 05145d7..0000000
--- a/liblog/uio.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007-2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if defined(_WIN32)
-
-#include <unistd.h>
-
-#include <log/uio.h>
-
-#include "log_portability.h"
-
-LIBLOG_ABI_PUBLIC int readv(int fd, struct iovec* vecs, int count) {
- int total = 0;
-
- for (; count > 0; count--, vecs++) {
- char* buf = static_cast<char*>(vecs->iov_base);
- int len = vecs->iov_len;
-
- while (len > 0) {
- int ret = read(fd, buf, len);
- if (ret < 0) {
- if (total == 0) total = -1;
- goto Exit;
- }
- if (ret == 0) goto Exit;
-
- total += ret;
- buf += ret;
- len -= ret;
- }
- }
-Exit:
- return total;
-}
-
-LIBLOG_ABI_PUBLIC int writev(int fd, const struct iovec* vecs, int count) {
- int total = 0;
-
- for (; count > 0; count--, vecs++) {
- const char* buf = static_cast<const char*>(vecs->iov_base);
- int len = vecs->iov_len;
-
- while (len > 0) {
- int ret = write(fd, buf, len);
- if (ret < 0) {
- if (total == 0) total = -1;
- goto Exit;
- }
- if (ret == 0) goto Exit;
-
- total += ret;
- buf += ret;
- len -= ret;
- }
- }
-Exit:
- return total;
-}
-
-#endif
diff --git a/liblog/include/log/uio.h b/liblog/uio.h
similarity index 67%
rename from liblog/include/log/uio.h
rename to liblog/uio.h
index 7feb552..c85893c 100644
--- a/liblog/include/log/uio.h
+++ b/liblog/uio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2014 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,32 +16,12 @@
#pragma once
-#if !defined(_WIN32)
-
-#include <sys/uio.h>
-
-#else
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//
-// Implementation of sys/uio.h for Win32.
-//
-
+#if defined(_WIN32)
#include <stddef.h>
-
struct iovec {
void* iov_base;
size_t iov_len;
};
-
-extern int readv(int fd, struct iovec* vecs, int count);
-extern int writev(int fd, const struct iovec* vecs, int count);
-
-#ifdef __cplusplus
-}
-#endif
-
+#else
+#include <sys/uio.h>
#endif
diff --git a/libstats/include/stats_event_list.h b/libstats/include/stats_event_list.h
index 162d1cf..b5bc5af 100644
--- a/libstats/include/stats_event_list.h
+++ b/libstats/include/stats_event_list.h
@@ -51,10 +51,6 @@
explicit stats_event_list(int tag) : ret(0) {
ctx = create_android_logger(static_cast<uint32_t>(tag));
}
- explicit stats_event_list(log_msg& log_msg) : ret(0) {
- ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
- log_msg.entry.len - sizeof(uint32_t));
- }
~stats_event_list() { android_log_destroy(&ctx); }
int close() {
@@ -251,9 +247,6 @@
}
return ret >= 0;
}
-
- android_log_list_element read() { return android_log_read_next(ctx); }
- android_log_list_element peek() { return android_log_peek_next(ctx); }
};
#endif
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
index f00fc2d..f5be95c 100644
--- a/libstats/statsd_writer.c
+++ b/libstats/statsd_writer.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>
diff --git a/logcat/Android.bp b/logcat/Android.bp
index b0563a6..0543aba 100644
--- a/logcat/Android.bp
+++ b/logcat/Android.bp
@@ -25,9 +25,9 @@
shared_libs: [
"libbase",
"libcutils",
- "liblog",
"libpcrecpp",
],
+ static_libs: ["liblog"],
logtags: ["event.logtags"],
}
diff --git a/logcat/tests/Android.bp b/logcat/tests/Android.bp
index e1f4d6f..ab84150 100644
--- a/logcat/tests/Android.bp
+++ b/logcat/tests/Android.bp
@@ -48,10 +48,8 @@
cc_test {
name: "logcat-unit-tests",
defaults: ["logcat-tests-defaults"],
- shared_libs: [
- "liblog",
- "libbase",
- ],
+ shared_libs: ["libbase"],
+ static_libs: ["liblog"],
srcs: [
"logcat_test.cpp",
"logcatd_test.cpp",
diff --git a/logd/Android.bp b/logd/Android.bp
index 5c79976..3abfc21 100644
--- a/logd/Android.bp
+++ b/logd/Android.bp
@@ -63,11 +63,13 @@
srcs: ["main.cpp"],
- static_libs: ["liblogd"],
+ static_libs: [
+ "liblog",
+ "liblogd",
+ ],
shared_libs: [
"libsysutils",
- "liblog",
"libcutils",
"libbase",
"libpackagelistparser",
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index 1ab9dd1..f19e7b0 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -30,6 +30,7 @@
#include <android-base/file.h>
#include <android-base/macros.h>
+#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <log/log_event_list.h>
#include <log/log_properties.h>
@@ -38,6 +39,8 @@
#include "LogTags.h"
#include "LogUtils.h"
+using android::base::make_scope_guard;
+
static LogTags* logtags;
const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags";
@@ -316,27 +319,29 @@
std::string Format;
android_log_list_element elem;
{
- android_log_event_list ctx(log_msg);
- elem = ctx.read();
+ auto ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
+ log_msg.entry.len - sizeof(uint32_t));
+ auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
+ elem = android_log_read_next(ctx);
if (elem.type != EVENT_TYPE_LIST) {
continue;
}
- elem = ctx.read();
+ elem = android_log_read_next(ctx);
if (elem.type != EVENT_TYPE_INT) {
continue;
}
Tag = elem.data.int32;
- elem = ctx.read();
+ elem = android_log_read_next(ctx);
if (elem.type != EVENT_TYPE_STRING) {
continue;
}
Name = std::string(elem.data.string, elem.len);
- elem = ctx.read();
+ elem = android_log_read_next(ctx);
if (elem.type != EVENT_TYPE_STRING) {
continue;
}
Format = std::string(elem.data.string, elem.len);
- elem = ctx.read();
+ elem = android_log_read_next(ctx);
}
if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue;
@@ -524,10 +529,22 @@
tag2format_const_iterator iform = tag2format.find(tag);
std::string Format = (iform != tag2format.end()) ? iform->second : "";
- __android_log_event_list ctx(TAG_DEF_LOG_TAG);
- ctx << tag << Name << Format;
- std::string buffer(ctx);
- if (buffer.length() <= 0) return; // unlikely
+ auto ctx = create_android_logger(TAG_DEF_LOG_TAG);
+ auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
+ if (android_log_write_int32(ctx, static_cast<int32_t>(tag) < 0) ||
+ android_log_write_string8_len(ctx, Name.c_str(), Name.size()) < 0 ||
+ android_log_write_string8_len(ctx, Format.c_str(), Format.size()) < 0) {
+ return;
+ }
+
+ const char* cp = nullptr;
+ ssize_t len = android_log_write_list_buffer(ctx, &cp);
+
+ if (len <= 0 || cp == nullptr) {
+ return;
+ }
+
+ std::string buffer(cp, len);
/*
* struct {
diff --git a/logd/tests/Android.bp b/logd/tests/Android.bp
index f15beb2..83a194f 100644
--- a/logd/tests/Android.bp
+++ b/logd/tests/Android.bp
@@ -38,9 +38,9 @@
shared_libs: [
"libbase",
"libcutils",
- "liblog",
"libselinux",
],
+ static_libs: ["liblog"],
}
// Build tests for the logger. Run with:
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9b20964..537bf86 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -12,12 +12,6 @@
import /init.${ro.zygote}.rc
on early-init
- # Mount shared so changes propagate into child namespaces
- # Do this before other processes are started from init. Otherwise,
- # processes launched while the propagation type of / is 'private'
- # won't get mount events from others.
- mount rootfs rootfs / shared rec
-
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000
@@ -46,8 +40,6 @@
# cgroup for system_server and surfaceflinger
mkdir /dev/memcg/system 0550 system system
- prepare_bootstrap_bionic
-
start ueventd
on init
@@ -117,6 +109,8 @@
mkdir /mnt/runtime/read/self 0755 root root
mkdir /mnt/runtime/write 0755 root root
mkdir /mnt/runtime/write/self 0755 root root
+ mkdir /mnt/runtime/full 0755 root root
+ mkdir /mnt/runtime/full/self 0755 root root
# Symlink to keep legacy apps working in multi-user world
symlink /storage/self/primary /sdcard
@@ -352,6 +346,8 @@
# Once everything is setup, no need to modify /.
# The bind+remount combination allows this to work in containers.
mount rootfs rootfs / remount bind ro nodev
+ # Mount shared so changes propagate into child namespaces
+ mount rootfs rootfs / shared rec
# Mount default storage into root namespace
mount none /mnt/runtime/default /storage bind rec
mount none none /storage slave rec
@@ -587,14 +583,6 @@
# Check any timezone data in /data is newer than the copy in the runtime module, delete if not.
exec - system system -- /system/bin/tzdatacheck /apex/com.android.runtime/etc/tz /data/misc/zoneinfo
- # Wait for apexd to finish activating APEXes before starting more processes.
- # This certainly reduces the parallelism but is required to make as many processes
- # as possible to use the bionic libs from the runtime APEX. This takes less than 50ms
- # so the impact on the booting time is not significant.
- wait_for_prop apexd.status ready
- setup_runtime_bionic
- parse_apex_configs
-
# If there is no post-fs-data action in the init.<device>.rc file, you
# must uncomment this line, otherwise encrypted filesystems
# won't work.
@@ -816,3 +804,6 @@
service flash_recovery /system/bin/install-recovery.sh
class main
oneshot
+
+on property:apexd.status=ready
+ parse_apex_configs
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index dc36596..e1de130 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -160,6 +160,7 @@
std::string dest_path_default = "/mnt/runtime/default/" + label;
std::string dest_path_read = "/mnt/runtime/read/" + label;
std::string dest_path_write = "/mnt/runtime/write/" + label;
+ std::string dest_path_full = "/mnt/runtime/full/" + label;
umask(0);
if (multi_user) {
@@ -172,7 +173,10 @@
default_normal, use_esdfs) ||
!sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_write, uid, gid,
multi_user, userid, AID_EVERYBODY, full_write ? 0007 : 0027,
- derive_gid, default_normal, use_esdfs)) {
+ derive_gid, default_normal, use_esdfs) ||
+ !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_full, uid, gid,
+ multi_user, userid, AID_EVERYBODY, 0007, derive_gid,
+ default_normal, use_esdfs)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
} else {
@@ -186,7 +190,10 @@
derive_gid, default_normal, use_esdfs) ||
!sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_write, uid, gid,
multi_user, userid, AID_EVERYBODY, full_write ? 0007 : 0022,
- derive_gid, default_normal, use_esdfs)) {
+ derive_gid, default_normal, use_esdfs) ||
+ !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_full, uid, gid,
+ multi_user, userid, AID_EVERYBODY, 0007, derive_gid,
+ default_normal, use_esdfs)) {
LOG(FATAL) << "failed to sdcardfs_setup";
}
}
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 2d4a26f..cb5c5cb 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -18,6 +18,7 @@
"newfs_msdos",
"reboot",
"sh",
+ "simpleperf",
"tcpdump",
"toolbox",
"toybox",
diff --git a/trusty/libtrusty/tipc-test/Android.bp b/trusty/libtrusty/tipc-test/Android.bp
index 32499e3..9676b79 100644
--- a/trusty/libtrusty/tipc-test/Android.bp
+++ b/trusty/libtrusty/tipc-test/Android.bp
@@ -17,12 +17,10 @@
vendor: true,
srcs: ["tipc_test.c"],
- static_libs: [
- "libtrusty",
- ],
shared_libs: [
"libc",
"liblog",
+ "libtrusty",
],
gtest: false,
cflags: [