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.
17 #include "db_handle_provider.hh"
20 #include <sys/types.h>
22 #include <tzplatform_config.h>
28 #include "pkgmgrinfo_debug.h"
29 #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);
51 static const std::string global_parser_memory_db_path =
52 "file:parserdb?mode=memory&cache=shared";
54 static const std::string cert_memory_db_path =
55 "file:certdb?mode=memory&cache=shared";
59 namespace pkgmgr_server {
62 std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>>
63 DBHandleProvider::provider_;
64 bool DBHandleProvider::is_memory_global_ = false;
65 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
66 DBHandleProvider::global_parser_memory_db_handle_(
67 nullptr, sqlite3_close_v2);
68 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
69 DBHandleProvider::cert_memory_db_handle_(nullptr, sqlite3_close_v2);
70 std::string DBHandleProvider::global_parser_file_db_path_;
71 std::string DBHandleProvider::cert_file_db_path_;
72 std::unordered_set<pid_t> DBHandleProvider::pid_list_;
73 std::recursive_mutex DBHandleProvider::lock_;
75 DBHandleProvider::DBHandleProvider(uid_t uid) : uid_(uid),
76 is_memory_(false), parser_memory_db_handle_(nullptr, sqlite3_close_v2) {
79 if (global_parser_file_db_path_.empty()) {
80 tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
81 global_parser_file_db_path_ = tmp_path;
84 tmp_path = getUserPkgCertDBPath();
85 cert_file_db_path_ = tmp_path;
89 tmp_path = getUserPkgParserDBPathUID(uid_);
90 parser_file_db_path_ = tmp_path;
93 parser_memory_db_path_ = "file:parserdb" +
94 std::to_string(static_cast<int>(uid_)) + "?mode=memory&cache=shared";
97 DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) {
98 static std::mutex singleton_lock;
99 std::unique_lock<std::mutex> u(singleton_lock);
101 uid = ConvertUID(uid);
102 auto& prov = provider_[uid];
104 prov.reset(new DBHandleProvider(uid));
109 bool DBHandleProvider::IsCrashedWriteRequest() {
110 std::unique_lock<std::recursive_mutex> u(lock_);
112 if (pid_list_.empty())
116 LOGD("Check process count : %zu", pid_list_.size());
117 std::vector<pid_t> remove_pids;
118 for (pid_t pid : pid_list_) {
119 std::string status_path = "/proc/" + std::to_string(pid) + "/status";
121 int fd = open(status_path.c_str(), O_RDONLY);
123 LOGE("Process is crashed (%d)", pid);
124 remove_pids.push_back(pid);
131 for (pid_t pid : remove_pids)
132 pid_list_.erase(pid);
137 std::vector<std::pair<std::string, uid_t>> DBHandleProvider::GetParserDBPath(
138 pid_t pid, bool write) {
139 std::unique_lock<std::recursive_mutex> u(lock_);
140 std::vector<std::pair<std::string, uid_t>> db_path_list;
142 if (is_memory_ != is_memory_global_)
143 is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
145 if (IsMemoryDBActive(pid, write)) {
146 if (uid_ > REGULAR_USER)
147 db_path_list.emplace_back(std::make_pair(parser_memory_db_path_, uid_));
148 db_path_list.emplace_back(
149 std::make_pair(global_parser_memory_db_path, GetGlobalUID()));
151 if (uid_ > REGULAR_USER)
152 db_path_list.emplace_back(std::make_pair(parser_file_db_path_, uid_));
153 db_path_list.emplace_back(
154 std::make_pair(global_parser_file_db_path_, GetGlobalUID()));
157 if (db_path_list.size() == 1) {
158 LOGD("global db path : %s", db_path_list[0].first.c_str());
160 LOGD("local db path : %s", db_path_list[0].first.c_str());
161 LOGD("global db path : %s", db_path_list[1].first.c_str());
167 std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) {
168 std::unique_lock<std::recursive_mutex> u(lock_);
169 if (is_memory_ != is_memory_global_)
171 SetMemoryMode(pid) : UnsetMemoryMode(is_memory_global_);
173 if (IsMemoryDBActive(pid, write))
174 return cert_memory_db_path;
176 return cert_file_db_path_;
179 sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
180 const std::string& memorydb_path) {
181 sqlite3* memorydb = nullptr;
182 sqlite3* filedb = nullptr;
183 int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
184 SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr);
185 if (ret != SQLITE_OK) {
186 LOGE("Failed to open memory DB %d(%s)", ret, memorydb_path.c_str());
190 ret = sqlite3_open_v2(filedb_path.c_str(), &filedb,
191 SQLITE_OPEN_READONLY, nullptr);
192 if (ret != SQLITE_OK) {
193 LOGE("Failed to open file DB %d(%s)", ret, filedb_path.c_str());
194 sqlite3_close_v2(memorydb);
198 sqlite3_backup* backup = sqlite3_backup_init(memorydb, "main",
200 if (backup == nullptr) {
201 LOGE("Failed to backup for memory DB");
202 sqlite3_close_v2(memorydb);
203 sqlite3_close_v2(filedb);
207 sqlite3_backup_step(backup, -1);
208 sqlite3_backup_finish(backup);
209 sqlite3_close_v2(filedb);
213 void DBHandleProvider::SetMemoryMode(pid_t pid) {
214 std::unique_lock<std::recursive_mutex> u(lock_);
215 if (is_memory_global_ && is_memory_)
218 sqlite3* parser_db = GetMemoryDBHandle(parser_file_db_path_,
219 parser_memory_db_path_);
220 if (parser_db != nullptr)
221 parser_memory_db_handle_.reset(parser_db);
223 if (is_memory_ == is_memory_global_) { /* first call */
224 sqlite3* global_parser_file_db = GetMemoryDBHandle(
225 global_parser_file_db_path_, global_parser_memory_db_path);
226 if (global_parser_file_db)
227 global_parser_memory_db_handle_.reset(global_parser_file_db);
228 sqlite3* cert_db = GetMemoryDBHandle(cert_file_db_path_,
229 cert_memory_db_path);
230 if (cert_db != nullptr)
231 cert_memory_db_handle_.reset(cert_db);
233 if (pid_list_.find(pid) == pid_list_.end())
234 pid_list_.insert(pid);
238 is_memory_global_ = true;
239 LOGD("Set Memory mode : Memory");
242 void DBHandleProvider::UnsetMemoryMode(pid_t pid) {
243 std::unique_lock<std::recursive_mutex> u(lock_);
244 if (!is_memory_global_ && !is_memory_)
247 parser_memory_db_handle_.reset(nullptr);
248 cert_memory_db_handle_.reset(nullptr);
249 global_parser_memory_db_handle_.reset(nullptr);
251 auto it = pid_list_.find(pid);
252 if (it != pid_list_.end())
255 LOGE("Given pid is not exists in pid list : %d", pid);
258 is_memory_global_ = false;
259 LOGD("Set Memory mode : File");
262 bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) {
263 return (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write);
266 } // namespace database
267 } // namespace pkgmgr_server