Fix locking of Berkeley databases.
* include/mailutils/locker.h (mu_locker_lock_mode): New proto. * libmailutils/base/locker.c (_mu_locker_lock): Rename to mu_locker_lock_mode. All callers updated. * libmu_dbm/berkeley.c (bdb_file) <locker>: New member. (do_bdb_open): New function. Lock the database file before opening it. Drop support for version 2. (_bdb_open): Rewrite as a wrapper over do_bdb_open. * mu/dbm.c (dbm_doc): Document the "dump" subcommand. * NEWS: Version 2.99.96 * configure.ac: Likewise.
Showing
6 changed files
with
73 additions
and
32 deletions
1 | GNU mailutils NEWS -- history of user-visible changes. 2011-12-31 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2012-02-26 |
2 | Copyright (C) 2002-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2012 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
5 | Please send mailutils bug reports to <bug-mailutils@gnu.org>. | 5 | Please send mailutils bug reports to <bug-mailutils@gnu.org>. |
6 | 6 | ||
7 | 7 | ||
8 | Version 2.99.95 (Git) | 8 | Version 2.99.96 (Git) |
9 | 9 | ||
10 | This version is a major rewrite of GNU Mailutils. Quite a few parts | 10 | This version is a major rewrite of GNU Mailutils. Quite a few parts |
11 | of the basic framework were rewritten from scratch, while some others | 11 | of the basic framework were rewritten from scratch, while some others | ... | ... |
... | @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License along | ... | @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License along |
16 | dnl with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | 16 | dnl with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | AC_PREREQ(2.63) | 18 | AC_PREREQ(2.63) |
19 | AC_INIT([GNU Mailutils], [2.99.95], [bug-mailutils@gnu.org], [mailutils]) | 19 | AC_INIT([GNU Mailutils], [2.99.96], [bug-mailutils@gnu.org], [mailutils]) |
20 | AC_CONFIG_SRCDIR([libmailutils/mailbox/mailbox.c]) | 20 | AC_CONFIG_SRCDIR([libmailutils/mailbox/mailbox.c]) |
21 | AC_CONFIG_AUX_DIR([build-aux]) | 21 | AC_CONFIG_AUX_DIR([build-aux]) |
22 | AM_INIT_AUTOMAKE([gnits 1.11 dist-bzip2 dist-xz std-options silent-rules]) | 22 | AM_INIT_AUTOMAKE([gnits 1.11 dist-bzip2 dist-xz std-options silent-rules]) | ... | ... |
... | @@ -133,6 +133,7 @@ enum mu_locker_mode | ... | @@ -133,6 +133,7 @@ enum mu_locker_mode |
133 | locking otherwise */ | 133 | locking otherwise */ |
134 | }; | 134 | }; |
135 | 135 | ||
136 | extern int mu_locker_lock_mode (mu_locker_t, enum mu_locker_mode); | ||
136 | extern int mu_locker_lock (mu_locker_t); | 137 | extern int mu_locker_lock (mu_locker_t); |
137 | extern int mu_locker_touchlock (mu_locker_t); | 138 | extern int mu_locker_touchlock (mu_locker_t); |
138 | extern int mu_locker_unlock (mu_locker_t); | 139 | extern int mu_locker_unlock (mu_locker_t); | ... | ... |
... | @@ -547,7 +547,7 @@ mu_locker_destroy (mu_locker_t *plocker) | ... | @@ -547,7 +547,7 @@ mu_locker_destroy (mu_locker_t *plocker) |
547 | } | 547 | } |
548 | 548 | ||
549 | int | 549 | int |
550 | _mu_locker_lock (mu_locker_t lock, enum mu_locker_mode mode) | 550 | mu_locker_lock_mode (mu_locker_t lock, enum mu_locker_mode mode) |
551 | { | 551 | { |
552 | int rc; | 552 | int rc; |
553 | unsigned type; | 553 | unsigned type; |
... | @@ -598,7 +598,7 @@ _mu_locker_lock (mu_locker_t lock, enum mu_locker_mode mode) | ... | @@ -598,7 +598,7 @@ _mu_locker_lock (mu_locker_t lock, enum mu_locker_mode mode) |
598 | int | 598 | int |
599 | mu_locker_lock (mu_locker_t lock) | 599 | mu_locker_lock (mu_locker_t lock) |
600 | { | 600 | { |
601 | return _mu_locker_lock (lock, mu_lck_exc); | 601 | return mu_locker_lock_mode (lock, mu_lck_exc); |
602 | } | 602 | } |
603 | 603 | ||
604 | int | 604 | int | ... | ... |
... | @@ -26,6 +26,7 @@ | ... | @@ -26,6 +26,7 @@ |
26 | #include <mailutils/errno.h> | 26 | #include <mailutils/errno.h> |
27 | #include <mailutils/error.h> | 27 | #include <mailutils/error.h> |
28 | #include <mailutils/stream.h> | 28 | #include <mailutils/stream.h> |
29 | #include <mailutils/locker.h> | ||
29 | #include "mudbm.h" | 30 | #include "mudbm.h" |
30 | 31 | ||
31 | #if defined(WITH_BDB) | 32 | #if defined(WITH_BDB) |
... | @@ -35,6 +36,7 @@ struct bdb_file | ... | @@ -35,6 +36,7 @@ struct bdb_file |
35 | { | 36 | { |
36 | DB *db; | 37 | DB *db; |
37 | DBC *dbc; | 38 | DBC *dbc; |
39 | mu_locker_t locker; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | static int | 42 | static int |
... | @@ -59,57 +61,71 @@ _bdb_get_fd (mu_dbm_file_t db, int *pag, int *dir) | ... | @@ -59,57 +61,71 @@ _bdb_get_fd (mu_dbm_file_t db, int *pag, int *dir) |
59 | } | 61 | } |
60 | 62 | ||
61 | static int | 63 | static int |
62 | _bdb_open (mu_dbm_file_t mdb, int flags, int mode) | 64 | do_bdb_open (mu_dbm_file_t mdb, int flags, int mode) |
63 | { | 65 | { |
64 | struct bdb_file *bdb_file; | 66 | struct bdb_file *bdb_file = mdb->db_descr; |
65 | int f, rc; | 67 | int f, rc, locker_flags; |
66 | DB *db; | 68 | enum mu_locker_mode locker_mode; |
67 | 69 | ||
68 | switch (flags) | 70 | switch (flags) |
69 | { | 71 | { |
70 | case MU_STREAM_CREAT: | 72 | case MU_STREAM_CREAT: |
71 | f = DB_CREATE|DB_TRUNCATE; | 73 | f = DB_CREATE|DB_TRUNCATE; |
74 | locker_mode = mu_lck_exc; | ||
72 | break; | 75 | break; |
73 | 76 | ||
74 | case MU_STREAM_READ: | 77 | case MU_STREAM_READ: |
75 | f = DB_RDONLY; | 78 | f = DB_RDONLY; |
79 | locker_mode = mu_lck_shr; | ||
76 | break; | 80 | break; |
77 | 81 | ||
78 | case MU_STREAM_RDWR: | 82 | case MU_STREAM_RDWR: |
79 | f = DB_CREATE; | 83 | f = DB_CREATE; |
84 | locker_mode = mu_lck_exc; | ||
80 | break; | 85 | break; |
81 | 86 | ||
82 | default: | 87 | default: |
83 | return EINVAL; | 88 | return EINVAL; |
84 | } | 89 | } |
85 | 90 | ||
86 | #if WITH_BDB == 2 | 91 | #ifdef DB_FCNTL_LOCKING |
87 | rc = db_open (db->db_name, DB_HASH, f, mode, NULL, NULL, &db); | 92 | f |= DB_FCNTL_LOCKING; |
93 | locker_flags = MU_LOCKER_KERNEL; | ||
88 | #else | 94 | #else |
89 | rc = db_create (&db, NULL, 0); | 95 | locker_flags = 0; |
90 | if (rc != 0 || db == NULL) | ||
91 | return MU_ERR_FAILURE; | ||
92 | # if DB_VERSION_MAJOR == 3 | ||
93 | rc = db->open (db, mdb->db_name, NULL, DB_HASH, f, mode); | ||
94 | # else | ||
95 | rc = db->open (db, NULL, mdb->db_name, NULL, DB_HASH, f, mode); | ||
96 | # endif | ||
97 | #endif | 96 | #endif |
98 | 97 | rc = mu_locker_create (&bdb_file->locker, mdb->db_name, | |
98 | locker_flags|MU_LOCKER_RETRY); | ||
99 | if (rc) | 99 | if (rc) |
100 | return MU_ERR_FAILURE; | 100 | return rc; |
101 | 101 | ||
102 | bdb_file = malloc (sizeof *bdb_file); | 102 | rc = mu_locker_lock_mode (bdb_file->locker, locker_mode); |
103 | if (!bdb_file) | 103 | switch (rc) |
104 | { | 104 | { |
105 | db->close (db, 0); | 105 | case 0: |
106 | return ENOMEM; | 106 | break; |
107 | } | ||
108 | bdb_file->db = db; | ||
109 | bdb_file->dbc = NULL; | ||
110 | 107 | ||
111 | mdb->db_descr = bdb_file; | 108 | case EACCES: |
109 | mu_locker_destroy (&bdb_file->locker); | ||
110 | break; | ||
111 | |||
112 | default: | ||
113 | return rc; | ||
114 | } | ||
115 | |||
116 | rc = db_create (&bdb_file->db, NULL, 0); | ||
117 | if (rc != 0 || bdb_file->db == NULL) | ||
118 | return MU_ERR_FAILURE; | ||
119 | #if DB_VERSION_MAJOR == 3 | ||
120 | rc = bdb_file->db->open (bdb_file->db, mdb->db_name, NULL, DB_HASH, f, mode); | ||
121 | #else | ||
122 | rc = bdb_file->db->open (bdb_file->db, NULL, mdb->db_name, NULL, DB_HASH, | ||
123 | f, mode); | ||
124 | #endif | ||
112 | 125 | ||
126 | if (rc) | ||
127 | return MU_ERR_FAILURE; | ||
128 | |||
113 | return 0; | 129 | return 0; |
114 | } | 130 | } |
115 | 131 | ||
... | @@ -119,7 +135,13 @@ _bdb_close (mu_dbm_file_t db) | ... | @@ -119,7 +135,13 @@ _bdb_close (mu_dbm_file_t db) |
119 | if (db->db_descr) | 135 | if (db->db_descr) |
120 | { | 136 | { |
121 | struct bdb_file *bdb_file = db->db_descr; | 137 | struct bdb_file *bdb_file = db->db_descr; |
122 | bdb_file->db->close (bdb_file->db, 0); | 138 | if (bdb_file->db) |
139 | bdb_file->db->close (bdb_file->db, 0); | ||
140 | if (bdb_file->locker) | ||
141 | { | ||
142 | mu_locker_unlock (bdb_file->locker); | ||
143 | mu_locker_destroy (&bdb_file->locker); | ||
144 | } | ||
123 | free (bdb_file); | 145 | free (bdb_file); |
124 | db->db_descr = NULL; | 146 | db->db_descr = NULL; |
125 | } | 147 | } |
... | @@ -127,6 +149,23 @@ _bdb_close (mu_dbm_file_t db) | ... | @@ -127,6 +149,23 @@ _bdb_close (mu_dbm_file_t db) |
127 | } | 149 | } |
128 | 150 | ||
129 | static int | 151 | static int |
152 | _bdb_open (mu_dbm_file_t mdb, int flags, int mode) | ||
153 | { | ||
154 | int rc; | ||
155 | struct bdb_file *bdb_file; | ||
156 | |||
157 | bdb_file = calloc (1, sizeof *bdb_file); | ||
158 | if (!bdb_file) | ||
159 | return ENOMEM; | ||
160 | |||
161 | mdb->db_descr = bdb_file; | ||
162 | rc = do_bdb_open (mdb, flags, mode); | ||
163 | if (rc) | ||
164 | _bdb_close (mdb); | ||
165 | return rc; | ||
166 | } | ||
167 | |||
168 | static int | ||
130 | _bdb_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | 169 | _bdb_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, |
131 | struct mu_dbm_datum *ret) | 170 | struct mu_dbm_datum *ret) |
132 | { | 171 | { | ... | ... |
... | @@ -35,6 +35,7 @@ static char dbm_doc[] = N_("mu dbm - DBM management tool\n" | ... | @@ -35,6 +35,7 @@ static char dbm_doc[] = N_("mu dbm - DBM management tool\n" |
35 | "Valid COMMANDs are:\n" | 35 | "Valid COMMANDs are:\n" |
36 | "\n" | 36 | "\n" |
37 | " create or load - create the database\n" | 37 | " create or load - create the database\n" |
38 | " dump - dump the database\n" | ||
38 | " list - list contents of the database\n" | 39 | " list - list contents of the database\n" |
39 | " delete - delete specified keys from the database\n" | 40 | " delete - delete specified keys from the database\n" |
40 | " add - add records to the database\n" | 41 | " add - add records to the database\n" | ... | ... |
-
Please register or sign in to post a comment