Remove --ni-ro-pkg / --ni-regen-all-ro-app options accepted/tizen/unified/20210623.125232 submit/tizen/20210623.065708
authorWoongsuk Cho <ws77.cho@samsung.com>
Mon, 21 Jun 2021 07:58:40 +0000 (16:58 +0900)
committer조웅석/Common Platform Lab(SR)/Principal Engineer/삼성전자 <ws77.cho@samsung.com>
Wed, 23 Jun 2021 06:55:32 +0000 (15:55 +0900)
When creating a target image or developing platform, "/usr/apps" which is the RO area, is mounted as RW.
In this case, if we perform AOTC for apps installed under /usr/apps,
NI files should be created under /usr/apps/, not "/opt/usr/dotnet".

So, combine options into one, and create NI files under /opt/usr/dotnet only if package directory is mounted as RO.

NativeLauncher/inc/ni_common.h
NativeLauncher/inc/utils.h
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/util/utils.cc
tests/TCs/6_TOOL/TOOL.py

index 944448a..7970963 100644 (file)
@@ -30,7 +30,7 @@
 #define NI_FLAGS_APPNI                  0x0002
 #define NI_FLAGS_COMPATIBILITY          0x0004
 #define NI_FLAGS_VERBOSE                0x0008
-#define NI_FLAGS_READONLY_APP           0x0010
+#define NI_FLAGS_APP_UNDER_RO_AREA      0x0010
 #define NI_FLAGS_INSTRUMENT             0x1000
 
 typedef std::function<void (std::string)> afterCreate;
index 983eca8..98e1da0 100644 (file)
@@ -114,11 +114,11 @@ std::string getMetadataValue(const std::string& pkgId, const std::string& key);
 std::string changeExtension(const std::string& path, const std::string& from, const std::string& to);
 
 /**
- * @brief check the package is 'readonly' or not
- * @param[in] package id
+ * @brief check the path is 'readonly' or not
+ * @param[in] path
  * @return bool package readonly value
  */
-bool isReadOnlyApp(const std::string& pkgId);
+bool isReadOnlyArea(const std::string& path);
 
 /**
  * @brief split path with ":" delimiter and put that in the vector
index 3269ee4..ffb52ca 100644 (file)
@@ -37,13 +37,12 @@ void DisplayUsage() {
                "       --ni-system               - Create NI under System DLLs\n"
                "       --ni-dll                  - Create NI for DLL\n"
                "       --ni-pkg                  - Create NI for package\n"
-               "       --ni-ro-pkg               - Create NI for read-only package\n"
+               "                                   (If package is installed under RO area, NI files are generated under RW area)\n"
                "       --ni-dir                  - Create NI for directory\n"
                "       --ni-reset-system         - Remove System NI files\n"
                "       --ni-reset-pkg            - Remove App NI files\n"
                "       --ni-reset-dir            - Remove NI for directory\n"
                "       --ni-regen-all-app        - Re-generate All App NI files\n"
-               "       --ni-regen-all-ro-app     - Re-generate All read-only type App NI files\n"
                "       --tac-regen-all           - Re-generate All TAC files\n"
                "       --tac-restore-db          - Restore TAC Database\n"
                "       --tac-disable-pkg         - Disable TAC for package\n"
@@ -171,36 +170,10 @@ int main(int argc, char* argv[])
                }
                while (it != args.end()) {
                        std::string pkg = std::string(*it);
-                       if (isReadOnlyApp(pkg)) {
-                               _SERR("Skip to generate app NI. Try to create NI for read-only package [%s]\n# dotnettool --ni-ro-pkg %s", pkg.c_str(), pkg.c_str());
-                       } else {
-                               // if there is AOTed dlls under package root, that is skiped.
-                               int ret = createNIUnderPkgRoot(pkg, flags);
-                               if (ret != NI_ERROR_NONE) {
-                                       _SERR("Failed to generate app NI [%s]", pkg.c_str());
-                                       break;
-                               }
-                       }
-                       it = args.erase(it);
-               }
-       }
-       //sh-3.2# dotnettool --ni-ro-pkg [pkgId] [pkgId] ...
-       else if (cmd == "--ni-ro-pkg") {
-               if (args.size() < 1) {
-                       _SERR("Package name is missing");
-               }
-               flags |= NI_FLAGS_READONLY_APP;
-               while (it != args.end()) {
-                       std::string pkg = std::string(*it);
-                       if (isReadOnlyApp(pkg)) {
-                               // if there is AOTed dlls under package root, that is skiped.
-                               int ret = createNIUnderPkgRoot(pkg, flags);
-                               if (ret != NI_ERROR_NONE) {
-                                       _SERR("Failed to generate read-only app NI [%s]", pkg.c_str());
-                                       break;
-                               }
-                       } else {
-                               _SERR("Skip to generate app NI. Try to create NI for package [%s]\n# dotnettool --ni-pkg %s", pkg.c_str(), pkg.c_str());
+                       int ret = createNIUnderPkgRoot(pkg, flags);
+                       if (ret != NI_ERROR_NONE) {
+                               _SERR("Failed to generate app NI [%s]", pkg.c_str());
+                               break;
                        }
                        it = args.erase(it);
                }
@@ -257,14 +230,6 @@ int main(int argc, char* argv[])
                        _SERR("Failed to regenerate all app NI");
                }
        }
-       //sh-3.2# dotnettool --ni-regen-readonly-app
-       else if (cmd == "--ni-regen-all-ro-app") {
-               flags |= NI_FLAGS_READONLY_APP;
-               int ret = regenerateAppNI(flags);
-               if (ret != NI_ERROR_NONE) {
-                       _SERR("Failed to regenerate read-only app NI");
-               }
-       }
        //sh-3.2# dotnettool --tac-regen-all
        else if (cmd == "--tac-regen-all") {
                int ret = regenerateTACNI(flags);
index f710ee8..73cf738 100644 (file)
@@ -148,8 +148,10 @@ static std::string getAppNIFilePath(const std::string& absDllPath, DWORD flags)
        prevPath = getBaseName(absDllPath);
        niDirPath = concatPath(prevPath, APP_NI_SUB_DIR);
 
-       if (flags & NI_FLAGS_READONLY_APP) {
+       if (flags & NI_FLAGS_APP_UNDER_RO_AREA) {
                niDirPath = replaceAll(niDirPath, getBaseName(__pm->getAppRootPath()), __READ_ONLY_APP_UPDATE_DIR);
+               _SERR("App is installed in RO area. So, create NI files in RW area(%s).", niDirPath.c_str());
+               _ERR("App is installed in RO area. So, create NI files in RW area(%s).", niDirPath.c_str());
        }
 
        if (!isDirectory(niDirPath)) {
@@ -427,25 +429,6 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
                return -1;
        }
 
-       bool readOnlyApp = isReadOnlyApp(pkgId);
-
-       // read-only and readonly flag set
-       if (readOnlyApp && (*pFlags & NI_FLAGS_READONLY_APP)) {
-               _SERR("try to regenerate read-only pkg [%s]", pkgId);
-       }
-       // not read-only and readonly flag does not set
-       else if (!readOnlyApp && !(*pFlags & NI_FLAGS_READONLY_APP)) {
-               if (removeNIUnderPkgRoot(pkgId) != NI_ERROR_NONE) {
-                       _SERR("Failed to remove previous dlls from [%s]", pkgId);
-                       return -1;
-               }
-       }
-       // skip regeneration
-       else {
-               _SERR("skip regeneration. pkg-type(read-only) doesnot match the configuration [%s]", pkgId);
-               return 0;
-       }
-
        if (createNIUnderPkgRoot(pkgId, *pFlags) != NI_ERROR_NONE) {
                _SERR("Failed to generate NI file [%s]", pkgId);
                return -1;
@@ -659,6 +642,17 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags)
 
        flags |= NI_FLAGS_APPNI;
 
+       if (isReadOnlyArea(rootPath)) {
+               flags |= NI_FLAGS_APP_UNDER_RO_AREA;
+       } else {
+               flags &= ~NI_FLAGS_APP_UNDER_RO_AREA;
+               ni_error_e err = removeNIUnderPkgRoot(pkgId);
+               if (err != NI_ERROR_NONE) {
+                       _SERR("Failed to remove previous dlls from [%s]", pkgId.c_str());
+                       return err;
+               }
+       }
+
        // create native image under bin and lib directory
        // tac directory is skipped in the createNIUnderDirs.
        return createNIUnderDirs(__pm->getAppPaths(), flags);
index 178741b..1f784ce 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/smack.h>
 #include <sys/prctl.h>
 #include <openssl/sha.h>
+#include <mntent.h>
 
 #include <cstdlib>
 #include <cstring>
@@ -236,37 +237,33 @@ std::string getMetadataValue(const std::string& pkgId, const std::string& key)
        return metadataValue;
 }
 
-bool isReadOnlyApp(const std::string& pkgId)
+bool isReadOnlyArea(const std::string& path)
 {
-       bool readOnly = false;
-       int ret = 0;
-       uid_t uid = 0;
+       FILE *f = NULL;
+       struct mntent *m = NULL;
 
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return readOnly;
-       }
-
-       pkgmgrinfo_pkginfo_h handle;
-       if (uid == 0) {
-               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
-       } else {
-               ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
+       // "/opt/usr" is mounted to "RW" only
+       if (path.find("/opt/usr") != std::string::npos) {
+               return false;
        }
 
-       if (ret != PMINFO_R_OK) {
-               return readOnly;
+       // check whether "/" is mounted to RO or not
+       f = setmntent("/proc/mounts", "r");
+       if (!f) {
+               // return true for fail case to generate NI files under RW area.
+               return true;
        }
 
-       ret = pkgmgrinfo_pkginfo_is_readonly(handle, &readOnly);
-       if (ret != PMINFO_R_OK) {
-               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-               return readOnly;
+       while((m = getmntent(f))) {
+               if (m->mnt_dir != NULL && strcmp(m->mnt_dir, "/") == 0 &&
+                       m->mnt_opts != NULL && strstr(m->mnt_opts, "ro,") != NULL) {
+                       endmntent(f);
+                       return true;
+               }
        }
+       endmntent(f);
+       return false;
 
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-
-       return readOnly;
 }
 
 std::string getBaseName(const std::string& path)
index c879877..8635f0f 100755 (executable)
@@ -431,11 +431,15 @@ def TC_17():
     if tpk_path == None:
         return f"FAIL : Get the tpk path for {sln_name}"
 
+    cmd(f"shell mount -o remount,rw /")
+
     raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
     if "1 file(s) pushed. 0 file(s) skipped." in raw:
         cmd(f"shell install_preload_pkg")
 
-    cmd(f"shell dotnettool --ni-regen-all-ro-app")
+    cmd(f"shell mount -o remount,ro /")
+
+    cmd(f"shell dotnettool --ni-regen-all-app")
 
     raw = subprocess.run((f"sdb -s {serial} shell pkginfo --metadata-flt").split(), stdout=subprocess.PIPE, input=f"http://tizen.org/metadata/prefer_dotnet_aot\ntrue\n", encoding="utf-8").stdout
     lines = [l for l in raw.splitlines() if "appid" in l]
@@ -502,9 +506,11 @@ def TC_19():
     if tpk_path == None:
         return f"FAIL : Get the tpk path for {sln_name}"
 
+    cmd(f"shell mount -o remount,rw /")
     raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
     if "1 file(s) pushed. 0 file(s) skipped." in raw:
         cmd(f"shell install_preload_pkg")
+    cmd(f"shell mount -o remount,ro /")
 
     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_09.Tizen"
 
@@ -515,7 +521,7 @@ def TC_19():
     if exist(f"{root_path}/bin/.native_image"):
         return "FAIL : The .native_image folder not should exist"
 
-    cmd(f"shell dotnettool --ni-ro-pkg {pkg_id}")
+    cmd(f"shell dotnettool --ni-pkg {pkg_id}")
 
     if not exist(f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image"):
         return "FAIL : The .native_image folder should exist"