2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <sys/types.h>
20 #include <tzplatform_config.h>
26 #include "db_handle_provider.hh"
27 #include "pkgmgrinfo_debug.h"
28 #include "pkgmgr-info.h"
34 #define LOG_TAG "PKGMGR_INFO"
38 constexpr uid_t REGULAR_USER = 5000;
40 uid_t GetGlobalUID() {
41 return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
44 uid_t ConvertUID(uid_t uid) {
45 if (uid < REGULAR_USER)
46 return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
53 namespace pkgmgr_common {
55 std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>>
56 DBHandleProvider::provider_;
57 bool DBHandleProvider::is_memory_global_ = false;
58 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
59 DBHandleProvider::global_parser_memory_db_handle_(
60 nullptr, sqlite3_close_v2);
61 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
62 DBHandleProvider::cert_memory_db_handle_(nullptr, sqlite3_close_v2);
63 std::string DBHandleProvider::global_parser_memory_db_path_ =
64 "file:parserdb?mode=memory&cache=shared";
65 std::string DBHandleProvider::global_parser_file_db_path_;
66 std::string DBHandleProvider::cert_memory_db_path_ =
67 "file:certdb?mode=memory&cache=shared";
68 std::string DBHandleProvider::cert_file_db_path_;
69 std::unordered_set<pid_t> DBHandleProvider::pid_list_;
70 std::recursive_mutex DBHandleProvider::lock_;
72 DBHandleProvider::DBHandleProvider(uid_t uid) : uid_(uid),
73 is_memory_(false), parser_memory_db_handle_(nullptr, sqlite3_close_v2) {
74 char* tmp_path = nullptr;
75 if (global_parser_file_db_path_.empty()) {
76 tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
77 global_parser_file_db_path_ = tmp_path;
80 tmp_path = getUserPkgCertDBPath();
81 cert_file_db_path_ = tmp_path;
85 tmp_path = getUserPkgParserDBPathUID(uid_);
86 parser_file_db_path_ = tmp_path;
89 parser_memory_db_path_ = "file:parserdb" +
90 std::to_string(static_cast<int>(uid_)) + "?mode=memory&cache=shared";
93 DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) {
94 static std::mutex singleton_lock;
95 std::unique_lock<std::mutex> u(singleton_lock);
96 uid = ConvertUID(uid);
97 auto& prov = provider_[uid];
99 prov.reset(new DBHandleProvider(uid));
104 bool DBHandleProvider::IsCrashedWriteRequest() {
105 std::unique_lock<std::recursive_mutex> u(lock_);
106 if (pid_list_.empty())
109 LOGD("Check process count : %d", pid_list_.size());
110 std::vector<pid_t> remove_pids;
111 for (pid_t pid : pid_list_) {
112 std::string status_path = "/proc/" + std::to_string(pid) + "/status";
114 int fd = open(status_path.c_str(), O_RDONLY);
116 LOGE("Process is crashed (%d)", pid);
117 remove_pids.push_back(pid);
124 for (pid_t pid : remove_pids)
125 pid_list_.erase(pid);
130 std::vector<std::pair<std::string, uid_t>> DBHandleProvider::GetParserDBPath(
131 pid_t pid, bool write) {
132 std::unique_lock<std::recursive_mutex> u(lock_);
133 std::vector<std::pair<std::string, uid_t>> db_path_list;
134 if (is_memory_ != is_memory_global_)
135 SetMemoryMode(pid, is_memory_global_);
137 if (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write) {
138 if (uid_ > REGULAR_USER)
139 db_path_list.emplace_back(std::make_pair(parser_memory_db_path_, uid_));
140 db_path_list.emplace_back(
141 std::make_pair(global_parser_memory_db_path_, GetGlobalUID()));
143 if (uid_ > REGULAR_USER)
144 db_path_list.emplace_back(std::make_pair(parser_file_db_path_, uid_));
145 db_path_list.emplace_back(
146 std::make_pair(global_parser_file_db_path_, GetGlobalUID()));
149 if (db_path_list.size() == 1) {
150 LOGD("global db path : %s", db_path_list[0].first.c_str());
152 LOGD("local db path : %s", db_path_list[0].first.c_str());
153 LOGD("global db path : %s", db_path_list[1].first.c_str());
159 std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) {
160 std::unique_lock<std::recursive_mutex> u(lock_);
161 if (is_memory_ != is_memory_global_)
162 SetMemoryMode(pid, is_memory_global_);
164 if ((is_memory_ && pid_list_.find(pid) == pid_list_.end()) && !write)
165 return cert_memory_db_path_;
167 return cert_file_db_path_;
170 sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
171 const std::string& memorydb_path) {
172 sqlite3* memorydb = nullptr;
173 sqlite3* filedb = nullptr;
174 int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
175 SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr);
176 if (ret != SQLITE_OK) {
177 LOGE("Failed to open memory DB %d(%s)", ret, memorydb_path.c_str());
181 ret = sqlite3_open_v2(filedb_path.c_str(), &filedb,
182 SQLITE_OPEN_READONLY, nullptr);
183 if (ret != SQLITE_OK) {
184 LOGE("Failed to open file DB %d(%s)", ret, filedb_path.c_str());
185 sqlite3_close_v2(memorydb);
188 sqlite3_backup* backup = sqlite3_backup_init(memorydb, "main",
190 if (backup == nullptr) {
191 LOGE("Failed to backup for memory DB");
192 sqlite3_close_v2(memorydb);
193 sqlite3_close_v2(filedb);
197 sqlite3_backup_step(backup, -1);
198 sqlite3_backup_finish(backup);
199 LOGD("Set memory DB(%s)", memorydb_path.c_str());
200 sqlite3_close_v2(filedb);
204 void DBHandleProvider::SetMemoryMode(pid_t pid, bool flag) {
205 std::unique_lock<std::recursive_mutex> u(lock_);
206 if (flag == is_memory_global_ && flag == is_memory_)
210 sqlite3* parser_db = GetMemoryDBHandle(parser_file_db_path_,
211 parser_memory_db_path_);
212 if (parser_db != nullptr)
213 parser_memory_db_handle_.reset(parser_db);
215 if (is_memory_ == is_memory_global_) { /* first call */
216 sqlite3* global_parser_file_db = GetMemoryDBHandle(
217 global_parser_file_db_path_, global_parser_memory_db_path_);
218 if (global_parser_file_db)
219 global_parser_memory_db_handle_.reset(global_parser_file_db);
220 sqlite3* cert_db = GetMemoryDBHandle(cert_file_db_path_,
221 cert_memory_db_path_);
222 if (cert_db != nullptr)
223 cert_memory_db_handle_.reset(cert_db);
225 if (pid_list_.find(pid) == pid_list_.end())
226 pid_list_.insert(pid);
229 parser_memory_db_handle_.reset(nullptr);
230 cert_memory_db_handle_.reset(nullptr);
231 global_parser_memory_db_handle_.reset(nullptr);
233 auto it = pid_list_.find(pid);
234 if (it != pid_list_.end())
237 LOGE("Given pid is not exists in pid list : %d", pid);
240 is_memory_global_ = flag;
241 LOGD("Set Memory mode : %s", flag ? "Memory" : "File");
244 } // namespace pkgmgr_common