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 "utils/logging.hh"
30 #include "pkgmgrinfo_debug.h"
31 #include "pkgmgr-info.h"
36 #define LOG_TAG "PKGMGR_INFO"
40 constexpr uid_t REGULAR_USER = 5000;
42 uid_t globaluser_uid = -1;
44 uid_t GetGlobalUID() {
45 if (globaluser_uid == (uid_t)-1)
46 globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
48 return globaluser_uid;
51 uid_t ConvertUID(uid_t uid) {
52 if (uid < REGULAR_USER)
53 return GetGlobalUID();
58 static const std::string global_parser_memory_db_path =
59 "file:parserdb?mode=memory&cache=shared";
61 static const std::string cert_memory_db_path =
62 "file:certdb?mode=memory&cache=shared";
66 namespace pkgmgr_server {
69 std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>>
70 DBHandleProvider::provider_;
71 bool DBHandleProvider::is_memory_global_ = false;
72 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
73 DBHandleProvider::global_parser_memory_db_handle_(
74 nullptr, sqlite3_close_v2);
75 std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
76 DBHandleProvider::cert_memory_db_handle_(nullptr, sqlite3_close_v2);
77 std::string DBHandleProvider::global_parser_file_db_path_;
78 std::string DBHandleProvider::cert_file_db_path_;
79 std::unordered_set<pid_t> DBHandleProvider::pid_list_;
80 std::recursive_mutex DBHandleProvider::lock_;
82 DBHandleProvider::DBHandleProvider(uid_t uid) : uid_(uid),
83 is_memory_(false), parser_memory_db_handle_(nullptr, sqlite3_close_v2) {
86 if (global_parser_file_db_path_.empty()) {
87 tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
88 global_parser_file_db_path_ = tmp_path;
91 tmp_path = getUserPkgCertDBPath();
92 cert_file_db_path_ = tmp_path;
96 tmp_path = getUserPkgParserDBPathUID(uid_);
97 parser_file_db_path_ = tmp_path;
100 parser_memory_db_path_ = "file:parserdb" +
101 std::to_string(static_cast<int>(uid_)) + "?mode=memory&cache=shared";
104 DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) {
105 static std::mutex singleton_lock;
106 std::unique_lock<std::mutex> u(singleton_lock);
108 uid = ConvertUID(uid);
109 auto& prov = provider_[uid];
111 prov.reset(new DBHandleProvider(uid));
116 bool DBHandleProvider::IsCrashedWriteRequest() {
117 std::unique_lock<std::recursive_mutex> u(lock_);
119 if (pid_list_.empty())
123 LOG(DEBUG) << "Check process count : " << pid_list_.size();
124 std::vector<pid_t> remove_pids;
125 for (pid_t pid : pid_list_) {
126 std::string status_path = "/proc/" + std::to_string(pid) + "/status";
128 int fd = open(status_path.c_str(), O_RDONLY);
130 LOG(ERROR) << "Process is crashed : " << pid;
131 remove_pids.push_back(pid);
138 for (pid_t pid : remove_pids)
139 pid_list_.erase(pid);
144 std::vector<std::pair<std::string, uid_t>> DBHandleProvider::GetParserDBPath(
145 pid_t pid, bool write) {
146 std::unique_lock<std::recursive_mutex> u(lock_);
147 std::vector<std::pair<std::string, uid_t>> db_path_list;
149 if (is_memory_ != is_memory_global_)
150 is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
152 if (IsMemoryDBActive(pid, write)) {
153 if (uid_ > REGULAR_USER)
154 db_path_list.emplace_back(std::make_pair(parser_memory_db_path_, uid_));
155 db_path_list.emplace_back(
156 std::make_pair(global_parser_memory_db_path, GetGlobalUID()));
158 if (uid_ > REGULAR_USER)
159 db_path_list.emplace_back(std::make_pair(parser_file_db_path_, uid_));
160 db_path_list.emplace_back(
161 std::make_pair(global_parser_file_db_path_, GetGlobalUID()));
164 if (db_path_list.size() == 1) {
165 LOG(DEBUG) << "global db path : " << db_path_list[0].first;
167 LOG(DEBUG) << "local db path : " << db_path_list[0].first;
168 LOG(DEBUG) << "global db path : " << db_path_list[1].first;
174 std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) {
175 std::unique_lock<std::recursive_mutex> u(lock_);
176 if (is_memory_ != is_memory_global_)
177 is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
179 if (IsMemoryDBActive(pid, write))
180 return cert_memory_db_path;
182 return cert_file_db_path_;
185 sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
186 const std::string& memorydb_path) {
187 sqlite3* memorydb = nullptr;
188 sqlite3* filedb = nullptr;
189 int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
190 SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr);
191 if (ret != SQLITE_OK) {
192 LOG(ERROR) << "Failed to open memory DB " << ret << ": " << memorydb_path;
196 ret = sqlite3_open_v2(filedb_path.c_str(), &filedb,
197 SQLITE_OPEN_READONLY, nullptr);
198 if (ret != SQLITE_OK) {
199 LOG(ERROR) << "Failed to open file DB " << ret << ": " << filedb_path;
200 sqlite3_close_v2(memorydb);
204 sqlite3_backup* backup = sqlite3_backup_init(memorydb, "main",
206 if (backup == nullptr) {
207 LOG(ERROR) << "Failed to backup for memory DB";
208 sqlite3_close_v2(memorydb);
209 sqlite3_close_v2(filedb);
213 sqlite3_backup_step(backup, -1);
214 sqlite3_backup_finish(backup);
215 sqlite3_close_v2(filedb);
219 void DBHandleProvider::SetMemoryMode(pid_t pid) {
220 std::unique_lock<std::recursive_mutex> u(lock_);
221 if (is_memory_global_ && is_memory_)
224 sqlite3* parser_db = GetMemoryDBHandle(parser_file_db_path_,
225 parser_memory_db_path_);
226 if (parser_db != nullptr)
227 parser_memory_db_handle_.reset(parser_db);
229 if (is_memory_ == is_memory_global_) { /* first call */
230 sqlite3* global_parser_file_db = GetMemoryDBHandle(
231 global_parser_file_db_path_, global_parser_memory_db_path);
232 if (global_parser_file_db)
233 global_parser_memory_db_handle_.reset(global_parser_file_db);
234 sqlite3* cert_db = GetMemoryDBHandle(cert_file_db_path_,
235 cert_memory_db_path);
236 if (cert_db != nullptr)
237 cert_memory_db_handle_.reset(cert_db);
239 if (pid_list_.find(pid) == pid_list_.end())
240 pid_list_.insert(pid);
244 is_memory_global_ = true;
245 LOG(DEBUG) << "Set Memory mode : Memory";
248 void DBHandleProvider::UnsetMemoryMode(pid_t pid) {
249 std::unique_lock<std::recursive_mutex> u(lock_);
250 if (!is_memory_global_ && !is_memory_)
253 parser_memory_db_handle_.reset(nullptr);
254 cert_memory_db_handle_.reset(nullptr);
255 global_parser_memory_db_handle_.reset(nullptr);
257 auto it = pid_list_.find(pid);
258 if (it != pid_list_.end())
261 LOG(ERROR) << "Given pid is not exists in pid list : " << pid;
264 is_memory_global_ = false;
265 LOG(DEBUG) << "Set Memory mode : File";
268 bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) {
269 return (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write);
272 } // namespace database
273 } // namespace pkgmgr_server