Merge "liblog: remove LOGGER_LOCAL"
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 4e6c879..c8d12cf 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -103,7 +103,7 @@
   void reset(int new_value = -1) { reset(new_value, nullptr); }
 
   int get() const { return fd_; }
-  operator int() const { return get(); }
+  operator int() const { return get(); }  // NOLINT
 
   int release() __attribute__((warn_unused_result)) {
     tag(fd_, this, nullptr);
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 943fe10..9f6c550 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -523,13 +523,13 @@
 }
 
 // Mark the given block device as read-only, using the BLKROSET ioctl.
-bool fs_mgr_set_blk_ro(const std::string& blockdev) {
+bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly) {
     unique_fd fd(TEMP_FAILURE_RETRY(open(blockdev.c_str(), O_RDONLY | O_CLOEXEC)));
     if (fd < 0) {
         return false;
     }
 
-    int ON = 1;
+    int ON = readonly;
     return ioctl(fd, BLKROSET, &ON) == 0;
 }
 
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 7dae7f1..6364ca9 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -277,6 +277,9 @@
     // Don't check entries that are managed by vold.
     if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false;
 
+    // *_other doesn't want overlayfs.
+    if (entry->fs_mgr_flags.slot_select_other) return false;
+
     // Only concerned with readonly partitions.
     if (!(entry->flags & MS_RDONLY)) return false;
 
@@ -595,7 +598,11 @@
     entry.mount_point = kScratchMountPoint;
     entry.fs_type = mnt_type;
     entry.flags = MS_RELATIME;
-    if (readonly) entry.flags |= MS_RDONLY;
+    if (readonly) {
+        entry.flags |= MS_RDONLY;
+    } else {
+        fs_mgr_set_blk_ro(device_path, false);
+    }
     auto save_errno = errno;
     auto mounted = fs_mgr_do_mount_one(entry) == 0;
     if (!mounted) {
@@ -653,6 +660,7 @@
         return false;
     }
     command += " " + scratch_device;
+    fs_mgr_set_blk_ro(scratch_device, false);
     auto ret = system(command.c_str());
     if (ret) {
         LERROR << "make " << mnt_type << " filesystem on " << scratch_device << " return=" << ret;
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 7d1159b..7842ca2 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -134,7 +134,7 @@
                           const std::chrono::milliseconds relative_timeout,
                           FileWaitMode wait_mode = FileWaitMode::Exists);
 
-bool fs_mgr_set_blk_ro(const std::string& blockdev);
+bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly = true);
 bool fs_mgr_update_for_slotselect(Fstab* fstab);
 bool fs_mgr_is_device_unlocked();
 const std::string& get_android_dt_dir();
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index 9ccabe9..ecf94a4 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -19,6 +19,11 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#if defined(__linux__)
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+#endif
+
 #include <android-base/file.h>
 #include <ext4_utils/ext4_utils.h>
 #include <openssl/sha.h>
@@ -155,5 +160,16 @@
     return true;
 }
 
+bool SetBlockReadonly(int fd, bool readonly) {
+#if defined(__linux__)
+    int val = readonly;
+    return ioctl(fd, BLKROSET, &val) == 0;
+#else
+    (void)fd;
+    (void)readonly;
+    return true;
+#endif
+}
+
 }  // namespace fs_mgr
 }  // namespace android
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index 8b70919..e8b2ca9 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -29,6 +29,7 @@
 #define LWARN LOG(WARNING) << LP_TAG
 #define LINFO LOG(INFO) << LP_TAG
 #define LERROR LOG(ERROR) << LP_TAG
+#define PWARNING PLOG(WARNING) << LP_TAG
 #define PERROR PLOG(ERROR) << LP_TAG
 
 namespace android {
@@ -88,6 +89,9 @@
 bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::string& name);
 bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name);
 
+// Call BLKROSET ioctl on fd so that fd is readonly / read-writable.
+bool SetBlockReadonly(int fd, bool readonly);
+
 }  // namespace fs_mgr
 }  // namespace android
 
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index 454258b..54a1883 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -259,6 +259,12 @@
         return false;
     }
 
+    // On retrofit devices, super_partition is system_other and might be set to readonly by
+    // fs_mgr_set_blk_ro(). Unset readonly so that fd can be written to.
+    if (!SetBlockReadonly(fd.get(), false)) {
+        PWARNING << __PRETTY_FUNCTION__ << " BLKROSET 0 failed: " << super_partition;
+    }
+
     // Write zeroes to the first block.
     std::string zeroes(LP_PARTITION_RESERVED_BYTES, 0);
     if (SeekFile64(fd, 0, SEEK_SET) < 0) {
diff --git a/init/main.cpp b/init/main.cpp
index 868c409..2ce46ef 100644
--- a/init/main.cpp
+++ b/init/main.cpp
@@ -57,27 +57,22 @@
         return ueventd_main(argc, argv);
     }
 
-    if (argc < 2) {
-        return FirstStageMain(argc, argv);
+    if (argc > 1) {
+        if (!strcmp(argv[1], "subcontext")) {
+            android::base::InitLogging(argv, &android::base::KernelLogger);
+            const BuiltinFunctionMap function_map;
+
+            return SubcontextMain(argc, argv, &function_map);
+        }
+
+        if (!strcmp(argv[1], "selinux_setup")) {
+            return SetupSelinux(argv);
+        }
+
+        if (!strcmp(argv[1], "second_stage")) {
+            return SecondStageMain(argc, argv);
+        }
     }
 
-    if (!strcmp(argv[1], "subcontext")) {
-        android::base::InitLogging(argv, &android::base::KernelLogger);
-        const BuiltinFunctionMap function_map;
-
-        return SubcontextMain(argc, argv, &function_map);
-    }
-
-    if (!strcmp(argv[1], "selinux_setup")) {
-        return SetupSelinux(argv);
-    }
-
-    if (!strcmp(argv[1], "second_stage")) {
-        return SecondStageMain(argc, argv);
-    }
-
-    android::base::InitLogging(argv, &android::base::KernelLogger);
-
-    LOG(ERROR) << "Unknown argument passed to init '" << argv[1] << "'";
-    return 1;
+    return FirstStageMain(argc, argv);
 }