Line data Source code
1 : #include "../common/tdb_private.h"
2 : #include "../common/io.c"
3 : #include "../common/tdb.c"
4 : #include "../common/lock.c"
5 : #include "../common/freelist.c"
6 : #include "../common/traverse.c"
7 : #include "../common/transaction.c"
8 : #include "../common/error.c"
9 : #include "../common/open.c"
10 : #include "../common/check.c"
11 : #include "../common/hash.c"
12 : #include "../common/mutex.c"
13 : #include "tap-interface.h"
14 : #include <stdlib.h>
15 :
16 22 : static unsigned int tdb_dumb_hash(TDB_DATA *key)
17 : {
18 22 : return key->dsize;
19 : }
20 :
21 4 : static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
22 : {
23 4 : unsigned int *count = tdb_get_logging_private(tdb);
24 4 : if (strstr(fmt, "hash"))
25 4 : (*count)++;
26 4 : }
27 :
28 6 : static unsigned int hdr_rwlocks(const char *fname)
29 : {
30 : struct tdb_header hdr;
31 : ssize_t nread;
32 :
33 6 : int fd = open(fname, O_RDONLY);
34 6 : if (fd == -1)
35 0 : return -1;
36 :
37 6 : nread = read(fd, &hdr, sizeof(hdr));
38 6 : close(fd);
39 6 : if (nread != sizeof(hdr)) {
40 0 : return -1;
41 : }
42 6 : return hdr.rwlocks;
43 : }
44 :
45 1 : int main(int argc, char *argv[])
46 : {
47 : struct tdb_context *tdb;
48 : unsigned int log_count, flags;
49 : TDB_DATA d, r;
50 1 : struct tdb_logging_context log_ctx = { log_fn, &log_count };
51 :
52 : plan_tests(38 * 2);
53 :
54 3 : for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
55 2 : unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC;
56 :
57 2 : if (flags & TDB_CONVERT)
58 1 : tdb_convert(&rwmagic, sizeof(rwmagic));
59 :
60 : /* Create an old-style hash. */
61 2 : log_count = 0;
62 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, flags,
63 : O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
64 : NULL);
65 2 : ok1(tdb);
66 2 : ok1(log_count == 0);
67 2 : d.dptr = discard_const_p(uint8_t, "Hello");
68 2 : d.dsize = 5;
69 2 : ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
70 2 : tdb_close(tdb);
71 :
72 : /* Should not have marked rwlocks field. */
73 2 : ok1(hdr_rwlocks("run-incompatible.tdb") == 0);
74 :
75 : /* We can still open any old-style with incompat flag. */
76 2 : log_count = 0;
77 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0,
78 : TDB_INCOMPATIBLE_HASH,
79 : O_RDWR, 0600, &log_ctx, NULL);
80 2 : ok1(tdb);
81 2 : ok1(log_count == 0);
82 2 : r = tdb_fetch(tdb, d);
83 2 : ok1(r.dsize == 5);
84 2 : free(r.dptr);
85 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
86 2 : tdb_close(tdb);
87 :
88 2 : log_count = 0;
89 2 : tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
90 : 0, &log_ctx, tdb_jenkins_hash);
91 2 : ok1(tdb);
92 2 : ok1(log_count == 0);
93 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
94 2 : tdb_close(tdb);
95 :
96 2 : log_count = 0;
97 2 : tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
98 : 0, &log_ctx, tdb_jenkins_hash);
99 2 : ok1(tdb);
100 2 : ok1(log_count == 0);
101 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
102 2 : tdb_close(tdb);
103 :
104 : /* OK, now create with incompatible flag, default hash. */
105 2 : log_count = 0;
106 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0,
107 2 : flags|TDB_INCOMPATIBLE_HASH,
108 : O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
109 : NULL);
110 2 : ok1(tdb);
111 2 : ok1(log_count == 0);
112 2 : d.dptr = discard_const_p(uint8_t, "Hello");
113 2 : d.dsize = 5;
114 2 : ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
115 2 : tdb_close(tdb);
116 :
117 : /* Should have marked rwlocks field. */
118 2 : ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
119 :
120 : /* Cannot open with old hash. */
121 2 : log_count = 0;
122 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
123 : O_RDWR, 0600, &log_ctx, tdb_old_hash);
124 2 : ok1(!tdb);
125 2 : ok1(log_count == 1);
126 :
127 : /* Can open with jenkins hash. */
128 2 : log_count = 0;
129 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
130 : O_RDWR, 0600, &log_ctx, tdb_jenkins_hash);
131 2 : ok1(tdb);
132 2 : ok1(log_count == 0);
133 2 : r = tdb_fetch(tdb, d);
134 2 : ok1(r.dsize == 5);
135 2 : free(r.dptr);
136 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
137 2 : tdb_close(tdb);
138 :
139 : /* Can open by letting it figure it out itself. */
140 2 : log_count = 0;
141 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
142 : O_RDWR, 0600, &log_ctx, NULL);
143 2 : ok1(tdb);
144 2 : ok1(log_count == 0);
145 2 : r = tdb_fetch(tdb, d);
146 2 : ok1(r.dsize == 5);
147 2 : free(r.dptr);
148 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
149 2 : tdb_close(tdb);
150 :
151 : /* We can also use incompatible hash with other hashes. */
152 2 : log_count = 0;
153 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0,
154 2 : flags|TDB_INCOMPATIBLE_HASH,
155 : O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
156 : tdb_dumb_hash);
157 2 : ok1(tdb);
158 2 : ok1(log_count == 0);
159 2 : d.dptr = discard_const_p(uint8_t, "Hello");
160 2 : d.dsize = 5;
161 2 : ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
162 2 : tdb_close(tdb);
163 :
164 : /* Should have marked rwlocks field. */
165 2 : ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
166 :
167 : /* It should not open if we don't specify. */
168 2 : log_count = 0;
169 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
170 : &log_ctx, NULL);
171 2 : ok1(!tdb);
172 2 : ok1(log_count == 1);
173 :
174 : /* Should reopen with correct hash. */
175 2 : log_count = 0;
176 2 : tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
177 : &log_ctx, tdb_dumb_hash);
178 2 : ok1(tdb);
179 2 : ok1(log_count == 0);
180 2 : r = tdb_fetch(tdb, d);
181 2 : ok1(r.dsize == 5);
182 2 : free(r.dptr);
183 2 : ok1(tdb_check(tdb, NULL, NULL) == 0);
184 2 : tdb_close(tdb);
185 : }
186 :
187 1 : return exit_status();
188 : }
|