Merge "logd: remove failing test."
diff --git a/adb/Android.bp b/adb/Android.bp
index 53bf7e3..97c9762 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -104,6 +104,7 @@
"socket_spec.cpp",
"sysdeps/errno.cpp",
"transport.cpp",
+ "transport_fd.cpp",
"transport_local.cpp",
"transport_usb.cpp",
]
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 06fcf16..e07dba7 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1795,6 +1795,11 @@
}
else if (!strcmp(argv[0], "track-devices")) {
return adb_connect_command("host:track-devices");
+ } else if (!strcmp(argv[0], "raw")) {
+ if (argc != 2) {
+ return syntax_error("adb raw SERVICE");
+ }
+ return adb_connect_command(argv[1]);
}
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index 1b7758c..f98c11a 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -21,6 +21,7 @@
#include "fdevent.h"
#include <fcntl.h>
+#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -34,6 +35,7 @@
#include <unordered_map>
#include <vector>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
@@ -75,6 +77,8 @@
static bool main_thread_valid;
static uint64_t main_thread_id;
+static uint64_t fdevent_id;
+
static bool run_needs_flush = false;
static auto& run_queue_notify_fd = *new unique_fd();
static auto& run_queue_mutex = *new std::mutex();
@@ -111,7 +115,8 @@
if (fde->state & FDE_ERROR) {
state += "E";
}
- return android::base::StringPrintf("(fdevent %d %s)", fde->fd.get(), state.c_str());
+ return android::base::StringPrintf("(fdevent %" PRIu64 ": fd %d %s)", fde->id, fde->fd.get(),
+ state.c_str());
}
void fdevent_install(fdevent* fde, int fd, fd_func func, void* arg) {
@@ -125,6 +130,7 @@
CHECK_GE(fd, 0);
fdevent* fde = new fdevent();
+ fde->id = fdevent_id++;
fde->state = FDE_ACTIVE;
fde->fd.reset(fd);
fde->func = func;
@@ -352,10 +358,56 @@
}
}
+static void fdevent_check_spin(uint64_t cycle) {
+ // Check to see if we're spinning because we forgot about an fdevent
+ // by keeping track of how long fdevents have been continuously pending.
+ struct SpinCheck {
+ fdevent* fde;
+ std::chrono::steady_clock::time_point timestamp;
+ uint64_t cycle;
+ };
+ static auto& g_continuously_pending = *new std::unordered_map<uint64_t, SpinCheck>();
+
+ auto now = std::chrono::steady_clock::now();
+ for (auto* fde : g_pending_list) {
+ auto it = g_continuously_pending.find(fde->id);
+ if (it == g_continuously_pending.end()) {
+ g_continuously_pending[fde->id] =
+ SpinCheck{.fde = fde, .timestamp = now, .cycle = cycle};
+ } else {
+ it->second.cycle = cycle;
+ }
+ }
+
+ for (auto it = g_continuously_pending.begin(); it != g_continuously_pending.end();) {
+ if (it->second.cycle != cycle) {
+ it = g_continuously_pending.erase(it);
+ } else {
+ // Use an absurdly long window, since all we really care about is
+ // getting a bugreport eventually.
+ if (now - it->second.timestamp > std::chrono::minutes(5)) {
+ LOG(FATAL_WITHOUT_ABORT) << "detected spin in fdevent: " << dump_fde(it->second.fde);
+#if defined(__linux__)
+ int fd = it->second.fde->fd.get();
+ std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fd);
+ std::string path;
+ if (!android::base::Readlink(fd_path, &path)) {
+ PLOG(FATAL_WITHOUT_ABORT) << "readlink of fd " << fd << " failed";
+ }
+ LOG(FATAL_WITHOUT_ABORT) << "fd " << fd << " = " << path;
+#endif
+ abort();
+ }
+ ++it;
+ }
+ }
+}
+
void fdevent_loop() {
set_main_thread();
fdevent_run_setup();
+ uint64_t cycle = 0;
while (true) {
if (terminate_loop) {
return;
@@ -365,6 +417,8 @@
fdevent_process();
+ fdevent_check_spin(cycle++);
+
while (!g_pending_list.empty()) {
fdevent* fde = g_pending_list.front();
g_pending_list.pop_front();
diff --git a/adb/fdevent.h b/adb/fdevent.h
index 69c4072..d501b86 100644
--- a/adb/fdevent.h
+++ b/adb/fdevent.h
@@ -32,8 +32,7 @@
typedef void (*fd_func)(int fd, unsigned events, void *userdata);
struct fdevent {
- fdevent* next = nullptr;
- fdevent* prev = nullptr;
+ uint64_t id;
unique_fd fd;
int force_eof = 0;
diff --git a/adb/services.cpp b/adb/services.cpp
index a757d90..b613d83 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -181,6 +181,29 @@
kick_transport(t);
}
+static void spin_service(int fd, void*) {
+ unique_fd sfd(fd);
+
+ if (!__android_log_is_debuggable()) {
+ WriteFdExactly(sfd.get(), "refusing to spin on non-debuggable build\n");
+ return;
+ }
+
+ // A service that creates an fdevent that's always pending, and then ignores it.
+ unique_fd pipe_read, pipe_write;
+ if (!Pipe(&pipe_read, &pipe_write)) {
+ WriteFdExactly(sfd.get(), "failed to create pipe\n");
+ return;
+ }
+
+ fdevent_run_on_main_thread([fd = pipe_read.release()]() {
+ fdevent* fde = fdevent_create(fd, [](int, unsigned, void*) {}, nullptr);
+ fdevent_add(fde, FDE_READ);
+ });
+
+ WriteFdExactly(sfd.get(), "spinning\n");
+}
+
int reverse_service(const char* command, atransport* transport) {
int s[2];
if (adb_socketpair(s)) {
@@ -328,6 +351,8 @@
reinterpret_cast<void*>(1));
} else if (!strcmp(name, "reconnect")) {
ret = create_service_thread("reconnect", reconnect_service, transport);
+ } else if (!strcmp(name, "spin")) {
+ ret = create_service_thread("spin", spin_service, nullptr);
#endif
}
if (ret >= 0) {
diff --git a/adb/transport.h b/adb/transport.h
index ae9cc02..cb20615 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -92,6 +92,8 @@
std::string transport_name_;
ReadCallback read_callback_;
ErrorCallback error_callback_;
+
+ static std::unique_ptr<Connection> FromFd(unique_fd fd);
};
// Abstraction for a blocking packet transport.
diff --git a/adb/transport_benchmark.cpp b/adb/transport_benchmark.cpp
index da24aa7..022808f 100644
--- a/adb/transport_benchmark.cpp
+++ b/adb/transport_benchmark.cpp
@@ -24,13 +24,19 @@
#include "sysdeps.h"
#include "transport.h"
-#define ADB_CONNECTION_BENCHMARK(benchmark_name, ...) \
- BENCHMARK_TEMPLATE(benchmark_name, FdConnection, ##__VA_ARGS__) \
- ->Arg(1) \
- ->Arg(16384) \
- ->Arg(MAX_PAYLOAD) \
+#define ADB_CONNECTION_BENCHMARK(benchmark_name, ...) \
+ BENCHMARK_TEMPLATE(benchmark_name, FdConnection, ##__VA_ARGS__) \
+ ->Arg(1) \
+ ->Arg(16384) \
+ ->Arg(MAX_PAYLOAD) \
+ ->UseRealTime(); \
+ BENCHMARK_TEMPLATE(benchmark_name, NonblockingFdConnection, ##__VA_ARGS__) \
+ ->Arg(1) \
+ ->Arg(16384) \
+ ->Arg(MAX_PAYLOAD) \
->UseRealTime()
+struct NonblockingFdConnection;
template <typename ConnectionType>
std::unique_ptr<Connection> MakeConnection(unique_fd fd);
@@ -40,6 +46,11 @@
return std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection));
}
+template <>
+std::unique_ptr<Connection> MakeConnection<NonblockingFdConnection>(unique_fd fd) {
+ return Connection::FromFd(std::move(fd));
+}
+
template <typename ConnectionType>
void BM_Connection_Unidirectional(benchmark::State& state) {
int fds[2];
diff --git a/adb/transport_fd.cpp b/adb/transport_fd.cpp
new file mode 100644
index 0000000..85f3c52
--- /dev/null
+++ b/adb/transport_fd.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <stdint.h>
+
+#include <deque>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
+
+#include "adb_unique_fd.h"
+#include "adb_utils.h"
+#include "sysdeps.h"
+#include "sysdeps/memory.h"
+#include "transport.h"
+#include "types.h"
+
+static void CreateWakeFds(unique_fd* read, unique_fd* write) {
+ // TODO: eventfd on linux?
+ int wake_fds[2];
+ int rc = adb_socketpair(wake_fds);
+ set_file_block_mode(wake_fds[0], false);
+ set_file_block_mode(wake_fds[1], false);
+ CHECK_EQ(0, rc);
+ *read = unique_fd(wake_fds[0]);
+ *write = unique_fd(wake_fds[1]);
+}
+
+struct NonblockingFdConnection : public Connection {
+ NonblockingFdConnection(unique_fd fd) : started_(false), fd_(std::move(fd)) {
+ set_file_block_mode(fd_.get(), false);
+ CreateWakeFds(&wake_fd_read_, &wake_fd_write_);
+ }
+
+ void SetRunning(bool value) {
+ std::lock_guard<std::mutex> lock(run_mutex_);
+ running_ = value;
+ }
+
+ bool IsRunning() {
+ std::lock_guard<std::mutex> lock(run_mutex_);
+ return running_;
+ }
+
+ void Run(std::string* error) {
+ SetRunning(true);
+ while (IsRunning()) {
+ adb_pollfd pfds[2] = {
+ {.fd = fd_.get(), .events = POLLIN},
+ {.fd = wake_fd_read_.get(), .events = POLLIN},
+ };
+
+ {
+ std::lock_guard<std::mutex> lock(this->write_mutex_);
+ if (!writable_) {
+ pfds[0].events |= POLLOUT;
+ }
+ }
+
+ int rc = adb_poll(pfds, 2, -1);
+ if (rc == -1) {
+ *error = android::base::StringPrintf("poll failed: %s", strerror(errno));
+ return;
+ } else if (rc == 0) {
+ LOG(FATAL) << "poll timed out with an infinite timeout?";
+ }
+
+ if (pfds[0].revents) {
+ if ((pfds[0].revents & POLLOUT)) {
+ std::lock_guard<std::mutex> lock(this->write_mutex_);
+ WriteResult result = DispatchWrites();
+ switch (result) {
+ case WriteResult::Error:
+ *error = "write failed";
+ return;
+
+ case WriteResult::Completed:
+ writable_ = true;
+ break;
+
+ case WriteResult::TryAgain:
+ break;
+ }
+ }
+
+ if (pfds[0].revents & POLLIN) {
+ // TODO: Should we be getting blocks from a free list?
+ auto block = std::make_unique<IOVector::block_type>(MAX_PAYLOAD);
+ rc = adb_read(fd_.get(), &(*block)[0], block->size());
+ if (rc == -1) {
+ *error = std::string("read failed: ") + strerror(errno);
+ return;
+ } else if (rc == 0) {
+ *error = "read failed: EOF";
+ return;
+ }
+ block->resize(rc);
+ read_buffer_.append(std::move(block));
+
+ if (!read_header_ && read_buffer_.size() >= sizeof(amessage)) {
+ auto header_buf = read_buffer_.take_front(sizeof(amessage)).coalesce();
+ CHECK_EQ(sizeof(amessage), header_buf.size());
+ read_header_ = std::make_unique<amessage>();
+ memcpy(read_header_.get(), header_buf.data(), sizeof(amessage));
+ }
+
+ if (read_header_ && read_buffer_.size() >= read_header_->data_length) {
+ auto data_chain = read_buffer_.take_front(read_header_->data_length);
+
+ // TODO: Make apacket carry around a IOVector instead of coalescing.
+ auto payload = data_chain.coalesce<apacket::payload_type>();
+ auto packet = std::make_unique<apacket>();
+ packet->msg = *read_header_;
+ packet->payload = std::move(payload);
+ read_header_ = nullptr;
+ read_callback_(this, std::move(packet));
+ }
+ }
+ }
+
+ if (pfds[1].revents) {
+ uint64_t buf;
+ rc = adb_read(wake_fd_read_.get(), &buf, sizeof(buf));
+ CHECK_EQ(static_cast<int>(sizeof(buf)), rc);
+
+ // We were woken up either to add POLLOUT to our events, or to exit.
+ // Do nothing.
+ }
+ }
+ }
+
+ void Start() override final {
+ if (started_.exchange(true)) {
+ LOG(FATAL) << "Connection started multiple times?";
+ }
+
+ thread_ = std::thread([this]() {
+ std::string error = "connection closed";
+ Run(&error);
+ this->error_callback_(this, error);
+ });
+ }
+
+ void Stop() override final {
+ SetRunning(false);
+ WakeThread();
+ thread_.join();
+ }
+
+ void WakeThread() {
+ uint64_t buf = 0;
+ if (TEMP_FAILURE_RETRY(adb_write(wake_fd_write_.get(), &buf, sizeof(buf))) != sizeof(buf)) {
+ LOG(FATAL) << "failed to wake up thread";
+ }
+ }
+
+ enum class WriteResult {
+ Error,
+ Completed,
+ TryAgain,
+ };
+
+ WriteResult DispatchWrites() REQUIRES(write_mutex_) {
+ CHECK(!write_buffer_.empty());
+ if (!writable_) {
+ return WriteResult::TryAgain;
+ }
+
+ auto iovs = write_buffer_.iovecs();
+ ssize_t rc = adb_writev(fd_.get(), iovs.data(), iovs.size());
+ if (rc == -1) {
+ return WriteResult::Error;
+ } else if (rc == 0) {
+ errno = 0;
+ return WriteResult::Error;
+ }
+
+ // TODO: Implement a more efficient drop_front?
+ write_buffer_.take_front(rc);
+ if (write_buffer_.empty()) {
+ return WriteResult::Completed;
+ }
+
+ // There's data left in the range, which means our write returned early.
+ return WriteResult::TryAgain;
+ }
+
+ bool Write(std::unique_ptr<apacket> packet) final {
+ std::lock_guard<std::mutex> lock(write_mutex_);
+ const char* header_begin = reinterpret_cast<const char*>(&packet->msg);
+ const char* header_end = header_begin + sizeof(packet->msg);
+ auto header_block = std::make_unique<IOVector::block_type>(header_begin, header_end);
+ write_buffer_.append(std::move(header_block));
+ if (!packet->payload.empty()) {
+ write_buffer_.append(std::make_unique<IOVector::block_type>(std::move(packet->payload)));
+ }
+ return DispatchWrites() != WriteResult::Error;
+ }
+
+ std::thread thread_;
+
+ std::atomic<bool> started_;
+ std::mutex run_mutex_;
+ bool running_ GUARDED_BY(run_mutex_);
+
+ std::unique_ptr<amessage> read_header_;
+ IOVector read_buffer_;
+
+ unique_fd fd_;
+ unique_fd wake_fd_read_;
+ unique_fd wake_fd_write_;
+
+ std::mutex write_mutex_;
+ bool writable_ GUARDED_BY(write_mutex_) = true;
+ IOVector write_buffer_ GUARDED_BY(write_mutex_);
+
+ IOVector incoming_queue_;
+};
+
+std::unique_ptr<Connection> Connection::FromFd(unique_fd fd) {
+ return std::make_unique<NonblockingFdConnection>(std::move(fd));
+}
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index d7bc6b5..0ca8938 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -19,6 +19,9 @@
host_supported: true,
recovery_available: true,
defaults: ["fs_mgr_defaults"],
+ cppflags: [
+ "-D_FILE_OFFSET_BITS=64",
+ ],
srcs: [
"builder.cpp",
"reader.cpp",
@@ -33,6 +36,9 @@
],
whole_static_libs: [
"libext2_uuid",
+ "libext4_utils",
+ "libsparse",
+ "libz",
],
export_include_dirs: ["include"],
}
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index bfbf3e5..a084893 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -20,7 +20,6 @@
#include <algorithm>
-#include <android-base/endian.h>
#include <uuid/uuid.h>
#include "liblp/metadata_format.h"
diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp
index 1b70da9..328fe37 100644
--- a/fs_mgr/liblp/reader.cpp
+++ b/fs_mgr/liblp/reader.cpp
@@ -63,7 +63,7 @@
}
// Check that the metadata area and logical partition areas don't overlap.
- off64_t end_of_metadata =
+ int64_t end_of_metadata =
GetPrimaryMetadataOffset(*geometry, geometry->metadata_slot_count - 1) +
geometry->metadata_max_size;
if (uint64_t(end_of_metadata) > geometry->first_logical_sector * LP_SECTOR_SIZE) {
@@ -79,8 +79,8 @@
static bool ReadLogicalPartitionGeometry(int fd, LpMetadataGeometry* geometry) {
// Read the first 4096 bytes.
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(LP_METADATA_GEOMETRY_SIZE);
- if (lseek64(fd, 0, SEEK_SET) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed";
+ if (SeekFile64(fd, 0, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed";
return false;
}
if (!android::base::ReadFully(fd, buffer.get(), LP_METADATA_GEOMETRY_SIZE)) {
@@ -92,8 +92,8 @@
}
// Try the backup copy in the last 4096 bytes.
- if (lseek64(fd, -LP_METADATA_GEOMETRY_SIZE, SEEK_END) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed, offset " << -LP_METADATA_GEOMETRY_SIZE;
+ if (SeekFile64(fd, -LP_METADATA_GEOMETRY_SIZE, SEEK_END) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed, offset " << -LP_METADATA_GEOMETRY_SIZE;
return false;
}
if (!android::base::ReadFully(fd, buffer.get(), LP_METADATA_GEOMETRY_SIZE)) {
@@ -248,9 +248,9 @@
}
// First try the primary copy.
- off64_t offset = GetPrimaryMetadataOffset(geometry, slot_number);
- if (lseek64(fd, offset, SEEK_SET) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << offset;
+ int64_t offset = GetPrimaryMetadataOffset(geometry, slot_number);
+ if (SeekFile64(fd, offset, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
return nullptr;
}
if (std::unique_ptr<LpMetadata> metadata = ParseMetadata(fd)) {
@@ -259,8 +259,8 @@
// Next try the backup copy.
offset = GetBackupMetadataOffset(geometry, slot_number);
- if (lseek64(fd, offset, SEEK_END) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << offset;
+ if (SeekFile64(fd, offset, SEEK_END) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
return nullptr;
}
return ParseMetadata(fd);
@@ -277,8 +277,8 @@
if (!ReadLogicalPartitionGeometry(fd, &geometry)) {
return nullptr;
}
- if (lseek64(fd, LP_METADATA_GEOMETRY_SIZE, SEEK_SET) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << LP_METADATA_GEOMETRY_SIZE;
+ if (SeekFile64(fd, LP_METADATA_GEOMETRY_SIZE, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << LP_METADATA_GEOMETRY_SIZE;
return nullptr;
}
std::unique_ptr<LpMetadata> metadata = ParseMetadata(fd);
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index c4b7028..958700b 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -15,13 +15,13 @@
*/
#include <fcntl.h>
-#include <linux/fs.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <android-base/file.h>
+#include <ext4_utils/ext4_utils.h>
#include <openssl/sha.h>
#include <uuid/uuid.h>
@@ -38,14 +38,12 @@
}
if (S_ISBLK(s.st_mode)) {
- if (ioctl(fd, BLKGETSIZE64, size) != -1) {
- return true;
- }
+ return get_block_device_size(fd);
}
- off64_t result = lseek64(fd, 0, SEEK_END);
- if (result == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed";
+ int64_t result = SeekFile64(fd, 0, SEEK_END);
+ if (result == -1) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed";
return false;
}
@@ -53,20 +51,25 @@
return true;
}
-off64_t GetPrimaryMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
+int64_t SeekFile64(int fd, int64_t offset, int whence) {
+ static_assert(sizeof(off_t) == sizeof(int64_t), "Need 64-bit lseek");
+ return lseek(fd, offset, whence);
+}
+
+int64_t GetPrimaryMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
CHECK(slot_number < geometry.metadata_slot_count);
- off64_t offset = LP_METADATA_GEOMETRY_SIZE + geometry.metadata_max_size * slot_number;
+ int64_t offset = LP_METADATA_GEOMETRY_SIZE + geometry.metadata_max_size * slot_number;
CHECK(offset + geometry.metadata_max_size <=
- off64_t(geometry.first_logical_sector * LP_SECTOR_SIZE));
+ int64_t(geometry.first_logical_sector * LP_SECTOR_SIZE));
return offset;
}
-off64_t GetBackupMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
+int64_t GetBackupMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
CHECK(slot_number < geometry.metadata_slot_count);
- off64_t start = off64_t(-LP_METADATA_GEOMETRY_SIZE) -
- off64_t(geometry.metadata_max_size) * geometry.metadata_slot_count;
- return start + off64_t(geometry.metadata_max_size * slot_number);
+ int64_t start = int64_t(-LP_METADATA_GEOMETRY_SIZE) -
+ int64_t(geometry.metadata_max_size) * geometry.metadata_slot_count;
+ return start + int64_t(geometry.metadata_max_size * slot_number);
}
void SHA256(const void* data, size_t length, uint8_t out[32]) {
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index dc559ed..09ed314 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -38,11 +38,14 @@
// Return the offset of a primary metadata slot, relative to the start of the
// device.
-off64_t GetPrimaryMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number);
+int64_t GetPrimaryMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number);
// Return the offset of a backup metadata slot, relative to the end of the
// device.
-off64_t GetBackupMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number);
+int64_t GetBackupMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number);
+
+// Cross-platform helper for lseek64().
+int64_t SeekFile64(int fd, int64_t offset, int whence);
// Compute a SHA256 hash.
void SHA256(const void* data, size_t length, uint8_t out[32]);
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index aab244a..6a9c124 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -169,8 +169,8 @@
// the first and last 4096-byte regions of the device.
if (sync_mode == SyncMode::Flash) {
std::string blob = SerializeGeometry(metadata.geometry);
- if (lseek64(fd, 0, SEEK_SET) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset 0";
+ if (SeekFile64(fd, 0, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset 0";
return false;
}
if (!android::base::WriteFully(fd, blob.data(), blob.size())) {
@@ -178,8 +178,8 @@
<< " bytes failed: " << block_device;
return false;
}
- if (lseek64(fd, -LP_METADATA_GEOMETRY_SIZE, SEEK_END) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << -LP_METADATA_GEOMETRY_SIZE;
+ if (SeekFile64(fd, -LP_METADATA_GEOMETRY_SIZE, SEEK_END) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << -LP_METADATA_GEOMETRY_SIZE;
return false;
}
if (!android::base::WriteFully(fd, blob.data(), blob.size())) {
@@ -190,9 +190,9 @@
}
// Write the primary copy of the metadata.
- off64_t primary_offset = GetPrimaryMetadataOffset(geometry, slot_number);
- if (lseek64(fd, primary_offset, SEEK_SET) == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << primary_offset;
+ int64_t primary_offset = GetPrimaryMetadataOffset(geometry, slot_number);
+ if (SeekFile64(fd, primary_offset, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << primary_offset;
return false;
}
if (!android::base::WriteFully(fd, blob.data(), blob.size())) {
@@ -202,13 +202,13 @@
}
// Write the backup copy of the metadata.
- off64_t backup_offset = GetBackupMetadataOffset(geometry, slot_number);
- off64_t abs_offset = lseek64(fd, backup_offset, SEEK_END);
- if (abs_offset == (off64_t)-1) {
- PERROR << __PRETTY_FUNCTION__ << "lseek64 failed: offset " << backup_offset;
+ int64_t backup_offset = GetBackupMetadataOffset(geometry, slot_number);
+ int64_t abs_offset = SeekFile64(fd, backup_offset, SEEK_END);
+ if (abs_offset == (int64_t)-1) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << backup_offset;
return false;
}
- if (abs_offset < off64_t((geometry.last_logical_sector + 1) * LP_SECTOR_SIZE)) {
+ if (abs_offset < int64_t((geometry.last_logical_sector + 1) * LP_SECTOR_SIZE)) {
PERROR << __PRETTY_FUNCTION__ << "backup offset " << abs_offset
<< " is within logical partition bounds, sector " << geometry.last_logical_sector;
return false;
diff --git a/init/Android.bp b/init/Android.bp
index 7d863c8..cf7637f 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -76,7 +76,6 @@
"libprotobuf-cpp-lite",
"libpropertyinfoserializer",
"libpropertyinfoparser",
- "libselinux",
],
shared_libs: [
"libcutils",
@@ -87,6 +86,7 @@
"libc++",
"libdl",
"libz",
+ "libselinux",
],
}
diff --git a/init/Android.mk b/init/Android.mk
index da27a73..a81a0f6 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -61,7 +61,6 @@
libseccomp_policy \
libcrypto_utils \
libsparse \
- libselinux \
libprocessgroup \
libavb \
libkeyutils \
@@ -76,6 +75,7 @@
libcrypto \
libdl \
libz \
+ libselinux \
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
# init is static executable for non-system-as-root devices, because the dynamic linker
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 70b6a3e..478b8d0 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -201,6 +201,7 @@
$$(hide) sed -i -e 's?%VNDK_CORE_LIBRARIES%?$$(PRIVATE_VNDK_CORE_LIBRARIES)?g' $$@
$$(hide) sed -i -e 's?%SANITIZER_RUNTIME_LIBRARIES%?$$(PRIVATE_SANITIZER_RUNTIME_LIBRARIES)?g' $$@
$$(hide) sed -i -e 's?%VNDK_VER%?$$(PRIVATE_VNDK_VERSION)?g' $$@
+ $$(hide) sed -i -e 's?%PRODUCT%?$$(TARGET_COPY_OUT_PRODUCT)?g' $$@
llndk_libraries_list :=
vndksp_libraries_list :=
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index eebad2b..42dc7ab 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -7,7 +7,7 @@
# absolute path of an executable is selected.
dir.system = /system/bin/
dir.system = /system/xbin/
-dir.system = /product/bin/
+dir.system = /%PRODUCT%/bin/
dir.vendor = /odm/bin/
dir.vendor = /vendor/bin/
@@ -39,7 +39,7 @@
namespace.default.isolated = true
namespace.default.search.paths = /system/${LIB}
-namespace.default.search.paths += /product/${LIB}
+namespace.default.search.paths += /%PRODUCT%/${LIB}
# We can't have entire /system/${LIB} as permitted paths because doing so
# makes it possible to load libs in /system/${LIB}/vndk* directories by
@@ -51,8 +51,7 @@
namespace.default.permitted.paths = /system/${LIB}/drm
namespace.default.permitted.paths += /system/${LIB}/extractors
namespace.default.permitted.paths += /system/${LIB}/hw
-namespace.default.permitted.paths += /product/${LIB}
-namespace.default.permitted.paths += /system/product/${LIB}
+namespace.default.permitted.paths += /%PRODUCT%/${LIB}
# These are where odex files are located. libart has to be able to dlopen the files
namespace.default.permitted.paths += /system/framework
namespace.default.permitted.paths += /system/app
@@ -64,12 +63,9 @@
namespace.default.permitted.paths += /odm/app
namespace.default.permitted.paths += /odm/priv-app
namespace.default.permitted.paths += /oem/app
-namespace.default.permitted.paths += /product/framework
-namespace.default.permitted.paths += /product/app
-namespace.default.permitted.paths += /product/priv-app
-namespace.default.permitted.paths += /system/product/framework
-namespace.default.permitted.paths += /system/product/app
-namespace.default.permitted.paths += /system/product/priv-app
+namespace.default.permitted.paths += /%PRODUCT%/framework
+namespace.default.permitted.paths += /%PRODUCT%/app
+namespace.default.permitted.paths += /%PRODUCT%/priv-app
namespace.default.permitted.paths += /data
namespace.default.permitted.paths += /mnt/expand
@@ -92,14 +88,10 @@
namespace.default.asan.permitted.paths += /odm/app
namespace.default.asan.permitted.paths += /odm/priv-app
namespace.default.asan.permitted.paths += /oem/app
-namespace.default.asan.permitted.paths += /product/${LIB}
-namespace.default.asan.permitted.paths += /product/framework
-namespace.default.asan.permitted.paths += /product/app
-namespace.default.asan.permitted.paths += /product/priv-app
-namespace.default.asan.permitted.paths += /system/product/${LIB}
-namespace.default.asan.permitted.paths += /system/product/framework
-namespace.default.asan.permitted.paths += /system/product/app
-namespace.default.asan.permitted.paths += /system/product/priv-app
+namespace.default.asan.permitted.paths += /%PRODUCT%/${LIB}
+namespace.default.asan.permitted.paths += /%PRODUCT%/framework
+namespace.default.asan.permitted.paths += /%PRODUCT%/app
+namespace.default.asan.permitted.paths += /%PRODUCT%/priv-app
namespace.default.asan.permitted.paths += /mnt/expand
###############################################################################
@@ -335,7 +327,7 @@
namespace.system.isolated = false
namespace.system.search.paths = /system/${LIB}
-namespace.system.search.paths += /product/${LIB}
+namespace.system.search.paths += /%PRODUCT%/${LIB}
namespace.system.asan.search.paths = /data/asan/system/${LIB}
namespace.system.asan.search.paths += /system/${LIB}
@@ -353,4 +345,4 @@
[postinstall]
namespace.default.isolated = false
namespace.default.search.paths = /system/${LIB}
-namespace.default.search.paths += /product/${LIB}
+namespace.default.search.paths += /%PRODUCT%/${LIB}