make 'mode, uid, gid' triplet separate atomized struct
there are only few combinations for that triplet, and they occur multiple times reducing the struct sizes a bit. make sane defaults and prepare to not write defaults to disk to reduce on-disk installed db size.cute-signatures
parent
36d5b91495
commit
4f823f2a50
|
@ -24,16 +24,21 @@
|
|||
struct apk_name;
|
||||
APK_ARRAY(apk_name_array, struct apk_name *);
|
||||
|
||||
struct apk_db_acl {
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
struct apk_db_file {
|
||||
struct hlist_node hash_node;
|
||||
struct hlist_node diri_files_list;
|
||||
|
||||
struct apk_db_dir_instance *diri;
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct apk_db_acl *acl;
|
||||
|
||||
unsigned short namelen;
|
||||
unsigned short audited : 1;
|
||||
unsigned short namelen : 15;
|
||||
struct apk_checksum csum;
|
||||
char name[];
|
||||
};
|
||||
|
@ -84,9 +89,7 @@ struct apk_db_dir_instance {
|
|||
struct hlist_head owned_files;
|
||||
struct apk_package *pkg;
|
||||
struct apk_db_dir *dir;
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct apk_db_acl *acl;
|
||||
};
|
||||
|
||||
struct apk_name {
|
||||
|
|
12
src/audit.c
12
src/audit.c
|
@ -97,7 +97,7 @@ static int audit_file(struct audit_ctx *actx,
|
|||
if (dbf == NULL)
|
||||
return 'A';
|
||||
|
||||
dbf->mode |= S_SEENFLAG;
|
||||
dbf->audited = 1;
|
||||
|
||||
if (apk_file_get_info(dirfd, name, APK_FI_NOFOLLOW | dbf->csum.type, &fi) != 0)
|
||||
return -EPERM;
|
||||
|
@ -109,11 +109,10 @@ static int audit_file(struct audit_ctx *actx,
|
|||
if (S_ISLNK(fi.mode) && dbf->csum.type == APK_CHECKSUM_NONE)
|
||||
return 'U';
|
||||
|
||||
if (actx->check_permissions &&
|
||||
(dbf->mode != 0 || dbf->uid != 0 || dbf->gid != 0)) {
|
||||
if ((fi.mode & 07777) != (dbf->mode & 07777))
|
||||
if (actx->check_permissions) {
|
||||
if ((fi.mode & 07777) != (dbf->acl->mode & 07777))
|
||||
return 'M';
|
||||
if (fi.uid != dbf->uid || fi.gid != dbf->gid)
|
||||
if (fi.uid != dbf->acl->uid || fi.gid != dbf->acl->gid)
|
||||
return 'M';
|
||||
}
|
||||
|
||||
|
@ -293,8 +292,7 @@ static int audit_missing_files(apk_hash_item item, void *pctx)
|
|||
char path[PATH_MAX];
|
||||
int len;
|
||||
|
||||
if (file->mode & S_SEENFLAG)
|
||||
return 0;
|
||||
if (file->audited) return 0;
|
||||
|
||||
dir = file->diri->dir;
|
||||
if (dir->mode & S_SEENFLAG) {
|
||||
|
|
|
@ -72,6 +72,8 @@ const char * const apk_installed_file = "lib/apk/db/installed";
|
|||
static const char * const apk_installed_file_tmp = "lib/apk/db/installed.new";
|
||||
static const char * const apk_installed_file_old = "var/lib/apk/installed";
|
||||
|
||||
static struct apk_db_acl *apk_default_acl_dir, *apk_default_acl_file;
|
||||
|
||||
struct install_ctx {
|
||||
struct apk_database *db;
|
||||
struct apk_package *pkg;
|
||||
|
@ -222,6 +224,14 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
|
|||
return pn;
|
||||
}
|
||||
|
||||
static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
struct apk_db_acl acl = { .mode = mode & 07777, .uid = uid, .gid = gid };
|
||||
apk_blob_t *b;
|
||||
b = apk_blob_atomize_dup(APK_BLOB_STRUCT(acl));
|
||||
return (struct apk_db_acl *) b->ptr;
|
||||
}
|
||||
|
||||
static void apk_db_dir_prepare(struct apk_database *db, struct apk_db_dir *dir, mode_t newmode)
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -356,6 +366,7 @@ static struct apk_db_dir_instance *apk_db_diri_new(struct apk_database *db,
|
|||
*after = &diri->pkg_dirs_list.next;
|
||||
diri->dir = apk_db_dir_get(db, name);
|
||||
diri->pkg = pkg;
|
||||
diri->acl = apk_default_acl_dir;
|
||||
}
|
||||
|
||||
return diri;
|
||||
|
@ -364,23 +375,20 @@ static struct apk_db_dir_instance *apk_db_diri_new(struct apk_database *db,
|
|||
static void apk_db_dir_apply_diri_permissions(struct apk_db_dir_instance *diri)
|
||||
{
|
||||
struct apk_db_dir *dir = diri->dir;
|
||||
struct apk_db_acl *acl = diri->acl;
|
||||
|
||||
if (diri->uid < dir->uid ||
|
||||
(diri->uid == dir->uid && diri->gid < dir->gid)) {
|
||||
dir->uid = diri->uid;
|
||||
dir->gid = diri->gid;
|
||||
dir->mode = diri->mode;
|
||||
} else if (diri->uid == dir->uid && diri->gid == dir->gid) {
|
||||
dir->mode &= diri->mode;
|
||||
if (acl->uid < dir->uid || (acl->uid == dir->uid && acl->gid < dir->gid)) {
|
||||
dir->uid = acl->uid;
|
||||
dir->gid = acl->gid;
|
||||
dir->mode = acl->mode;
|
||||
} else if (acl->uid == dir->uid && acl->gid == dir->gid) {
|
||||
dir->mode &= acl->mode;
|
||||
}
|
||||
}
|
||||
|
||||
static void apk_db_diri_set(struct apk_db_dir_instance *diri, mode_t mode,
|
||||
uid_t uid, gid_t gid)
|
||||
static void apk_db_diri_set(struct apk_db_dir_instance *diri, struct apk_db_acl *acl)
|
||||
{
|
||||
diri->mode = mode & 07777;
|
||||
diri->uid = uid;
|
||||
diri->gid = gid;
|
||||
diri->acl = acl;
|
||||
apk_db_dir_apply_diri_permissions(diri);
|
||||
}
|
||||
|
||||
|
@ -431,19 +439,13 @@ static struct apk_db_file *apk_db_file_new(struct apk_db_dir_instance *diri,
|
|||
file->namelen = name.len;
|
||||
|
||||
file->diri = diri;
|
||||
file->acl = apk_default_acl_file;
|
||||
hlist_add_after(&file->diri_files_list, *after);
|
||||
*after = &file->diri_files_list.next;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static void apk_db_file_set(struct apk_db_file *file, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
file->mode = mode & 07777;
|
||||
file->uid = uid;
|
||||
file->gid = gid;
|
||||
}
|
||||
|
||||
static struct apk_db_file *apk_db_file_get(struct apk_database *db,
|
||||
struct apk_db_dir_instance *diri,
|
||||
apk_blob_t name,
|
||||
|
@ -737,6 +739,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
|||
struct apk_installed_package *ipkg = NULL;
|
||||
struct apk_db_dir_instance *diri = NULL;
|
||||
struct apk_db_file *file = NULL;
|
||||
struct apk_db_acl *acl;
|
||||
struct hlist_node **diri_node = NULL;
|
||||
struct hlist_node **file_diri_node = NULL;
|
||||
apk_blob_t token = APK_BLOB_STR("\n"), l;
|
||||
|
@ -813,10 +816,11 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
|||
gid = apk_blob_pull_uint(&l, 10);
|
||||
apk_blob_pull_char(&l, ':');
|
||||
mode = apk_blob_pull_uint(&l, 8);
|
||||
acl = apk_db_acl_atomize(mode, uid, gid);
|
||||
if (field == 'M')
|
||||
apk_db_diri_set(diri, mode, uid, gid);
|
||||
apk_db_diri_set(diri, acl);
|
||||
else
|
||||
apk_db_file_set(file, mode, uid, gid);
|
||||
file->acl = acl;
|
||||
break;
|
||||
case 'R':
|
||||
if (diri == NULL) goto bad_entry;
|
||||
|
@ -866,6 +870,19 @@ bad_entry:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void apk_blob_push_db_acl(apk_blob_t *b, char field, struct apk_db_acl *acl)
|
||||
{
|
||||
char hdr[2] = { field, ':' };
|
||||
|
||||
apk_blob_push_blob(b, APK_BLOB_BUF(hdr));
|
||||
apk_blob_push_uint(b, acl->uid, 10);
|
||||
apk_blob_push_blob(b, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(b, acl->gid, 10);
|
||||
apk_blob_push_blob(b, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(b, acl->mode, 8);
|
||||
apk_blob_push_blob(b, APK_BLOB_STR("\n"));
|
||||
}
|
||||
|
||||
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||
{
|
||||
struct apk_installed_package *ipkg;
|
||||
|
@ -909,31 +926,25 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
|||
hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:"));
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN(diri->dir->name, diri->dir->namelen));
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nM:"));
|
||||
apk_blob_push_uint(&bbuf, diri->uid, 10);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(&bbuf, diri->gid, 10);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(&bbuf, diri->mode, 8);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||
|
||||
if (1 || diri->acl != apk_default_acl_dir)
|
||||
apk_blob_push_db_acl(&bbuf, 'M', diri->acl);
|
||||
|
||||
hlist_for_each_entry(file, c2, &diri->owned_files, diri_files_list) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("R:"));
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN(file->name, file->namelen));
|
||||
if (file->mode != 0 || file->uid != 0 || file->gid != 0) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\na:"));
|
||||
apk_blob_push_uint(&bbuf, file->uid, 10);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(&bbuf, file->gid, 10);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
||||
apk_blob_push_uint(&bbuf, file->mode, 8);
|
||||
}
|
||||
if (file->csum.type != APK_CHECKSUM_NONE) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nZ:"));
|
||||
apk_blob_push_csum(&bbuf, &file->csum);
|
||||
}
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||
|
||||
if (1 || file->acl != apk_default_acl_file)
|
||||
apk_blob_push_db_acl(&bbuf, 'a', file->acl);
|
||||
|
||||
if (file->csum.type != APK_CHECKSUM_NONE) {
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("Z:"));
|
||||
apk_blob_push_csum(&bbuf, &file->csum);
|
||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||
}
|
||||
|
||||
if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
|
||||
return -EIO;
|
||||
bbuf = APK_BLOB_BUF(buf);
|
||||
|
@ -1440,6 +1451,9 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
|
|||
apk_blob_t blob;
|
||||
int r, fd, write_arch = FALSE;
|
||||
|
||||
apk_default_acl_dir = apk_db_acl_atomize(0755, 0, 0);
|
||||
apk_default_acl_file = apk_db_acl_atomize(0644, 0, 0);
|
||||
|
||||
memset(db, 0, sizeof(*db));
|
||||
if (apk_flags & APK_SIMULATE) {
|
||||
dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
|
||||
|
@ -2363,7 +2377,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
|||
apk_message("%s", ae->name);
|
||||
|
||||
/* Extract the file as name.apk-new */
|
||||
apk_db_file_set(file, ae->mode, ae->uid, ae->gid);
|
||||
file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid);
|
||||
r = apk_archive_entry_extract(db->root_fd, ae, ".apk-new", is,
|
||||
extract_cb, ctx);
|
||||
|
||||
|
@ -2405,7 +2419,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
|||
|
||||
diri = apk_db_install_directory_entry(ctx, name);
|
||||
apk_db_dir_prepare(db, diri->dir, ae->mode);
|
||||
apk_db_diri_set(diri, ae->mode, ae->uid, ae->gid);
|
||||
apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid));
|
||||
}
|
||||
ctx->installed_size += ctx->current_file_size;
|
||||
|
||||
|
|
Loading…
Reference in New Issue