Do not close tables on each query.
authorAndre Noll <maan@systemlinux.org>
Sun, 9 Nov 2008 00:45:42 +0000 (01:45 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 9 Nov 2008 00:45:42 +0000 (01:45 +0100)
This speeds up interactive mode where many queries may be executed
in a row. User tables are opened on demand (if the uid is admissible)
and only closed on exit. Also the dir table is opened only once per
session rather than on each query.

adu.c
create.c
interactive.c
select.c
user.c
user.h

diff --git a/adu.c b/adu.c
index 787b0e899d18cb86b20c53263603bcee735ba8ec..cbc42cb5769bc86b8e7c4ae214adaf781a63871e 100644 (file)
--- a/adu.c
+++ b/adu.c
@@ -106,6 +106,7 @@ static void close_dir_table(void)
 
        if (!dir_table)
                return;
 
        if (!dir_table)
                return;
+       NOTICE_LOG("closing dir table\n");
        ret = osl(osl_close_table(dir_table, OSL_MARK_CLEAN));
        if (ret < 0)
                ERROR_LOG("failed to close dir table: %s\n", adu_strerror(-ret));
        ret = osl(osl_close_table(dir_table, OSL_MARK_CLEAN));
        if (ret < 0)
                ERROR_LOG("failed to close dir table: %s\n", adu_strerror(-ret));
@@ -146,15 +147,20 @@ static int init_signals(void)
 
 int open_dir_table(int create)
 {
 
 int open_dir_table(int create)
 {
+
+       if (dir_table)
+               return 1;
        dir_table_desc.dir = adu_strdup(conf.database_dir_arg);
 
        if (create) {
        dir_table_desc.dir = adu_strdup(conf.database_dir_arg);
 
        if (create) {
+               NOTICE_LOG("creating dir table\n");
                int ret = osl(osl_create_table(&dir_table_desc));
                if (ret < 0) {
                        free((char *)dir_table_desc.dir);
                        return ret;
                }
        }
                int ret = osl(osl_create_table(&dir_table_desc));
                if (ret < 0) {
                        free((char *)dir_table_desc.dir);
                        return ret;
                }
        }
+       INFO_LOG("opening dir table\n");
        return osl(osl_open_table(&dir_table_desc, &dir_table));
 }
 
        return osl(osl_open_table(&dir_table_desc, &dir_table));
 }
 
@@ -249,6 +255,7 @@ int main(int argc, char **argv)
        if (ret < 0)
                goto out;
 out:
        if (ret < 0)
                goto out;
 out:
+       close_all_tables();
        if (ret < 0) {
                ERROR_LOG("%s\n", adu_strerror(-ret));
                return -EXIT_FAILURE;
        if (ret < 0) {
                ERROR_LOG("%s\n", adu_strerror(-ret));
                return -EXIT_FAILURE;
index a5bd29810539e79a24d45fa6a287a0f644771e93..29b46edb5d63dc6432b110ac8215acb02d0f441c 100644 (file)
--- a/create.c
+++ b/create.c
@@ -172,6 +172,5 @@ int com_create(void)
                goto out;
        ret = write_uid_file();
 out:
                goto out;
        ret = write_uid_file();
 out:
-       close_all_tables();
        return ret;
 }
        return ret;
 }
index 9460877e344e8f8452b0f0d20f1d6ceef83dd39e..e184dbe4fce70b65a22b54d1cacb58cd74074e43 100644 (file)
@@ -82,16 +82,18 @@ void print_interactive_help(void)
 
 static int icom_reset(__a_unused char *line)
 {
 
 static int icom_reset(__a_unused char *line)
 {
+       NOTICE_LOG("resetting configuration to default\n");
        free_format_info(fi);
        fi = NULL;
        free(admissible_uids);
        admissible_uids = NULL;
        select_cmdline_parser_init(&select_conf);
        free_format_info(fi);
        fi = NULL;
        free(admissible_uids);
        admissible_uids = NULL;
        select_cmdline_parser_init(&select_conf);
-       return 1;
+       return parse_select_options(NULL, NULL, &admissible_uids, &fi);
 }
 
 static int icom_set(char *line)
 {
 }
 
 static int icom_set(char *line)
 {
+       int ret;
        struct select_cmdline_parser_params params = {
                .override = 1,
                .initialize = 0,
        struct select_cmdline_parser_params params = {
                .override = 1,
                .initialize = 0,
@@ -108,7 +110,10 @@ static int icom_set(char *line)
        fi = NULL;
        free(admissible_uids);
        admissible_uids = NULL;
        fi = NULL;
        free(admissible_uids);
        admissible_uids = NULL;
-       return parse_select_options(line, &params, &admissible_uids, &fi);
+       ret = parse_select_options(line, &params, &admissible_uids, &fi);
+       if (ret >= 0)
+               return ret;
+       return icom_reset(NULL);
 }
 
 static int exec_interactive_command(char *line)
 }
 
 static int exec_interactive_command(char *line)
@@ -166,6 +171,11 @@ int com_interactive(void)
 
        select_cmdline_parser_init(&select_conf);
        ret = parse_select_options(NULL, NULL, &admissible_uids, &fi);
 
        select_cmdline_parser_init(&select_conf);
        ret = parse_select_options(NULL, NULL, &admissible_uids, &fi);
+       if (ret< 0)
+               return ret;
+       ret = read_uid_file();
+       if (ret < 0)
+               return ret;
        while (read_input_line(line, sizeof(line)) >= 0) {
                ret = exec_interactive_command(line);
                if (ret < 0)
        while (read_input_line(line, sizeof(line)) >= 0) {
                ret = exec_interactive_command(line);
                if (ret < 0)
index 6b1fc93f7f2464b32cbb27620408c5504b60d05f..6318d7c47b67857302f8757ba7ed5ca31a175b33 100644 (file)
--- a/select.c
+++ b/select.c
@@ -686,13 +686,12 @@ int run_select_query(struct uid_range *admissible_uids, struct format_info *fi)
        if (ret < 0)
                goto out;
        check_signals();
        if (ret < 0)
                goto out;
        check_signals();
-       ret = read_uid_file(admissible_uids);
+       ret = open_admissible_user_tables(admissible_uids);
        if (ret < 0)
                goto out;
        check_signals();
        ret = print_statistics(fi);
 out:
        if (ret < 0)
                goto out;
        check_signals();
        ret = print_statistics(fi);
 out:
-       close_all_tables();
        if (output_file && output_file != stdout) {
                fclose(output_file);
                output_file = NULL;
        if (output_file && output_file != stdout) {
                fclose(output_file);
                output_file = NULL;
@@ -802,9 +801,13 @@ int com_select(void)
        ret = parse_select_options(conf.select_options_arg, &params,
                &admissible_uids, &fi);
        if (ret > 0) {
        ret = parse_select_options(conf.select_options_arg, &params,
                &admissible_uids, &fi);
        if (ret > 0) {
+               ret = read_uid_file();
+               if (ret < 0)
+                       goto out;
                ret = run_select_query(admissible_uids, fi);
                free_format_info(fi);
        }
                ret = run_select_query(admissible_uids, fi);
                free_format_info(fi);
        }
+out:
        select_cmdline_parser_free(&select_conf);
        return ret;
 }
        select_cmdline_parser_free(&select_conf);
        return ret;
 }
diff --git a/user.c b/user.c
index 497af156905862fda844d81d832deb2ac39702d7..3f368e2a6ed6bcecdf176b23122fcb9cf49af7c8 100644 (file)
--- a/user.c
+++ b/user.c
@@ -246,7 +246,7 @@ static int open_user_table(struct user_info *ui, int create)
        if (pw && pw->pw_name)
                ui->pw_name = adu_strdup(pw->pw_name);
 
        if (pw && pw->pw_name)
                ui->pw_name = adu_strdup(pw->pw_name);
 
-       DEBUG_LOG("opening table for uid %u\n", (unsigned)ui->uid);
+       INFO_LOG("opening table for uid %u\n", (unsigned)ui->uid);
        if (create) {
                ret = osl(osl_create_table(ui->desc));
                if (ret < 0)
        if (create) {
                ret = osl(osl_create_table(ui->desc));
                if (ret < 0)
@@ -312,7 +312,7 @@ void close_user_tables(void)
                        continue;
                if (!ui->table)
                        continue;
                        continue;
                if (!ui->table)
                        continue;
-               DEBUG_LOG("closing user table for uid %u\n", (unsigned)ui->uid);
+               INFO_LOG("closing user table for uid %u\n", (unsigned)ui->uid);
                ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN));
                if (ret < 0)
                        ERROR_LOG("failed to close user table %u: %s\n",
                ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN));
                if (ret < 0)
                        ERROR_LOG("failed to close user table %u: %s\n",
@@ -393,7 +393,34 @@ void sort_hash_table(int (*comp)(const void *, const void *))
                comp);
 }
 
                comp);
 }
 
-int read_uid_file(struct uid_range *admissible_uids)
+int open_admissible_user_tables(struct uid_range *admissible_uids)
+{
+       struct user_info *ui;
+
+       assert(uid_hash_table);
+       DEBUG_LOG("size: %d\n", uid_hash_table_size);
+       FOR_EACH_USER(ui) {
+               int ret;
+
+               if (!ui_used(ui)) {
+                       continue;
+               }
+               if (!uid_is_admissible(ui->uid, admissible_uids)) {
+                       DEBUG_LOG("uid %u is not admissible\n", ui->uid);
+                       ui->flags &= ~UI_FL_ADMISSIBLE;
+                       continue;
+               }
+               ui->flags |= UI_FL_ADMISSIBLE;
+               if (ui->table)
+                       continue;
+               ret = open_user_table(ui, 0);
+               if (ret < 0)
+                       return ret;
+       }
+       return 1;
+}
+
+int read_uid_file(void)
 {
        size_t size;
        uint32_t n;
 {
        size_t size;
        uint32_t n;
@@ -423,17 +450,11 @@ int read_uid_file(struct uid_range *admissible_uids)
                assert(ui);
                if (ui_used(ui)) { /* impossible */
                        ERROR_LOG("duplicate user id!?\n");
                assert(ui);
                if (ui_used(ui)) { /* impossible */
                        ERROR_LOG("duplicate user id!?\n");
-                       ret =-EFAULT;
+                       ret = -EFAULT;
                        goto out;
                }
                ui->uid = uid;
                ui->flags |= UI_FL_SLOT_USED;
                        goto out;
                }
                ui->uid = uid;
                ui->flags |= UI_FL_SLOT_USED;
-               if (!uid_is_admissible(uid, admissible_uids))
-                       continue;
-               ui->flags |= UI_FL_ADMISSIBLE;
-               ret = open_user_table(ui, 0);
-               if (ret < 0)
-                       return ret;
        }
        ret = 1;
 out:
        }
        ret = 1;
 out:
diff --git a/user.h b/user.h
index aa07acc5213d5f2e85790b20eb84daa804ba808e..7a06876369bcf6345919d44a424a2dddff50aaa1 100644 (file)
--- a/user.h
+++ b/user.h
@@ -34,7 +34,7 @@ struct user_info {
 struct uid_range;
 
 int create_user_table(uint32_t uid, struct user_info **ui_ptr);
 struct uid_range;
 
 int create_user_table(uint32_t uid, struct user_info **ui_ptr);
-int read_uid_file(struct uid_range *admissible_uids);
+int read_uid_file(void);
 int write_uid_file(void);
 
 void create_hash_table(unsigned bits);
 int write_uid_file(void);
 
 void create_hash_table(unsigned bits);
@@ -46,3 +46,4 @@ int parse_uid_arg(const char *orig_arg, struct uid_range **ur);
 int append_users(char **users, int num_users,
                struct uid_range **admissible_uids, int num_uid_ranges);
 void close_user_tables(void);
 int append_users(char **users, int num_users,
                struct uid_range **admissible_uids, int num_uid_ranges);
 void close_user_tables(void);
+int open_admissible_user_tables(struct uid_range *admissible_uids);