使用quota获取应用数据大小

Signed-off-by: Zhou Shihui <zhoushihui4@huawei.com>
This commit is contained in:
Zhou Shihui 2024-01-16 15:41:42 +08:00
parent 3d9ed5c7f7
commit 0dc64ae6ed
20 changed files with 122 additions and 59 deletions

View File

@ -16,6 +16,7 @@
#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_INSTALLD_HOST_IMPL_H
#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_INSTALLD_HOST_IMPL_H
#include "bundle_constants.h"
#include "code_sign_helper.h"
#include "ipc/installd_host.h"
#include "installd/installd_operator.h"
@ -106,8 +107,8 @@ public:
* @param bundleStats Indicates the bundle Stats.
* @return Returns ERR_OK if get stats successfully; returns error code otherwise.
*/
virtual ErrCode GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats) override;
virtual ErrCode GetBundleStats(const std::string &bundleName, const int32_t userId,
std::vector<int64_t> &bundleStats, const int32_t uid = Constants::INVALID_UID) override;
/**
* @brief Set dir apl.
* @param dir Indicates the data dir.

View File

@ -192,6 +192,10 @@ public:
*/
static int64_t GetDiskUsageFromPath(const std::vector<std::string> &path);
static bool InitialiseQuotaMounts();
static int64_t GetDiskUsageFromQuota(const int32_t uid);
static bool ScanDir(
const std::string &dirPath, ScanMode scanMode, ResultMode resultMode, std::vector<std::string> &paths);

View File

@ -104,7 +104,8 @@ public:
* @param bundleStats Indicates the bundle Stats.
* @return Returns ERR_OK if get stats successfully; returns error code otherwise.
*/
ErrCode GetBundleStats(const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats);
ErrCode GetBundleStats(const std::string &bundleName, const int32_t userId,
std::vector<int64_t> &bundleStats, const int32_t uid = Constants::INVALID_UID);
/**
* @brief Reset the installd proxy object when installd service died.

View File

@ -151,7 +151,7 @@ public:
* @return Returns ERR_OK if get stats successfully; returns error code otherwise.
*/
virtual ErrCode GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
return ERR_OK;
}

View File

@ -19,6 +19,7 @@
#include <string>
#include "appexecfwk_errors.h"
#include "bundle_constants.h"
#include "bundle_framework_services_ipc_interface_code.h"
#include "iremote_proxy.h"
#include "ipc/installd_interface.h"
@ -108,8 +109,8 @@ public:
* @param bundleStats Indicates the bundle Stats.
* @return Returns ERR_OK if get stats successfully; returns error code otherwise.
*/
virtual ErrCode GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats) override;
virtual ErrCode GetBundleStats(const std::string &bundleName, const int32_t userId,
std::vector<int64_t> &bundleStats, const int32_t uid = Constants::INVALID_UID) override;
/**
* @brief Set dir apl.
* @param dir Indicates the data dir.

View File

@ -13,7 +13,7 @@
"importance" : -20,
"uid" : "installs",
"gid" : ["installs", "update"],
"caps" : ["DAC_OVERRIDE", "CHOWN", "FOWNER"],
"caps" : ["DAC_OVERRIDE", "CHOWN", "FOWNER", "SYS_ADMIN"],
"secon" : "u:r:installs:s0",
"permission": [
"ohos.permission.STORAGE_MANAGER",

View File

@ -2344,7 +2344,8 @@ bool BundleDataMgr::GetBundleStats(
return false;
}
int32_t responseUserId = infoItem->second.GetResponseUserId(userId);
if (InstalldClient::GetInstance()->GetBundleStats(bundleName, responseUserId, bundleStats) != ERR_OK) {
int32_t uid = infoItem->second.GetUid(responseUserId);
if (InstalldClient::GetInstance()->GetBundleStats(bundleName, responseUserId, bundleStats, uid) != ERR_OK) {
APP_LOGW("bundle%{public}s GetBundleStats failed ", bundleName.c_str());
return false;
}

View File

@ -634,7 +634,7 @@ std::string InstalldHostImpl::GetBundleDataDir(const std::string &el, const int
}
ErrCode InstalldHostImpl::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) {
APP_LOGE("installd permission denied, only used for foundation process");
@ -669,28 +669,12 @@ ErrCode InstalldHostImpl::GetBundleStats(
int64_t systemFolderSize = allBundleLocalSize - bundleLocalSize;
// index 0 : bundle data size
bundleStats.push_back(fileSize + systemFolderSize);
int64_t cacheSize = InstalldOperator::GetDiskUsageFromPath(cachePath);
bundleLocalSize -= cacheSize;
int64_t bundleDataSize = InstalldOperator::GetDiskUsageFromQuota(uid);
// index 1 : local bundle data size
bundleStats.push_back(bundleLocalSize);
// index 2 : distributed data size
std::string distributedfilePath = DISTRIBUTED_FILE;
distributedfilePath = distributedfilePath.replace(distributedfilePath.find("%"), 1, std::to_string(userId)) +
bundleName;
int64_t distributedFileSize = InstalldOperator::GetDiskUsage(distributedfilePath);
bundleStats.push_back(distributedFileSize);
// index 3 : database size
std::vector<std::string> dataBasePath;
for (const auto &el : Constants::BUNDLE_EL) {
std::string filePath = Constants::BUNDLE_APP_DATA_BASE_DIR + el + Constants::PATH_SEPARATOR +
std::to_string(userId) + Constants::DATABASE + bundleName;
dataBasePath.push_back(filePath);
}
int64_t databaseFileSize = InstalldOperator::GetDiskUsageFromPath(dataBasePath);
bundleStats.push_back(databaseFileSize);
bundleStats.push_back(bundleDataSize);
bundleStats.push_back(0);
bundleStats.push_back(0);
int64_t cacheSize = InstalldOperator::GetDiskUsageFromPath(cachePath);
// index 4 : cache size
bundleStats.push_back(cacheSize);
return ERR_OK;

View File

@ -36,6 +36,7 @@
#include <sstream>
#include <string.h>
#include <sys/mman.h>
#include <sys/quota.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@ -57,6 +58,8 @@ static std::string PREFIX_TARGET_PATH = "/print_service/";
static const std::string SO_SUFFIX_REGEX = "\\.so\\.[0-9][0-9]*$";
static constexpr int32_t INSTALLS_UID = 3060;
static constexpr int32_t MODE_BASE = 07777;
static const std::string PROC_MOUNTS_PATH = "/proc/mounts";
static const std::string QUOTA_DEVICE_DATA_PATH = "/data";
#if defined(CODE_SIGNATURE_ENABLE)
using namespace OHOS::Security::CodeSign;
#endif
@ -65,6 +68,8 @@ static std::string CODE_DECRYPT = "/dev/code_decrypt";
static int32_t INVALID_RETURN_VALUE = -1;
static int32_t INVALID_FILE_DESCRIPTOR = -1;
#endif
std::recursive_mutex mMountsLock;
static std::map<std::string, std::string> mQuotaReverseMounts;
using ApplyPatch = int32_t (*)(const std::string, const std::string, const std::string);
static std::string HandleScanResult(
@ -752,6 +757,66 @@ int64_t InstalldOperator::GetDiskUsageFromPath(const std::vector<std::string> &p
return fileSize;
}
bool InstalldOperator::InitialiseQuotaMounts()
{
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
mQuotaReverseMounts.clear();
std::ifstream mountsFile(PROC_MOUNTS_PATH);
if (!mountsFile.is_open()) {
APP_LOGE("Failed to open mounts file");
return false;
}
std::string line;
while (std::getline(mountsFile, line)) {
std::string device;
std::string mountPoint;
std::string fsType;
std::istringstream lineStream(line);
if (!(lineStream >> device >> mountPoint >> fsType)) {
APP_LOGW("Failed to parse mounts file line: %{public}s", line.c_str());
continue;
}
if (mountPoint == QUOTA_DEVICE_DATA_PATH) {
struct dqblk dq;
if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), 0, reinterpret_cast<char*>(&dq)) == 0) {
mQuotaReverseMounts[mountPoint] = device;
APP_LOGD("InitialiseQuotaMounts, mountPoint: %{public}s, device: %{public}s", mountPoint.c_str(),
device.c_str());
} else {
APP_LOGW("InitialiseQuotaMounts, Failed to get quotactl, errno: %{public}d", errno);
}
}
}
return true;
}
int64_t InstalldOperator::GetDiskUsageFromQuota(const int32_t uid)
{
std::string device = "";
if (mQuotaReverseMounts.find(QUOTA_DEVICE_DATA_PATH) == mQuotaReverseMounts.end()) {
if (!InitialiseQuotaMounts()) {
APP_LOGE("Failed to initialise quota mounts");
return 0;
}
}
device = mQuotaReverseMounts[QUOTA_DEVICE_DATA_PATH];
if (device.empty()) {
APP_LOGW("skip when device no quotas present");
return 0;
}
struct dqblk dq;
if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid, reinterpret_cast<char*>(&dq)) != 0) {
APP_LOGE("Failed to get quotactl, errno: %{public}d", errno);
return 0;
}
APP_LOGD("get disk usage from quota, uid: %{public}d, usage: %{public}llu", uid, dq.dqb_curspace);
return dq.dqb_curspace;
}
bool InstalldOperator::ScanDir(
const std::string &dirPath, ScanMode scanMode, ResultMode resultMode, std::vector<std::string> &paths)
{

View File

@ -142,14 +142,14 @@ ErrCode InstalldClient::CleanBundleDataDirByName(const std::string &bundleName,
}
ErrCode InstalldClient::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
if (bundleName.empty()) {
APP_LOGE("bundleName is empty");
return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
}
return CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats);
return CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats, uid);
}
ErrCode InstalldClient::SetDirApl(const std::string &dir, const std::string &bundleName, const std::string &apl,

View File

@ -285,8 +285,9 @@ bool InstalldHost::HandleGetBundleStats(MessageParcel &data, MessageParcel &repl
{
std::string bundleName = Str16ToStr8(data.ReadString16());
int32_t userId = data.ReadInt32();
int32_t uid = data.ReadInt32();
std::vector<int64_t> bundleStats;
ErrCode result = GetBundleStats(bundleName, userId, bundleStats);
ErrCode result = GetBundleStats(bundleName, userId, bundleStats, uid);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, reply, result);
if (!reply.WriteInt64Vector(bundleStats)) {
APP_LOGE("HandleGetBundleStats write failed");

View File

@ -197,12 +197,13 @@ ErrCode InstalldProxy::CleanBundleDataDirByName(const std::string &bundleName, c
}
ErrCode InstalldProxy::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
MessageParcel data;
INSTALLD_PARCEL_WRITE_INTERFACE_TOKEN(data, (GetDescriptor()));
INSTALLD_PARCEL_WRITE(data, String16, Str8ToStr16(bundleName));
INSTALLD_PARCEL_WRITE(data, Int32, userId);
INSTALLD_PARCEL_WRITE(data, Int32, uid);
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
auto ret = TransactInstalldCmd(InstalldInterfaceCode::GET_BUNDLE_STATS, data, reply, option);

View File

@ -136,14 +136,14 @@ ErrCode InstalldClient::CleanBundleDataDirByName(
}
ErrCode InstalldClient::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
if (bundleName.empty()) {
APP_LOGE("bundleName is empty");
return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR;
}
return CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats);
return CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats, uid);
}
ErrCode InstalldClient::SetDirApl(const std::string &dir, const std::string &bundleName, const std::string &apl,

View File

@ -88,7 +88,7 @@ ErrCode InstalldClient::CleanBundleDataDirByName(const std::string &bundleName,
}
ErrCode InstalldClient::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
return 0;
}

View File

@ -86,7 +86,7 @@ std::string InstalldHostImpl::GetBundleDataDir(const std::string &el, const int
}
ErrCode InstalldHostImpl::GetBundleStats(
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats)
const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats, const int32_t uid)
{
return ERR_OK;
}

View File

@ -1115,11 +1115,12 @@ HWTEST_F(BmsBundleInstallerTest, GetBundleStats_001, Function | SmallTest | Leve
EXPECT_EQ(installResult, ERR_OK);
std::vector<int64_t> bundleStats;
auto ret = InstalldClient::GetInstance()->GetBundleStats(BUNDLE_BACKUP_NAME, USERID, bundleStats);
auto ret = InstalldClient::GetInstance()->GetBundleStats(BUNDLE_BACKUP_NAME, USERID, bundleStats, 0);
EXPECT_EQ(ret, ERR_OK);
if (!bundleStats.empty()) {
EXPECT_NE(bundleStats[0], 0);
for (size_t index = NUMBER_ONE; index < bundleStats.size(); index++) {
EXPECT_NE(bundleStats[1], 0);
for (size_t index = 2; index < bundleStats.size(); index++) {
EXPECT_EQ(bundleStats[index], 0);
}
}
@ -2540,7 +2541,7 @@ HWTEST_F(BmsBundleInstallerTest, InstalldHostImpl_1500, Function | SmallTest | L
{
InstalldHostImpl impl;
std::vector<int64_t> bundleStats;
ErrCode ret = impl.GetBundleStats("", USERID, bundleStats);
ErrCode ret = impl.GetBundleStats("", USERID, bundleStats, 0);
EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR);
}

View File

@ -216,7 +216,7 @@ HWTEST_F(BmsInstallDaemonHostImplTest, InstalldHostImplTest_0900, Function | Sma
ASSERT_NE(hostImpl, nullptr);
std::vector<int64_t> vec;
auto ret = hostImpl->GetBundleStats(TEST_STRING, 0, vec);
auto ret = hostImpl->GetBundleStats(TEST_STRING, 0, vec, 0);
EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED);
}
@ -660,7 +660,7 @@ HWTEST_F(BmsInstallDaemonHostImplTest, InstalldHostImplTest_3600, Function | Sma
ASSERT_NE(hostImpl, nullptr);
std::vector<int64_t> vec;
auto ret = hostImpl->GetBundleStats("", 0, vec);
auto ret = hostImpl->GetBundleStats("", 0, vec, 0);
EXPECT_NE(ret, ERR_OK);
}

View File

@ -296,7 +296,7 @@ HWTEST_F(BmsInstallDaemonIpcTest, InstalldProxyTest_0900, Function | SmallTest |
EXPECT_NE(proxy, nullptr);
std::vector<int64_t> vec;
auto ret = proxy->GetBundleStats(TEST_STRING, 0, vec);
auto ret = proxy->GetBundleStats(TEST_STRING, 0, vec, 0);
EXPECT_EQ(ret, ERR_OK);
}

View File

@ -71,7 +71,8 @@ public:
int RenameModuleDir(const std::string &oldPath, const std::string &newPath) const;
bool CheckBundleDirExist() const;
bool CheckBundleDataDirExist() const;
bool GetBundleStats(const std::string &bundleName, const int32_t userId, std::vector<int64_t> &bundleStats) const;
bool GetBundleStats(const std::string &bundleName, const int32_t userId,
std::vector<int64_t> &bundleStats, const int32_t uid) const;
int32_t GetNativeLibraryFileNames(const std::string &filePath, const std::string &cpuAbi,
std::vector<std::string> &fileNames) const;
private:
@ -200,12 +201,12 @@ bool BmsInstallDaemonTest::CheckBundleDataDirExist() const
}
bool BmsInstallDaemonTest::GetBundleStats(const std::string &bundleName, const int32_t userId,
std::vector<int64_t> &bundleStats) const
std::vector<int64_t> &bundleStats, const int32_t uid) const
{
if (!service_->IsServiceReady()) {
service_->Start();
}
if (InstalldClient::GetInstance()->GetBundleStats(bundleName, userId, bundleStats) == ERR_OK) {
if (InstalldClient::GetInstance()->GetBundleStats(bundleName, userId, bundleStats, uid) == ERR_OK) {
return true;
}
return false;
@ -808,7 +809,7 @@ HWTEST_F(BmsInstallDaemonTest, ExtractBundleFile_0500, Function | SmallTest | Le
HWTEST_F(BmsInstallDaemonTest, GetBundleStats_0100, Function | SmallTest | Level0)
{
std::vector<int64_t> stats;
bool result = GetBundleStats("", 0, stats);
bool result = GetBundleStats("", 0, stats, 0);
EXPECT_EQ(result, false);
}
@ -820,11 +821,13 @@ HWTEST_F(BmsInstallDaemonTest, GetBundleStats_0100, Function | SmallTest | Level
HWTEST_F(BmsInstallDaemonTest, GetBundleStats_0200, Function | SmallTest | Level0)
{
std::vector<int64_t> stats;
bool result = GetBundleStats(BUNDLE_NAME13, 0, stats);
bool result = GetBundleStats(BUNDLE_NAME13, 0, stats, 0);
EXPECT_EQ(result, true);
for (const auto &t : stats) {
EXPECT_EQ(t, 0);
}
EXPECT_EQ(stats[0], 0);
EXPECT_NE(stats[1], 0);
EXPECT_EQ(stats[2], 0);
EXPECT_EQ(stats[3], 0);
EXPECT_EQ(stats[4], 0);
}
/**
@ -836,9 +839,9 @@ HWTEST_F(BmsInstallDaemonTest, GetBundleStats_0300, Function | SmallTest | Level
{
OHOS::ForceCreateDirectory(BUNDLE_CODE_DIR_CODE);
std::vector<int64_t> stats;
bool result = GetBundleStats(BUNDLE_NAME13, 0, stats);
bool result = GetBundleStats(BUNDLE_NAME13, 0, stats, 0);
EXPECT_EQ(result, true);
EXPECT_EQ(stats[1], 0);
EXPECT_NE(stats[1], 0);
OHOS::ForceRemoveDirectory(BUNDLE_CODE_DIR_CODE);
}
@ -855,12 +858,12 @@ HWTEST_F(BmsInstallDaemonTest, GetBundleStats_0400, Function | SmallTest | Level
OHOS::ForceCreateDirectory(BUNDLE_DATA_DIR_DATA_BASE);
OHOS::ForceCreateDirectory(BUNDLE_DATA_DIR_DATA_BASE_TEMP);
std::vector<int64_t> stats;
bool result = GetBundleStats(BUNDLE_NAME13, USERID, stats);
bool result = GetBundleStats(BUNDLE_NAME13, USERID, stats, 0);
EXPECT_EQ(result, true);
EXPECT_NE(stats[0], 0);
EXPECT_NE(stats[1], 0);
EXPECT_EQ(stats[2], 0); // distributed file does not exist
EXPECT_NE(stats[3], 0);
EXPECT_EQ(stats[3], 0);
EXPECT_NE(stats[4], 0);
OHOS::ForceRemoveDirectory(BUNDLE_DATA_DIR_CACHE);
OHOS::ForceRemoveDirectory(BUNDLE_DATA_DIR_TEMP);

View File

@ -514,7 +514,7 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_GetBundleStats_0100, TestS
std::string bundleName = EMPTY_STRING;
int userId = USERID;
std::vector<int64_t> bundleStats;
ErrCode result = installClient_->GetBundleStats(bundleName, userId, bundleStats);
ErrCode result = installClient_->GetBundleStats(bundleName, userId, bundleStats, 0);
EXPECT_EQ(result, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR);
GTEST_LOG_(INFO) << "BmsInstalldClientTest_GetBundleStats_0100 end";
}
@ -530,8 +530,8 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_GetBundleStats_0200, TestS
std::string bundleName = BUNDLE_NAME;
int userId = USERID;
std::vector<int64_t> bundleStats;
ErrCode result = installClient_->GetBundleStats(bundleName, userId, bundleStats);
EXPECT_EQ(result, installClient_->CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats));
ErrCode result = installClient_->GetBundleStats(bundleName, userId, bundleStats, 0);
EXPECT_EQ(result, installClient_->CallService(&IInstalld::GetBundleStats, bundleName, userId, bundleStats, 0));
GTEST_LOG_(INFO) << "BmsInstalldClientTest_GetBundleStats_0200 end";
}