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 787b0e8..cbc42cb 100644 (file)
--- a/adu.c
+++ b/adu.c
@@ -106,6 +106,7 @@ static void close_dir_table(void)
 
        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));
@@ -146,15 +147,20 @@ static int init_signals(void)
 
 int open_dir_table(int create)
 {
+
+       if (dir_table)
+               return 1;
        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;
                }
        }
+       INFO_LOG("opening dir table\n");
        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:
+       close_all_tables();
        if (ret < 0) {
                ERROR_LOG("%s\n", adu_strerror(-ret));
                return -EXIT_FAILURE;
index a5bd298..29b46ed 100644 (file)
--- a/create.c
+++ b/create.c
@@ -172,6 +172,5 @@ int com_create(void)
                goto out;
        ret = write_uid_file();
 out:
-       close_all_tables();
        return ret;
 }
index 9460877..e184dbe 100644 (file)
@@ -82,16 +82,18 @@ void print_interactive_help(void)
 
 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);
-       return 1;
+       return parse_select_options(NULL, NULL, &admissible_uids, &fi);
 }
 
 static int icom_set(char *line)
 {
+       int ret;
        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;
-       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)
@@ -166,6 +171,11 @@ int com_interactive(void)
 
        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)
index 6b1fc93..6318d7c 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();
-       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:
-       close_all_tables();
        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 = read_uid_file();
+               if (ret < 0)
+                       goto out;
                ret = run_select_query(admissible_uids, fi);
                free_format_info(fi);
        }
+out:
        select_cmdline_parser_free(&select_conf);
        return ret;
 }
diff --git a/user.c b/user.c
index 497af15..3f368e2 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);
 
-       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)
@@ -312,7 +312,7 @@ void close_user_tables(void)
                        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",
@@ -393,7 +393,34 @@ void sort_hash_table(int (*comp)(const void *, const void *))
                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;
@@ -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");
-                       ret =-EFAULT;
+                       ret = -EFAULT;
                        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:
diff --git a/user.h b/user.h
index aa07acc..7a06876 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);
-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);
@@ -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 open_admissible_user_tables(struct uid_range *admissible_uids);