tar: cache [ug]id->username/groupname mappings. Cuts down amount
of open/read/close of /etc/passwd and /etc/group dramatically (we were rereading those for each untarred file!!!)
This commit is contained in:
parent
4fbb584a0e
commit
c50f370f98
@ -211,12 +211,9 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
|
|||||||
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
|
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
|
||||||
strcpy(header.magic, "ustar ");
|
strcpy(header.magic, "ustar ");
|
||||||
|
|
||||||
/* Enter the user and group names (default to root if it fails) */
|
/* Enter the user and group names */
|
||||||
//cache!!!
|
safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname));
|
||||||
if (bb_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL)
|
safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname));
|
||||||
strcpy(header.uname, "root");
|
|
||||||
if (bb_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL)
|
|
||||||
strcpy(header.gname, "root");
|
|
||||||
|
|
||||||
if (tbInfo->hlInfo) {
|
if (tbInfo->hlInfo) {
|
||||||
/* This is a hard link */
|
/* This is a hard link */
|
||||||
|
@ -567,6 +567,7 @@ pid_t *find_pid_by_name(const char* procName);
|
|||||||
pid_t *pidlist_reverse(pid_t *pidList);
|
pid_t *pidlist_reverse(pid_t *pidList);
|
||||||
void clear_username_cache(void);
|
void clear_username_cache(void);
|
||||||
const char* get_cached_username(uid_t uid);
|
const char* get_cached_username(uid_t uid);
|
||||||
|
const char* get_cached_groupname(gid_t gid);
|
||||||
|
|
||||||
|
|
||||||
extern const char bb_uuenc_tbl_base64[];
|
extern const char bb_uuenc_tbl_base64[];
|
||||||
|
@ -11,32 +11,62 @@
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct unsigned_to_name_map_t {
|
||||||
uid_t uid;
|
unsigned id;
|
||||||
char username[12];
|
char name[12];
|
||||||
} user_map_t;
|
} unsigned_to_name_map_t;
|
||||||
|
|
||||||
static user_map_t *username_cache;
|
typedef struct cache_t {
|
||||||
static int username_cache_size;
|
unsigned_to_name_map_t *cache;
|
||||||
|
int size;
|
||||||
|
} cache_t;
|
||||||
|
|
||||||
|
static cache_t username, groupname;
|
||||||
|
|
||||||
|
static void clear_cache(cache_t *cp)
|
||||||
|
{
|
||||||
|
free(cp->cache);
|
||||||
|
cp->cache = NULL;
|
||||||
|
cp->size = 0;
|
||||||
|
}
|
||||||
void clear_username_cache(void)
|
void clear_username_cache(void)
|
||||||
{
|
{
|
||||||
free(username_cache);
|
clear_cache(&username);
|
||||||
username_cache = NULL;
|
clear_cache(&groupname);
|
||||||
username_cache_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* get_cached_username(uid_t uid)
|
/* Returns -N-1 if not found. */
|
||||||
|
/* cp->cache[N] is allocated and must be filled in this case */
|
||||||
|
static int get_cached(cache_t *cp, unsigned id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < username_cache_size; i++)
|
for (i = 0; i < cp->size; i++)
|
||||||
if (username_cache[i].uid == uid)
|
if (cp->cache[i].id == id)
|
||||||
return username_cache[i].username;
|
return i;
|
||||||
i = username_cache_size++;
|
i = cp->size++;
|
||||||
username_cache = xrealloc(username_cache, username_cache_size * sizeof(*username_cache));
|
cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache));
|
||||||
username_cache[i].uid = uid;
|
cp->cache[i++].id = id;
|
||||||
bb_getpwuid(username_cache[i].username, uid, sizeof(username_cache[i].username));
|
return -i;
|
||||||
return username_cache[i].username;
|
}
|
||||||
|
const char* get_cached_username(uid_t uid)
|
||||||
|
{
|
||||||
|
int i = get_cached(&username, uid);
|
||||||
|
if (i < 0) {
|
||||||
|
i = -i - 1;
|
||||||
|
bb_getpwuid(username.cache[i].name, uid,
|
||||||
|
sizeof(username.cache[i].name));
|
||||||
|
}
|
||||||
|
return username.cache[i].name;
|
||||||
|
}
|
||||||
|
const char* get_cached_groupname(uid_t uid)
|
||||||
|
{
|
||||||
|
int i = get_cached(&groupname, uid);
|
||||||
|
if (i < 0) {
|
||||||
|
i = -i - 1;
|
||||||
|
bb_getgrgid(groupname.cache[i].name, uid,
|
||||||
|
sizeof(groupname.cache[i].name));
|
||||||
|
}
|
||||||
|
return username.cache[i].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user