Do not re-create symlink for app exec file 89/321489/2
authorSangyoon Jang <jeremy.jang@samsung.com>
Mon, 24 Mar 2025 04:39:59 +0000 (13:39 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Tue, 25 Mar 2025 08:19:15 +0000 (17:19 +0900)
In some case(OSU), re-creating symlink changes the original timestamp of
app exec file. This can lead to unintended degradation of performance.
(for example, re-setting smack labels)

Change-Id: I93388e7b9a152e939139bc286d1d23f7bcb5e732
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/wgt/step/filesystem/step_create_wgt_symbolic_link.cc

index b7041519b63a5cdd9c15d732166f4f271f510204..66cf14eaf9170d294953d370924f16ffff1718d1 100644 (file)
@@ -29,6 +29,30 @@ const char kWrtServiceLauncherBinaryPath[] = "/usr/bin/wrt-service-launcher";
 const char kWebWidgetRuntimeBinaryPath[] = "/usr/bin/web-widget-runtime";
 const char kWRTPath[] = "/usr/bin/wrt";
 
+bool CreateSymlinkIfNotExists(const fs::path& target, const fs::path& link) {
+  std::error_code ec;
+  bool exists = fs::exists(link, ec);
+  if (exists && !ec) {
+    // check if the symlink points to the correct target
+    exists = fs::is_symlink(link, ec) && fs::read_symlink(link, ec) == target;
+    if (ec)
+      LOG(WARNING) << "Failed to check symlink status: " << ec.message();
+  }
+
+  // symlink already exists with correct target
+  if (exists)
+    return true;
+
+  common_installer::RemoveAll(link);
+  fs::create_symlink(target, link, ec);
+  if (ec) {
+    LOG(ERROR) << "Failed to create symlink: " << ec.message();
+    return false;
+  }
+
+  return true;
+}
+
 }  // namespace
 
 namespace wgt {
@@ -42,7 +66,6 @@ bool StepCreateWgtSymbolicLink::CreateSymlinksForApps() {
     service_app_type[service_info.id()] = service_info.type();
   }
 
-  std::error_code error;
   for (application_x* app :
       GListRange<application_x*>(context_->manifest_data.get()->application)) {
     // filter out non-wgt apps as this step is run for hybrid backend too
@@ -54,22 +77,20 @@ bool StepCreateWgtSymbolicLink::CreateSymlinksForApps() {
       return false;
 
     exec_path /= fs::path(app->appid);
-    common_installer::RemoveAll(exec_path);
-
+    bool r;
     if (strcmp(app->component_type, "uiapp") == 0) {
-      fs::create_symlink(fs::path(kWRTPath), exec_path, error);
+      r = CreateSymlinkIfNotExists(fs::path(kWRTPath), exec_path);
     } else if (strcmp(app->component_type, "watchapp") == 0) {
-      fs::create_symlink(fs::path(kWRTPath), exec_path, error);
+      r = CreateSymlinkIfNotExists(fs::path(kWRTPath), exec_path);
     } else if (strcmp(app->component_type, "widgetapp") == 0) {
-      fs::create_symlink(kWebWidgetRuntimeBinaryPath, exec_path, error);
+      r = CreateSymlinkIfNotExists(kWebWidgetRuntimeBinaryPath, exec_path);
     } else if (service_app_type[app->appid] == "standalone") {
-      fs::create_symlink(kWrtServiceBinaryPath, exec_path, error);
+      r = CreateSymlinkIfNotExists(kWrtServiceBinaryPath, exec_path);
     } else {
-      fs::create_symlink(kWrtServiceLauncherBinaryPath, exec_path, error);
+      r = CreateSymlinkIfNotExists(kWrtServiceLauncherBinaryPath, exec_path);
     }
-    if (error) {
-      LOG(ERROR) << "Failed to set symbolic link "
-        << error.message();
+    if (!r) {
+      LOG(ERROR) << "Failed to set symbolic link";
       return false;
     }
   }