Refactoring TAC to support multi-package installation
authorj-h.choi <j-h.choi@samsung.com>
Wed, 23 Apr 2025 03:24:16 +0000 (12:24 +0900)
committer조웅석/MDE Lab(SR)/삼성전자 <ws77.cho@samsung.com>
Wed, 28 May 2025 08:07:17 +0000 (17:07 +0900)
Change-Id: I57b52ad0edeb8cb9c9944de30a43940d0c84aeca

NativeLauncher/tool/tac_installer.cc

index fffcaefb6bd7c79692d9fe6834b8e465b26c20a7..675269a3daac5506128f0dc4d6ce12c83a4cb487 100644 (file)
@@ -42,34 +42,56 @@ static const char* __READ_ONLY_TAC_DIR = __STR(READ_ONLY_TAC_DIR);
 #undef __STR
 #undef __XSTR
 
-static std::vector<std::string> nugetPackagesAssembliesSha;
-static std::vector<std::string> tacDB;
-static std::vector<std::string> createDirectories;
-static std::vector<std::string> createLibraries;
-static std::vector<std::string> updateTac;
-static std::vector<std::string> updateTlc;
-static tac_state tacState = TAC_STATE_NONE;
-static std::string prevInstallPkgId = std::string("");
-static std::string prevFinishPkgId = std::string("");
-static std::string tacLocation = __DOTNET_DIR;
-static bool isTacReadonly = false;
+typedef struct TACInfo {
+       std::vector<std::string> nugetPackagesAssembliesSha;
+       std::vector<std::string> tacDB;
+       std::vector<std::string> createDirectories;
+       std::vector<std::string> createLibraries;
+       std::vector<std::string> updateTac;
+       std::vector<std::string> updateTlc;
+       tac_state tacState = TAC_STATE_NONE;
+       std::string prevInstallPkgId = std::string("");
+       std::string prevFinishPkgId = std::string("");
+       std::string tacLocation = __DOTNET_DIR;
+       bool isTacReadonly = false;
+} TACInfo;
+
+std::map<std::string, TACInfo> TacMgr;
+
+static void addTacMgr(TACInfo& tacInfo, const std::string& pkgId)
+{
+       TacMgr[pkgId] = tacInfo;
+}
+
+static TACInfo findTacMgr(const std::string& pkgId)
+{
+       return TacMgr.at(pkgId);
+}
 
 // initialize static vector to support multi-package install scenario
-static void tacInitialize()
+static TACInfo tacInitialize(const std::string& pkgId)
 {
-       nugetPackagesAssembliesSha.clear();
-       tacDB.clear();
-       createDirectories.clear();
-       createLibraries.clear();
-       updateTac.clear();
-       updateTlc.clear();
+       TACInfo tacInfo;
+       tacInfo.nugetPackagesAssembliesSha.clear();
+       tacInfo.tacDB.clear();
+       tacInfo.createDirectories.clear();
+       tacInfo.createLibraries.clear();
+       tacInfo.updateTac.clear();
+       tacInfo.updateTlc.clear();
+       tacInfo.tacState = TAC_STATE_NONE;
+       tacInfo.prevInstallPkgId = std::string("");
+       tacInfo.prevFinishPkgId = std::string("");
+       tacInfo.tacLocation = __DOTNET_DIR;
+       tacInfo.isTacReadonly = false;
+       addTacMgr(tacInfo, pkgId);
+       return tacInfo;
 }
 
-static void createSHA256Info(std::string sha256Info, std::string nugetPackage)
+static void createSHA256Info(TACInfo& tacInfo, const std::string& sha256Info, const std::string& nugetPackage)
 {
        std::ofstream ofs(sha256Info, std::ios::app);
        int assembly_count = 0;
-       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+       for (auto& npAssemblySha : tacInfo.nugetPackagesAssembliesSha) {
                std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
                std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
                std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
@@ -83,12 +105,12 @@ static void createSHA256Info(std::string sha256Info, std::string nugetPackage)
        ofs.close();
 }
 
-static bool compareSHA256Info(std::string sha256Info, std::string nugetPackage)
+static bool compareSHA256Info(TACInfo& tacInfo, const std::string& sha256Info, const std::string& nugetPackage)
 {
        int compare_count = 0;
        int assembly_count = 0;
        std::string sha256_count = "0";
-       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+       for (auto& npAssemblySha : tacInfo.nugetPackagesAssembliesSha) {
                std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
                std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
                std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
@@ -116,12 +138,12 @@ static bool compareSHA256Info(std::string sha256Info, std::string nugetPackage)
        return false;
 }
 
-static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, std::string nugetPackage, bool isCreateTacDir)
+static bool copyAssemblyCreateSymlink(TACInfo& tacInfo, const std::string& binPath, const std::string& tacDir, const std::string& nugetPackage, bool isCreateTacDir)
 {
        std::string binNiPath = concatPath(binPath, APP_NI_SUB_DIR);
-       std::string tac_version_dir = concatPath(tacLocation, nugetPackage);
+       std::string tac_version_dir = concatPath(tacInfo.tacLocation, nugetPackage);
        bool nuget_restoration = false;
-       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+       for (auto& npAssemblySha : tacInfo.nugetPackagesAssembliesSha) {
                std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
                std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
                std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
@@ -173,7 +195,7 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s
        }
 
        if (nuget_restoration) {
-               for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+               for (auto& npAssemblySha : tacInfo.nugetPackagesAssembliesSha) {
                        std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
                        std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
                        std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
@@ -188,7 +210,7 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s
        return nuget_restoration;
 }
 
-static void copyLibraryCreateSymlink(const std::string pkgId, std::vector<std::string> LibrariesInfo)
+static void copyLibraryCreateSymlink(TACInfo& tacInfo, const std::string& pkgId, std::vector<std::string> LibrariesInfo)
 {
        if (LibrariesInfo.empty()) {
                return;
@@ -198,7 +220,7 @@ static void copyLibraryCreateSymlink(const std::string pkgId, std::vector<std::s
                std::string library = librarySha.substr(0, librarySha.find(':'));
                std::string filename = library.substr(library.rfind('/') + 1);
                std::string fileSha = filename + ".." + librarySha.substr(librarySha.find(':') + 1);
-               std::string shaPath = concatPath(tlcLBPath(isTacReadonly), fileSha);
+               std::string shaPath = concatPath(tlcLBPath(tacInfo.isTacReadonly), fileSha);
                bool fileCopied = false;
                if (!exist(shaPath)) {
                        if (!copyFile(library, shaPath)) {
@@ -206,7 +228,7 @@ static void copyLibraryCreateSymlink(const std::string pkgId, std::vector<std::s
                                continue;
                        }
                        fileCopied = true;
-                       createLibraries.push_back(shaPath);
+                       tacInfo.createLibraries.push_back(shaPath);
                }
                if (!removeFile(library)) {
                        _ERR("Failed to remove of %s", library.c_str());
@@ -239,21 +261,21 @@ static void copyLibraryCreateSymlink(const std::string pkgId, std::vector<std::s
        }
 }
 
-static void checkDepsJson(std::string rootPath, std::string binPath)
+static void checkDepsJson(TACInfo& tacInfo, const std::string& rootPath, const std::string& binPath)
 {
        for (auto& npAssembly : depsJsonParser(rootPath)) {
                std::string nuget_package = npAssembly.substr(0, npAssembly.rfind(':'));
                std::string assembly_name = npAssembly.substr(npAssembly.rfind(':') + 1);
-               tacDB.push_back(nuget_package);
+               tacInfo.tacDB.push_back(nuget_package);
                std::string buffer = SHA256(concatPath(binPath, assembly_name));
-               nugetPackagesAssembliesSha.push_back(nuget_package + ":" + assembly_name + ":" + buffer);
+               tacInfo.nugetPackagesAssembliesSha.push_back(nuget_package + ":" + assembly_name + ":" + buffer);
                _INFO("Assembly : [%s] / SHA256 : [%s]", assembly_name.c_str(), buffer.c_str());
        }
-       std::sort(tacDB.begin(), tacDB.end());
-       tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end());
+       std::sort(tacInfo.tacDB.begin(), tacInfo.tacDB.end());
+       tacInfo.tacDB.erase(unique(tacInfo.tacDB.begin(), tacInfo.tacDB.end()), tacInfo.tacDB.end());
 }
 
-static int generateTAC(const std::string& pkgId, const std::string& binPath)
+static int generateTAC(TACInfo& tacInfo, const std::string& pkgId, const std::string& binPath)
 {
        std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
        if (!createDir(tac_dir)) {
@@ -263,14 +285,14 @@ static int generateTAC(const std::string& pkgId, const std::string& binPath)
 
        copySmackAndOwnership(binPath.c_str(), tac_dir.c_str());
 
-       for (auto& np : tacDB) {
+       for (auto& np : tacInfo.tacDB) {
                std::string tac_name = np.substr(0, np.find('/'));
                std::string tac_version = np.substr(np.rfind('/') + 1);
                _INFO("TAC name : %s", tac_name.c_str());
                _INFO("TAC version : %s", tac_version.c_str());
 
                bs::error_code error;
-               std::string tac_version_dir = concatPath(tacLocation, np);
+               std::string tac_version_dir = concatPath(tacInfo.tacLocation, np);
                std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
                bool isCreateTacDir = false;
                if (!exist(tac_version_dir)) {
@@ -278,21 +300,21 @@ static int generateTAC(const std::string& pkgId, const std::string& binPath)
 
                        if (!createDir(tac_version_dir)) {
                                _ERR("Cannot create directory: %s", tac_version_dir.c_str());
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
-                       createDirectories.push_back(tac_version_dir);
+                       tacInfo.createDirectories.push_back(tac_version_dir);
 
                        if (isSymlinkFile(sha256_info)) {
                                _ERR("Failed to create sha256_info. Symbolic link is detected");
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
 
-                       createSHA256Info(sha256_info, np);
+                       createSHA256Info(tacInfo, sha256_info, np);
 
                        if (!exist(sha256_info)) {
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
 
@@ -302,11 +324,11 @@ static int generateTAC(const std::string& pkgId, const std::string& binPath)
 
                        if (isSymlinkFile(sha256_info)) {
                                _ERR("Failed to create sha256_info. Symbolic link is detected");
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
 
-                       if (!compareSHA256Info(sha256_info, np)) {
+                       if (!compareSHA256Info(tacInfo, sha256_info, np)) {
                                _INFO("Different nuget : %s", np.c_str());
                                continue;
                        }
@@ -314,31 +336,31 @@ static int generateTAC(const std::string& pkgId, const std::string& binPath)
                        isCreateTacDir = false;
                }
 
-               if (copyAssemblyCreateSymlink(binPath, tac_dir, np, isCreateTacDir)) {
+               if (copyAssemblyCreateSymlink(tacInfo, binPath, tac_dir, np, isCreateTacDir)) {
                        _ERR("Failed to create symlink");
-                       tacState = TAC_STATE_RESTORE;
+                       tacInfo.tacState = TAC_STATE_RESTORE;
                        return -1;
                }
 
-               if (tacState == TAC_STATE_INSTALL) {
+               if (tacInfo.tacState == TAC_STATE_INSTALL) {
                        if (tac_insertDB(pkgId, np, tac_name, tac_version) != 0) {
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
-               } else if (tacState == TAC_STATE_UPGRADE) {
+               } else if (tacInfo.tacState == TAC_STATE_UPGRADE) {
                        int count = -1;
                        if (tac_countDB(pkgId, tac_name, "", count) != 0) {
-                               tacState = TAC_STATE_RESTORE;
+                               tacInfo.tacState = TAC_STATE_RESTORE;
                                return -1;
                        }
                        if (count == 1) {
                                if (tac_updateDB(pkgId, np, tac_name, tac_version) != 0) {
-                                       tacState = TAC_STATE_RESTORE;
+                                       tacInfo.tacState = TAC_STATE_RESTORE;
                                        return -1;
                                }
                        } else if (count == 0) {
                                if (tac_insertDB(pkgId, np, tac_name, tac_version) != 0) {
-                                       tacState = TAC_STATE_RESTORE;
+                                       tacInfo.tacState = TAC_STATE_RESTORE;
                                        return -1;
                                }
                        }
@@ -347,16 +369,16 @@ static int generateTAC(const std::string& pkgId, const std::string& binPath)
        return 0;
 }
 
-void tacUpdateDB(const std::string& pkgId)
+void tacUpdateDB(TACInfo& tacInfo, const std::string& pkgId)
 {
-       for (auto& unp : updateTac) {
+       for (auto& unp : tacInfo.updateTac) {
                int count = -1;
                if (tac_countDB(pkgId, "", unp, count) != 0) {
                        continue;
                }
 
                if (count == 0) {
-                       std::string tac_version_dir_prev = concatPath(tacLocation, unp);
+                       std::string tac_version_dir_prev = concatPath(tacInfo.tacLocation, unp);
                        std::string tac_version_dir_backup = tac_version_dir_prev + ".bck";
                        if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
                                _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
@@ -370,16 +392,16 @@ void tacUpdateDB(const std::string& pkgId)
        }
 }
 
-void tlcUpdateDB(const std::string& pkgId)
+void tlcUpdateDB(TACInfo& tacInfo, const std::string& pkgId)
 {
-       for (auto& ulp : updateTlc) {
+       for (auto& ulp : tacInfo.updateTlc) {
                int count = -1;
                if (tlc_countDB(pkgId, ulp, count) != 0) {
                        continue;
                }
 
                if (count == 0) {
-                       std::string library_prev = concatPath(tlcLBPath(isTacReadonly), ulp);
+                       std::string library_prev = concatPath(tlcLBPath(tacInfo.isTacReadonly), ulp);
                        std::string library_backup = library_prev + ".bck";
                        if (!copyFile(library_prev, library_backup)) {
                                _ERR("Failed to copy of %s", library_prev.c_str());
@@ -398,17 +420,17 @@ int tacInstall(const std::string& pkgId, tac_state state, bool tacForce)
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_INSTALL =====]");
        _INFO("PackageID : %s", pkgId.c_str());
 
-       tacInitialize();
+       TACInfo tacInfo = tacInitialize(pkgId);
 
-       isTacReadonly = isReadOnlyPkg(pkgId);
-       tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+       tacInfo.isTacReadonly = isReadOnlyPkg(pkgId);
+       tacInfo.tacLocation = tacInfo.isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
 
        // Can be multiple apps in one package
-       if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
+       if (strcmp(pkgId.c_str(), tacInfo.prevInstallPkgId.c_str()) == 0) {
                _INFO("TAC Plugin(INSTALL) already run for same pkgId (%s)", pkgId.c_str());
                return 0;
        }
-       prevInstallPkgId = pkgId;
+       tacInfo.prevInstallPkgId = pkgId;
 
        std::string appType = getAppType(pkgId);
        if (strstr(appType.c_str(), "dotnet") == NULL) {
@@ -433,33 +455,36 @@ int tacInstall(const std::string& pkgId, tac_state state, bool tacForce)
                }
        }
        if (metaValue == METADATA_VALUE_TRUE || tacForce) {
-               checkDepsJson(rootPath, binPath);
+               checkDepsJson(tacInfo, rootPath, binPath);
        }
 
-       tacState = state;
-       if (tacDB.empty()) {
+       tacInfo.tacState = state;
+       if (tacInfo.tacDB.empty()) {
                return 0;
        }
 
-       if (tac_createDB(isTacReadonly) != 0) {
+       if (tac_createDB(tacInfo.isTacReadonly) != 0) {
                return -1;
        }
 
-       if (generateTAC(pkgId, binPath) != 0) {
+       if (generateTAC(tacInfo, pkgId, binPath) != 0) {
                tac_closeDB();
                return -1;
        }
 
        ///// TLC /////
-       if (tlc_createDB(isTacReadonly) != 0) {
+       if (tlc_createDB(tacInfo.isTacReadonly) != 0) {
                tac_closeDB();
                return -1;
        }
 
-       copyLibraryCreateSymlink(pkgId, getLibrariesInfo(rootPath));
+       copyLibraryCreateSymlink(tacInfo, pkgId, getLibrariesInfo(rootPath));
 
        tac_closeDB();
        tlc_closeDB();
+
+       addTacMgr(tacInfo, pkgId);
+
        return 0;
 }
 
@@ -468,17 +493,20 @@ int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UPGRADE =====]");
        _INFO("PackageID : %s", pkgId.c_str());
 
-       tacInitialize();
+       TACInfo tacInfo = tacInitialize(pkgId);
+       if (state == TAC_STATE_REMOVED) {
+               tacInfo = findTacMgr(pkgId);
+       }
 
-       isTacReadonly = isReadOnlyPkg(pkgId);
-       tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+       tacInfo.isTacReadonly = isReadOnlyPkg(pkgId);
+       tacInfo.tacLocation = tacInfo.isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
 
        // Can be multiple apps in one package
-       if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
+       if (strcmp(pkgId.c_str(), tacInfo.prevInstallPkgId.c_str()) == 0) {
                _INFO("TAC Plugin(UPGRADE) already run for same pkgId (%s)", pkgId.c_str());
                return 0;
        }
-       prevInstallPkgId = pkgId;
+       tacInfo.prevInstallPkgId = pkgId;
 
        std::string appType = getAppType(pkgId);
        if (strstr(appType.c_str(), "dotnet") == NULL) {
@@ -506,35 +534,35 @@ int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
                        }
                }
                if (metaValue == METADATA_VALUE_TRUE || tacForce) {
-                       checkDepsJson(rootPath, binPath);
+                       checkDepsJson(tacInfo, rootPath, binPath);
                }
        }
 
-       tacState = TAC_STATE_UPGRADE;
-       if (tac_createDB(isTacReadonly) != 0) {
+       tacInfo.tacState = TAC_STATE_UPGRADE;
+       if (tac_createDB(tacInfo.isTacReadonly) != 0) {
                return -1;
        }
 
-       updateTac = tac_selectDB(pkgId);
+       tacInfo.updateTac = tac_selectDB(pkgId);
 
        bool skipTLC = false;
-       if (tacDB.empty()) {
+       if (tacInfo.tacDB.empty()) {
                if (tac_deleteDB(pkgId, "") != 0) {
                        tac_closeDB();
                        return -1;
                }
-               tacUpdateDB(pkgId);
+               tacUpdateDB(tacInfo, pkgId);
 
                skipTLC = true;
        } else {
-               if (generateTAC(pkgId, binPath) != 0) {
+               if (generateTAC(tacInfo, pkgId, binPath) != 0) {
                        tac_closeDB();
                        return -1;
                }
 
-               for (auto& unp : updateTac) {
+               for (auto& unp : tacInfo.updateTac) {
                        bool isExits = false;
-                       for (auto& np : tacDB) {
+                       for (auto& np : tacInfo.tacDB) {
                                if (!strcmp(unp.c_str(), np.c_str())) {
                                        isExits = true;
                                        break;
@@ -542,22 +570,22 @@ int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
                        }
                        if (!isExits) {
                                if (tac_deleteDB(pkgId, unp) != 0) {
-                                       tacState = TAC_STATE_RESTORE;
+                                       tacInfo.tacState = TAC_STATE_RESTORE;
                                        tac_closeDB();
                                        return -1;
                                }
                        }
                }
-               tacUpdateDB(pkgId);
+               tacUpdateDB(tacInfo, pkgId);
        }
 
        ///// TLC /////
-       if (tlc_createDB(isTacReadonly) != 0) {
+       if (tlc_createDB(tacInfo.isTacReadonly) != 0) {
                tac_closeDB();
                return -1;
        }
 
-       updateTlc = tlc_selectDB(pkgId);
+       tacInfo.updateTlc = tlc_selectDB(pkgId);
 
        if (tlc_deleteDB(pkgId) != 0) {
                tac_closeDB();
@@ -565,13 +593,15 @@ int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
                return -1;
        }
 
-       tlcUpdateDB(pkgId);
+       tlcUpdateDB(tacInfo, pkgId);
 
-       copyLibraryCreateSymlink(pkgId, skipTLC ? std::vector<std::string>() : getLibrariesInfo(rootPath));
+       copyLibraryCreateSymlink(tacInfo, pkgId, skipTLC ? std::vector<std::string>() : getLibrariesInfo(rootPath));
 
        tac_closeDB();
        tlc_closeDB();
 
+       addTacMgr(tacInfo, pkgId);
+
        return 0;
 }
 
@@ -580,39 +610,39 @@ int tacUninstall(const std::string& pkgId, tac_state state)
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNINSTALL =====]");
        _INFO("PackageID : %s", pkgId.c_str());
 
-       tacInitialize();
+       TACInfo tacInfo = tacInitialize(pkgId);
 
-       isTacReadonly = isReadOnlyPkg(pkgId);
-       tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+       tacInfo.isTacReadonly = isReadOnlyPkg(pkgId);
+       tacInfo.tacLocation = tacInfo.isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
 
        // Can be multiple apps in one package
-       if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
+       if (strcmp(pkgId.c_str(), tacInfo.prevInstallPkgId.c_str()) == 0) {
                _INFO("TAC Plugin(UNINSTALL) already run for same pkgId (%s)", pkgId.c_str());
                return 0;
        }
-       prevInstallPkgId = pkgId;
+       tacInfo.prevInstallPkgId = pkgId;
 
-       tacState= state;
-       if (tac_openDB(isTacReadonly) != 0) {
+       tacInfo.tacState = state;
+       if (tac_openDB(tacInfo.isTacReadonly) != 0) {
                return -1;
        }
 
-       updateTac = tac_selectDB(pkgId);
+       tacInfo.updateTac = tac_selectDB(pkgId);
 
        if (tac_deleteDB(pkgId, "") != 0) {
-               tacState = TAC_STATE_RESTORE;
+               tacInfo.tacState = TAC_STATE_RESTORE;
                tac_closeDB();
                return -1;
        }
-       tacUpdateDB(pkgId);
+       tacUpdateDB(tacInfo, pkgId);
 
        ///// TLC /////
-       if (tlc_openDB(isTacReadonly) != 0) {
+       if (tlc_openDB(tacInfo.isTacReadonly) != 0) {
                tac_closeDB();
                return -1;
        }
 
-       updateTlc = tlc_selectDB(pkgId);
+       tacInfo.updateTlc = tlc_selectDB(pkgId);
 
        if (tlc_deleteDB(pkgId) != 0) {
                tac_closeDB();
@@ -620,11 +650,13 @@ int tacUninstall(const std::string& pkgId, tac_state state)
                return -1;
        }
 
-       tlcUpdateDB(pkgId);
+       tlcUpdateDB(tacInfo, pkgId);
 
        tac_closeDB();
        tlc_closeDB();
 
+       addTacMgr(tacInfo, pkgId);
+
        return 0;
 }
 
@@ -636,9 +668,9 @@ int tacRemoved(const std::string& pkgId)
        return tacUpgrade(pkgId, TAC_STATE_REMOVED);
 }
 
-void undoStep(std::string tac)
+void undoStep(TACInfo& tacInfo, const std::string& tac)
 {
-       std::string current_tac = concatPath(tacLocation, tac.substr(0, tac.find('/')));
+       std::string current_tac = concatPath(tacInfo.tacLocation, tac.substr(0, tac.find('/')));
        try {
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
                        std::string bck_path = bck.path().string();
@@ -663,40 +695,40 @@ void undoStep(std::string tac)
                }
        };
 
-       scanFilesInDirectory(tlcLBPath(isTacReadonly), convert, 0);
+       scanFilesInDirectory(tlcLBPath(tacInfo.isTacReadonly), convert, 0);
 }
 
-void install_Undo()
+void install_Undo(TACInfo& tacInfo)
 {
-       for (auto& cd : createDirectories) {
+       for (auto& cd : tacInfo.createDirectories) {
                if (!removeAll(cd)) {
                        _ERR("Failed to remove of %s", cd.c_str());
                }
        }
 
-       for (auto& cl : createLibraries) {
+       for (auto& cl : tacInfo.createLibraries) {
                if (!removeFile(cl)) {
                        _ERR("Failed to remove of %s", cl.c_str());
                }
        }
 }
 
-void unInstall_Undo()
+void unInstall_Undo(TACInfo& tacInfo)
 {
-       for (auto& unp : updateTac) {
-               undoStep(unp);
+       for (auto& unp : tacInfo.updateTac) {
+               undoStep(tacInfo, unp);
        }
 }
 
-void update_Undo()
+void update_Undo(TACInfo& tacInfo)
 {
-       install_Undo();
-       if (!tacDB.empty()) {
-               for (auto& np : tacDB) {
-                       undoStep(np);
+       install_Undo(tacInfo);
+       if (!tacInfo.tacDB.empty()) {
+               for (auto& np : tacInfo.tacDB) {
+                       undoStep(tacInfo, np);
                }
        }
-       unInstall_Undo();
+       unInstall_Undo(tacInfo);
 }
 
 int tacUndo(const std::string& pkgId)
@@ -704,24 +736,23 @@ int tacUndo(const std::string& pkgId)
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
        _INFO("PackageID : %s", pkgId.c_str());
 
-       isTacReadonly = isReadOnlyPkg(pkgId);
-       tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+       TACInfo tacInfo = findTacMgr(pkgId);
 
        // Can be multiple apps in one package
-       if (strcmp(pkgId.c_str(), prevFinishPkgId.c_str()) == 0) {
+       if (strcmp(pkgId.c_str(), tacInfo.prevFinishPkgId.c_str()) == 0) {
                _INFO("TAC Plugin(UNDO) already run for same pkgId (%s)", pkgId.c_str());
                return 0;
        }
-       prevFinishPkgId = pkgId;
+       tacInfo.prevFinishPkgId = pkgId;
 
-       if (tacState == TAC_STATE_INSTALL) {
-               install_Undo();
-       } else if (tacState == TAC_STATE_UPGRADE) {
-               update_Undo();
-       } else if (tacState == TAC_STATE_UNINSTALL) {
-               unInstall_Undo();
-       } else if (tacState == TAC_STATE_RESTORE) {
-               update_Undo();
+       if (tacInfo.tacState == TAC_STATE_INSTALL) {
+               install_Undo(tacInfo);
+       } else if (tacInfo.tacState == TAC_STATE_UPGRADE) {
+               update_Undo(tacInfo);
+       } else if (tacInfo.tacState == TAC_STATE_UNINSTALL) {
+               unInstall_Undo(tacInfo);
+       } else if (tacInfo.tacState == TAC_STATE_RESTORE) {
+               update_Undo(tacInfo);
        }
 
        tac_rollbackDB();
@@ -731,20 +762,20 @@ int tacUndo(const std::string& pkgId)
        return 0;
 }
 
-void changeOwnershipTAC(std::string current_tac)
+void changeOwnershipTAC(TACInfo& tacInfo, const std::string& current_tac)
 {
-       copySmackAndOwnership(tacLocation, current_tac);
+       copySmackAndOwnership(tacInfo.tacLocation, current_tac);
        try {
                for (auto& path : bf::recursive_directory_iterator(current_tac))
-                       copySmackAndOwnership(tacLocation, path.path().string());
+                       copySmackAndOwnership(tacInfo.tacLocation, path.path().string());
        } catch (const bf::filesystem_error& error) {
                _ERR("Failed to recursive directory: %s", error.what());
        }
 }
 
-void cleanStep(std::string tac)
+void cleanStep(TACInfo& tacInfo, const std::string tac)
 {
-       std::string current_tac = concatPath(tacLocation, tac.substr(0, tac.find('/')));
+       std::string current_tac = concatPath(tacInfo.tacLocation, tac.substr(0, tac.find('/')));
        try {
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
                        std::string bck_path = bck.path().string();
@@ -783,43 +814,45 @@ void cleanStep(std::string tac)
                }
        };
 
-       scanFilesInDirectory(tlcLBPath(isTacReadonly), convert, 0);
+       scanFilesInDirectory(tlcLBPath(tacInfo.isTacReadonly), convert, 0);
 }
 
-void install_Clean()
+void install_Clean(TACInfo& tacInfo)
 {
-       for (auto& cd : createDirectories) {
-               changeOwnershipTAC(cd);
-               copySmackAndOwnership(tacLocation, cd.substr(0, cd.rfind('/')));
+       for (auto& cd : tacInfo.createDirectories) {
+               changeOwnershipTAC(tacInfo, cd);
+               copySmackAndOwnership(tacInfo.tacLocation, cd.substr(0, cd.rfind('/')));
        }
 
-       for (auto& cl : createLibraries) {
-               copySmackAndOwnership(tacLocation, cl);
+       for (auto& cl : tacInfo.createLibraries) {
+               copySmackAndOwnership(tacInfo.tacLocation, cl);
        }
 }
 
-void unInstall_Clean()
+void unInstall_Clean(TACInfo& tacInfo)
 {
-       for (auto& unp : updateTac) {
-               cleanStep(unp);
+       for (auto& unp : tacInfo.updateTac) {
+               cleanStep(tacInfo, unp);
        }
 }
 
-void update_Clean()
+void update_Clean(TACInfo& tacInfo)
 {
-       install_Clean();
-       if (!tacDB.empty()) {
-               for (auto& np : tacDB) {
-                       cleanStep(np);
-                       changeOwnershipTAC(concatPath(tacLocation, np.substr(0, np.find('/'))));
+       install_Clean(tacInfo);
+       if (!tacInfo.tacDB.empty()) {
+               for (auto& np : tacInfo.tacDB) {
+                       cleanStep(tacInfo, np);
+                       changeOwnershipTAC(tacInfo, concatPath(tacInfo.tacLocation, np.substr(0, np.find('/'))));
                }
        }
-       unInstall_Clean();
+       unInstall_Clean(tacInfo);
 }
 
 int tacClean(const std::string& pkgId)
 {
-       if (tacState == TAC_STATE_RESTORE) {
+       TACInfo tacInfo = findTacMgr(pkgId);
+
+       if (tacInfo.tacState == TAC_STATE_RESTORE) {
                disableTACPackage(pkgId);
 
                std::string rootPath = getRootPath(pkgId);
@@ -858,30 +891,30 @@ int tacClean(const std::string& pkgId)
        _INFO("PackageID : %s", pkgId.c_str());
 
        // Can be multiple apps in one package
-       if (strcmp(pkgId.c_str(), prevFinishPkgId.c_str()) == 0) {
+       if (strcmp(pkgId.c_str(), tacInfo.prevFinishPkgId.c_str()) == 0) {
                _INFO("TAC Plugin(CLEAN) already run for same pkgId (%s)", pkgId.c_str());
                return 0;
        }
-       prevFinishPkgId = pkgId;
+       tacInfo.prevFinishPkgId = pkgId;
 
-       if (tacState == TAC_STATE_INSTALL) {
-               install_Clean();
-       } else if (tacState == TAC_STATE_UPGRADE) {
-               update_Clean();
-       } else if (tacState == TAC_STATE_UNINSTALL) {
-               unInstall_Clean();
+       if (tacInfo.tacState == TAC_STATE_INSTALL) {
+               install_Clean(tacInfo);
+       } else if (tacInfo.tacState == TAC_STATE_UPGRADE) {
+               update_Clean(tacInfo);
+       } else if (tacInfo.tacState == TAC_STATE_UNINSTALL) {
+               unInstall_Clean(tacInfo);
        }
 
        if (tac_closeDB()) {
-               std::string tacDbPath = tacDBPath(isTacReadonly, TAC_APP_LIST_DB);
-               copySmackAndOwnership(tacLocation, tacDbPath);
-               copySmackAndOwnership(tacLocation, tacDbPath + std::string("-journal"));
+               std::string tacDbPath = tacDBPath(tacInfo.isTacReadonly, TAC_APP_LIST_DB);
+               copySmackAndOwnership(tacInfo.tacLocation, tacDbPath);
+               copySmackAndOwnership(tacInfo.tacLocation, tacDbPath + std::string("-journal"));
        }
 
        if (tlc_closeDB()) {
-               std::string tlcDbPath = tacDBPath(isTacReadonly, TLC_APP_LIST_DB);
-               copySmackAndOwnership(tacLocation, tlcDbPath);
-               copySmackAndOwnership(tacLocation, tlcDbPath + std::string("-journal"));
+               std::string tlcDbPath = tacDBPath(tacInfo.isTacReadonly, TLC_APP_LIST_DB);
+               copySmackAndOwnership(tacInfo.tacLocation, tlcDbPath);
+               copySmackAndOwnership(tacInfo.tacLocation, tlcDbPath + std::string("-journal"));
        }
 
        return 0;