summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/daemon/remount_service.cpp60
1 files changed, 51 insertions, 9 deletions
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index d679a6dff..7876368a2 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -25,14 +25,18 @@
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <sys/mount.h> 27#include <sys/mount.h>
28#include <sys/vfs.h>
28#include <unistd.h> 29#include <unistd.h>
29 30
30#include <string> 31#include <string>
32#include <vector>
31 33
32#include <android-base/properties.h> 34#include <android-base/properties.h>
35#include <ext4_utils/ext4_utils.h>
33 36
34#include "adb.h" 37#include "adb.h"
35#include "adb_io.h" 38#include "adb_io.h"
39#include "adb_unique_fd.h"
36#include "adb_utils.h" 40#include "adb_utils.h"
37#include "fs_mgr.h" 41#include "fs_mgr.h"
38 42
@@ -82,7 +86,27 @@ bool make_block_device_writable(const std::string& dev) {
82 return result; 86 return result;
83} 87}
84 88
85static bool remount_partition(int fd, const char* dir) { 89static bool fs_has_shared_blocks(const char* dev) {
90 struct statfs fs;
91 if (statfs(dev, &fs) == -1 || fs.f_type == EXT4_SUPER_MAGIC) {
92 return false;
93 }
94 unique_fd fd(unix_open(dev, O_RDONLY));
95 if (fd < 0) {
96 return false;
97 }
98 struct ext4_super_block sb;
99 if (lseek64(fd, 1024, SEEK_SET) < 0 || unix_read(fd, &sb, sizeof(sb)) < 0) {
100 return false;
101 }
102 struct fs_info info;
103 if (ext4_parse_sb(&sb, &info) < 0) {
104 return false;
105 }
106 return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
107}
108
109static bool remount_partition(int fd, const char* dir, std::vector<std::string>& dedup) {
86 if (!directory_exists(dir)) { 110 if (!directory_exists(dir)) {
87 return true; 111 return true;
88 } 112 }
@@ -108,6 +132,12 @@ static bool remount_partition(int fd, const char* dir) {
108 return false; 132 return false;
109 } 133 }
110 if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) { 134 if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
135 if (errno == EROFS && fs_has_shared_blocks(dev.c_str())) {
136 // We return true so remount_service() can detect that the only
137 // failure was deduplicated filesystems.
138 dedup.push_back(dev);
139 return true;
140 }
111 WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno)); 141 WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
112 return false; 142 return false;
113 } 143 }
@@ -140,17 +170,29 @@ void remount_service(int fd, void* cookie) {
140 } 170 }
141 171
142 bool success = true; 172 bool success = true;
173 std::vector<std::string> dedup;
143 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) { 174 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
144 success &= remount_partition(fd, "/"); 175 success &= remount_partition(fd, "/", dedup);
145 } else { 176 } else {
146 success &= remount_partition(fd, "/system"); 177 success &= remount_partition(fd, "/system", dedup);
178 }
179 success &= remount_partition(fd, "/odm", dedup);
180 success &= remount_partition(fd, "/oem", dedup);
181 success &= remount_partition(fd, "/product", dedup);
182 success &= remount_partition(fd, "/vendor", dedup);
183
184 if (!success) {
185 WriteFdExactly(fd, "remount failed\n");
186 } else if (dedup.empty()) {
187 WriteFdExactly(fd, "remount succeeded\n");
188 } else {
189 WriteFdExactly(fd,
190 "The following partitions are deduplicated and could "
191 "not be remounted:\n");
192 for (const std::string& name : dedup) {
193 WriteFdFmt(fd, " %s\n", name.c_str());
194 }
147 } 195 }
148 success &= remount_partition(fd, "/odm");
149 success &= remount_partition(fd, "/oem");
150 success &= remount_partition(fd, "/product");
151 success &= remount_partition(fd, "/vendor");
152
153 WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
154 196
155 adb_close(fd); 197 adb_close(fd);
156} 198}