Merge "libsnapshot: compile tests for both 32 and 64 bit" into main
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 43be098..77ab7d1 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -277,6 +277,10 @@
test_suites: [
"vts",
],
+ test_options: {
+ // VABC mandatory in Android T per VSR.
+ min_shipping_api_level: 32,
+ },
}
cc_binary_host {
diff --git a/fs_mgr/libsnapshot/snapuserd/dm_user_block_server.cpp b/fs_mgr/libsnapshot/snapuserd/dm_user_block_server.cpp
index e988335..4599ad3 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm_user_block_server.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm_user_block_server.cpp
@@ -27,11 +27,12 @@
DmUserBlockServer::DmUserBlockServer(const std::string& misc_name, unique_fd&& ctrl_fd,
Delegate* delegate, size_t buffer_size)
: misc_name_(misc_name), ctrl_fd_(std::move(ctrl_fd)), delegate_(delegate) {
- buffer_.Initialize(buffer_size);
+ buffer_.Initialize(sizeof(struct dm_user_header), buffer_size);
}
bool DmUserBlockServer::ProcessRequests() {
- struct dm_user_header* header = buffer_.GetHeaderPtr();
+ struct dm_user_header* header =
+ reinterpret_cast<struct dm_user_header*>(buffer_.GetHeaderPtr());
if (!android::base::ReadFully(ctrl_fd_, header, sizeof(*header))) {
if (errno != ENOTBLK) {
SNAP_PLOG(ERROR) << "Control-read failed";
@@ -90,7 +91,8 @@
}
void DmUserBlockServer::SendError() {
- struct dm_user_header* header = buffer_.GetHeaderPtr();
+ struct dm_user_header* header =
+ reinterpret_cast<struct dm_user_header*>(buffer_.GetHeaderPtr());
header->type = DM_USER_RESP_ERROR;
// This is an issue with the dm-user interface. There
// is no way to propagate the I/O error back to dm-user
diff --git a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/dm_user_block_server.h b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/dm_user_block_server.h
index f1f8da1..35c6bfb 100644
--- a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/dm_user_block_server.h
+++ b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/dm_user_block_server.h
@@ -20,6 +20,7 @@
#include <snapuserd/block_server.h>
#include <snapuserd/snapuserd_buffer.h>
+#include <snapuserd/snapuserd_kernel.h>
namespace android {
namespace snapshot {
diff --git a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_buffer.h b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_buffer.h
index c5ca2b1..cc7c48c 100644
--- a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_buffer.h
+++ b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_buffer.h
@@ -27,13 +27,17 @@
class BufferSink final {
public:
- void Initialize(size_t size);
+ // Do not reserve any space of header by default
+ void Initialize(size_t size) { return Initialize(0, size); };
+ // This allows to set const header_size_ to be used if caller needs it
+ // for example, while working with dm_user
+ void Initialize(size_t header_size, size_t size);
void* GetBufPtr() { return buffer_.get(); }
void Clear() { memset(GetBufPtr(), 0, buffer_size_); }
void* GetPayloadBuffer(size_t size);
void* GetBuffer(size_t requested, size_t* actual);
void UpdateBufferOffset(size_t size) { buffer_offset_ += size; }
- struct dm_user_header* GetHeaderPtr();
+ void* GetHeaderPtr();
void ResetBufferOffset() { buffer_offset_ = 0; }
void* GetPayloadBufPtr();
loff_t GetPayloadBytesWritten() { return buffer_offset_; }
@@ -56,6 +60,7 @@
std::unique_ptr<uint8_t[]> buffer_;
loff_t buffer_offset_;
size_t buffer_size_;
+ size_t header_size_;
};
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_kernel.h b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_kernel.h
index 7ab75dc..14291b2 100644
--- a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_kernel.h
+++ b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_kernel.h
@@ -92,15 +92,5 @@
__u64 len;
} __attribute__((packed));
-struct dm_user_payload {
- __u8 buf[];
-};
-
-// Message comprising both header and payload
-struct dm_user_message {
- struct dm_user_header header;
- struct dm_user_payload payload;
-};
-
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd_buffer.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd_buffer.cpp
index 490c0e6..51b2490 100644
--- a/fs_mgr/libsnapshot/snapuserd/snapuserd_buffer.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/snapuserd_buffer.cpp
@@ -22,8 +22,9 @@
namespace android {
namespace snapshot {
-void BufferSink::Initialize(size_t size) {
- buffer_size_ = size + sizeof(struct dm_user_header);
+void BufferSink::Initialize(size_t header_size, size_t size) {
+ header_size_ = header_size;
+ buffer_size_ = size + header_size;
buffer_offset_ = 0;
buffer_ = std::make_unique<uint8_t[]>(buffer_size_);
}
@@ -41,11 +42,11 @@
void* BufferSink::GetPayloadBuffer(size_t size) {
char* buffer = reinterpret_cast<char*>(GetBufPtr());
- struct dm_user_message* msg = (struct dm_user_message*)(&(buffer[0]));
- if ((buffer_size_ - buffer_offset_ - sizeof(msg->header)) < size) {
+
+ if ((buffer_size_ - buffer_offset_ - header_size_) < size) {
return nullptr;
}
- return (char*)msg->payload.buf + buffer_offset_;
+ return (char*)(&buffer[0] + header_size_ + buffer_offset_);
}
void* BufferSink::GetBuffer(size_t requested, size_t* actual) {
@@ -58,19 +59,18 @@
return buf;
}
-struct dm_user_header* BufferSink::GetHeaderPtr() {
- if (!(sizeof(struct dm_user_header) <= buffer_size_)) {
+void* BufferSink::GetHeaderPtr() {
+ // If no sufficient space or header not reserved
+ if (!(header_size_ <= buffer_size_) || !header_size_) {
return nullptr;
}
char* buf = reinterpret_cast<char*>(GetBufPtr());
- struct dm_user_header* header = (struct dm_user_header*)(&(buf[0]));
- return header;
+ return (void*)(&(buf[0]));
}
void* BufferSink::GetPayloadBufPtr() {
char* buffer = reinterpret_cast<char*>(GetBufPtr());
- struct dm_user_message* msg = reinterpret_cast<struct dm_user_message*>(&(buffer[0]));
- return msg->payload.buf;
+ return &buffer[header_size_];
}
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
index 9042f2b..4dfb9bf 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
@@ -1530,6 +1530,14 @@
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
+#ifdef __ANDROID__
+ if (!android::snapshot::CanUseUserspaceSnapshots() ||
+ android::snapshot::IsVendorFromAndroid12()) {
+ std::cerr << "snapuserd_test not supported on this device\n";
+ return 0;
+ }
+#endif
+
gflags::ParseCommandLineFlags(&argc, &argv, false);
return RUN_ALL_TESTS();
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.cpp b/fs_mgr/libsnapshot/snapuserd/utility.cpp
index 684ca3d..b44f5ab 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/utility.cpp
@@ -14,11 +14,14 @@
#include "utility.h"
+#include <android-base/properties.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <libdm/dm.h>
#include <processgroup/processgroup.h>
#include <private/android_filesystem_config.h>
@@ -27,6 +30,7 @@
namespace snapshot {
using android::base::unique_fd;
+using android::dm::DeviceMapper;
bool SetThreadPriority([[maybe_unused]] int priority) {
#ifdef __ANDROID__
@@ -61,5 +65,38 @@
return major > 5 || (major == 5 && minor >= 6);
}
+bool GetUserspaceSnapshotsEnabledProperty() {
+ return android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
+}
+
+bool KernelSupportsCompressedSnapshots() {
+ auto& dm = DeviceMapper::Instance();
+ return dm.GetTargetByName("user", nullptr);
+}
+
+bool IsVendorFromAndroid12() {
+ const std::string UNKNOWN = "unknown";
+ const std::string vendor_release =
+ android::base::GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
+
+ if (vendor_release.find("12") != std::string::npos) {
+ return true;
+ }
+ return false;
+}
+
+bool CanUseUserspaceSnapshots() {
+ if (!GetUserspaceSnapshotsEnabledProperty()) {
+ LOG(INFO) << "Virtual A/B - Userspace snapshots disabled";
+ return false;
+ }
+
+ if (!KernelSupportsCompressedSnapshots()) {
+ LOG(ERROR) << "Userspace snapshots requested, but no kernel support is available.";
+ return false;
+ }
+ return true;
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.h b/fs_mgr/libsnapshot/snapuserd/utility.h
index c3c3cba..50be418 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.h
+++ b/fs_mgr/libsnapshot/snapuserd/utility.h
@@ -24,5 +24,10 @@
bool SetProfiles(std::initializer_list<std::string_view> profiles);
bool KernelSupportsIoUring();
+bool GetUserspaceSnapshotsEnabledProperty();
+bool KernelSupportsCompressedSnapshots();
+bool CanUseUserspaceSnapshots();
+bool IsVendorFromAndroid12();
+
} // namespace snapshot
} // namespace android