From 376e3cbb50fdf1a423e0aa0c7cba4f87c9b30813 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Thu, 30 Aug 2018 15:20:43 -0700 Subject: [PATCH] adb: identical symlink, do not update Inefficient to always update the symlinks to overlayfs, can also lead to failed to copy 'xxx' to 'yyy': remote symlink failed: File exists on older variants of overlayfs that do not effectively mark them deleted. Test: manual Bug: 109821005 Change-Id: If1286d76f45ce14087cdb515fe8d2fed198fd9d8 --- adb/daemon/file_sync_service.cpp | 36 +++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp index 8c39a20fa..d55096aa8 100644 --- a/adb/daemon/file_sync_service.cpp +++ b/adb/daemon/file_sync_service.cpp @@ -32,6 +32,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -47,6 +51,7 @@ #include "security_log_tags.h" #include "sysdeps/errno.h" +using android::base::Dirname; using android::base::StringPrintf; static bool should_use_fs_config(const std::string& path) { @@ -219,7 +224,7 @@ static bool handle_send_file(int s, const char* path, uid_t uid, gid_t gid, uint } if (fd < 0 && errno == ENOENT) { - if (!secure_mkdirs(android::base::Dirname(path))) { + if (!secure_mkdirs(Dirname(path))) { SendSyncFailErrno(s, "secure_mkdirs failed"); goto fail; } @@ -327,8 +332,6 @@ extern bool handle_send_link(int s, const std::string& path, std::vector& #else static bool handle_send_link(int s, const std::string& path, std::vector& buffer) { syncmsg msg; - unsigned int len; - int ret; if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false; @@ -337,24 +340,28 @@ static bool handle_send_link(int s, const std::string& path, std::vector& return false; } - len = msg.data.size; + unsigned int len = msg.data.size; if (len > buffer.size()) { // TODO: resize buffer? SendSyncFail(s, "oversize data message"); return false; } if (!ReadFdExactly(s, &buffer[0], len)) return false; - ret = symlink(&buffer[0], path.c_str()); - if (ret && errno == ENOENT) { - if (!secure_mkdirs(android::base::Dirname(path))) { - SendSyncFailErrno(s, "secure_mkdirs failed"); + std::string buf_link; + if (!android::base::Readlink(path, &buf_link) || (buf_link != &buffer[0])) { + adb_unlink(path.c_str()); + auto ret = symlink(&buffer[0], path.c_str()); + if (ret && errno == ENOENT) { + if (!secure_mkdirs(Dirname(path))) { + SendSyncFailErrno(s, "secure_mkdirs failed"); + return false; + } + ret = symlink(&buffer[0], path.c_str()); + } + if (ret) { + SendSyncFailErrno(s, "symlink failed"); return false; } - ret = symlink(&buffer[0], path.c_str()); - } - if (ret) { - SendSyncFailErrno(s, "symlink failed"); - return false; } if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) return false; @@ -391,7 +398,8 @@ static bool do_send(int s, const std::string& spec, std::vector& buffer) { // Don't delete files before copying if they are not "regular" or symlinks. struct stat st; - bool do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode); + bool do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) || + (S_ISLNK(st.st_mode) && !S_ISLNK(mode)); if (do_unlink) { adb_unlink(path.c_str()); }