Add an installd command to prune dex files.
This is a straightforward port of logic from PackageManagerService#pruneDexFiles. bug: 14407732 Change-Id: I892cff027ddcbb1a4fb37a7af5ecf1697049a188
This commit is contained in:
parent
065e9c86e2
commit
3aee2c5c74
@ -73,7 +73,7 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (S_ISDIR(libStat.st_mode)) {
|
if (S_ISDIR(libStat.st_mode)) {
|
||||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
|
||||||
ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
|
ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -176,6 +176,10 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_dir_matcher(const char* file_name, const int is_dir) {
|
||||||
|
return is_dir && !strcmp(file_name, "lib");
|
||||||
|
}
|
||||||
|
|
||||||
int delete_user_data(const char *pkgname, userid_t userid)
|
int delete_user_data(const char *pkgname, userid_t userid)
|
||||||
{
|
{
|
||||||
char pkgdir[PKG_PATH_MAX];
|
char pkgdir[PKG_PATH_MAX];
|
||||||
@ -184,7 +188,7 @@ int delete_user_data(const char *pkgname, userid_t userid)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* delete contents, excluding "lib", but not the directory itself */
|
/* delete contents, excluding "lib", but not the directory itself */
|
||||||
return delete_dir_contents(pkgdir, 0, "lib");
|
return delete_dir_contents(pkgdir, 0, &lib_dir_matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
|
int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
|
||||||
@ -225,7 +229,7 @@ int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char*
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (S_ISDIR(libStat.st_mode)) {
|
if (S_ISDIR(libStat.st_mode)) {
|
||||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
|
||||||
ALOGE("couldn't delete lib directory during install for non-primary: %s",
|
ALOGE("couldn't delete lib directory during install for non-primary: %s",
|
||||||
libsymlink);
|
libsymlink);
|
||||||
unlink(pkgdir);
|
unlink(pkgdir);
|
||||||
@ -294,7 +298,7 @@ int delete_cache(const char *pkgname, userid_t userid)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* delete contents, not the directory, no exceptions */
|
/* delete contents, not the directory, no exceptions */
|
||||||
return delete_dir_contents(cachedir, 0, 0);
|
return delete_dir_contents(cachedir, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to ensure free_size bytes of storage are available.
|
/* Try to ensure free_size bytes of storage are available.
|
||||||
@ -1105,7 +1109,7 @@ int linklib(const char* pkgname, const char* asecLibDir, int userId)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (S_ISDIR(libStat.st_mode)) {
|
if (S_ISDIR(libStat.st_mode)) {
|
||||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1330,3 +1334,30 @@ int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid)
|
|||||||
free(userdir);
|
free(userdir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prune_dex_exclusion_predicate(const char *file_name, const int is_dir)
|
||||||
|
{
|
||||||
|
// Don't exclude any directories, we want to inspect them
|
||||||
|
// recusively for files.
|
||||||
|
if (is_dir) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Don't exclude regular files that start with the list
|
||||||
|
// of prefixes.
|
||||||
|
static const char data_app_prefix[] = "data@app@";
|
||||||
|
static const char data_priv_app_prefix[] = "data@priv-app@";
|
||||||
|
if (!strncmp(file_name, data_app_prefix, sizeof(data_app_prefix) - 1) ||
|
||||||
|
!strncmp(file_name, data_priv_app_prefix, sizeof(data_priv_app_prefix) - 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude all regular files that don't start with the prefix "data@app@" or
|
||||||
|
// "data@priv-app@".
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prune_dex_cache() {
|
||||||
|
return delete_dir_contents(DALVIK_CACHE_PREFIX, 0, &prune_dex_exclusion_predicate);
|
||||||
|
}
|
||||||
|
@ -135,6 +135,12 @@ static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((u
|
|||||||
/* pkgName, seinfo, uid*/
|
/* pkgName, seinfo, uid*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_prune_dex_cache(char **arg __attribute__((unused)),
|
||||||
|
char reply[REPLY_MAX] __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return prune_dex_cache();
|
||||||
|
}
|
||||||
|
|
||||||
struct cmdinfo {
|
struct cmdinfo {
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned numargs;
|
unsigned numargs;
|
||||||
@ -160,6 +166,7 @@ struct cmdinfo cmds[] = {
|
|||||||
{ "rmuser", 1, do_rm_user },
|
{ "rmuser", 1, do_rm_user },
|
||||||
{ "idmap", 3, do_idmap },
|
{ "idmap", 3, do_idmap },
|
||||||
{ "restorecondata", 3, do_restorecon_data },
|
{ "restorecondata", 3, do_restorecon_data },
|
||||||
|
{ "prunedexcache", 0, do_prune_dex_cache },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int readx(int s, void *_buf, int count)
|
static int readx(int s, void *_buf, int count)
|
||||||
|
@ -157,7 +157,7 @@ int create_cache_path(char path[PKG_PATH_MAX], const char *src,
|
|||||||
|
|
||||||
int delete_dir_contents(const char *pathname,
|
int delete_dir_contents(const char *pathname,
|
||||||
int also_delete_dir,
|
int also_delete_dir,
|
||||||
const char *ignore);
|
int (*exclusion_predicate)(const char *name, const int is_dir));
|
||||||
|
|
||||||
int delete_dir_contents_fd(int dfd, const char *name);
|
int delete_dir_contents_fd(int dfd, const char *name);
|
||||||
|
|
||||||
@ -216,3 +216,4 @@ int movefiles();
|
|||||||
int linklib(const char* target, const char* source, int userId);
|
int linklib(const char* target, const char* source, int userId);
|
||||||
int idmap(const char *target_path, const char *overlay_path, uid_t uid);
|
int idmap(const char *target_path, const char *overlay_path, uid_t uid);
|
||||||
int restorecon_data();
|
int restorecon_data();
|
||||||
|
int prune_dex_cache();
|
||||||
|
@ -208,7 +208,8 @@ int is_valid_package_name(const char* pkgname) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _delete_dir_contents(DIR *d, const char *ignore)
|
static int _delete_dir_contents(DIR *d,
|
||||||
|
int (*exclusion_predicate)(const char *name, const int is_dir))
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@ -221,8 +222,10 @@ static int _delete_dir_contents(DIR *d, const char *ignore)
|
|||||||
while ((de = readdir(d))) {
|
while ((de = readdir(d))) {
|
||||||
const char *name = de->d_name;
|
const char *name = de->d_name;
|
||||||
|
|
||||||
/* skip the ignore name if provided */
|
/* check using the exclusion predicate, if provided */
|
||||||
if (ignore && !strcmp(name, ignore)) continue;
|
if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (de->d_type == DT_DIR) {
|
if (de->d_type == DT_DIR) {
|
||||||
int r, subfd;
|
int r, subfd;
|
||||||
@ -247,7 +250,7 @@ static int _delete_dir_contents(DIR *d, const char *ignore)
|
|||||||
result = -1;
|
result = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_delete_dir_contents(subdir, 0)) {
|
if (_delete_dir_contents(subdir, exclusion_predicate)) {
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
closedir(subdir);
|
closedir(subdir);
|
||||||
@ -268,7 +271,7 @@ static int _delete_dir_contents(DIR *d, const char *ignore)
|
|||||||
|
|
||||||
int delete_dir_contents(const char *pathname,
|
int delete_dir_contents(const char *pathname,
|
||||||
int also_delete_dir,
|
int also_delete_dir,
|
||||||
const char *ignore)
|
int (*exclusion_predicate)(const char*, const int))
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
DIR *d;
|
DIR *d;
|
||||||
@ -278,7 +281,7 @@ int delete_dir_contents(const char *pathname,
|
|||||||
ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
|
ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
res = _delete_dir_contents(d, ignore);
|
res = _delete_dir_contents(d, exclusion_predicate);
|
||||||
closedir(d);
|
closedir(d);
|
||||||
if (also_delete_dir) {
|
if (also_delete_dir) {
|
||||||
if (rmdir(pathname)) {
|
if (rmdir(pathname)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user