57
57
#include "assert.h"
58
58
#include "bsearch.h"
59
59
#include "cyrusdb.h"
60
+ #include "cyr_lock.h"
60
61
#include "util.h"
61
62
#include "libcyr_cfg.h"
62
63
#include "xmalloc.h"
@@ -108,30 +109,10 @@ static struct cyrusdb_backend *cyrusdb_fromname(const char *name)
108
109
fatal (errbuf , EX_CONFIG );
109
110
}
110
111
111
- static int _myopen ( const char * backend , const char * fname ,
112
- int flags , struct db * * ret , struct txn * * tid )
112
+ static int _detect_or_convert ( struct db * db , const char * backend ,
113
+ const char * fname , int flags )
113
114
{
114
- const char * realname ;
115
- struct db * db = xzmalloc (sizeof (struct db ));
116
- int r ;
117
-
118
- if (!backend ) backend = DEFAULT_BACKEND ; /* not used yet, later */
119
- db -> backend = cyrusdb_fromname (backend );
120
-
121
- /* Check if shared lock is requested */
122
- if (flags & CYRUSDB_SHARED ) {
123
- assert (tid && * tid == NULL );
124
- if (flags & CYRUSDB_CONVERT ) {
125
- xsyslog (LOG_ERR ,
126
- "DBERROR: CONVERT and SHARED are mutually exclusive,"
127
- " won't open db" ,
128
- "fname=<%s> backend=<%s>" ,
129
- fname , backend );
130
- r = CYRUSDB_INTERNAL ;
131
- goto done ;
132
- }
133
- }
134
-
115
+ int r = 0 ;
135
116
/* This whole thing is a fricking critical section. We don't have the API
136
117
* in place for a safe rename of a locked database, so the choices are
137
118
* basically:
@@ -142,29 +123,43 @@ static int _myopen(const char *backend, const char *fname,
142
123
* We do that.
143
124
*/
144
125
145
- /* check if it opens normally. Horray */
146
- r = db -> backend -> open (fname , flags , & db -> engine , tid );
147
- if (r == CYRUSDB_NOTFOUND ) goto done ; /* no open flags */
148
- if (!r ) goto done ;
126
+ // make sure we have a lock file fd
127
+ if (cyrusdb_convertlock_fd < 0 ) {
128
+ struct buf namebuf = BUF_INITIALIZER ;
129
+ const char * config_dir = libcyrus_config_getstring (CYRUSOPT_CONFIG_DIR );
130
+ buf_printf (& namebuf , "%s/lock/cyrusdb_convert.lock" , config_dir );
131
+ const char * fname = buf_cstring (& namebuf );
132
+ cyrusdb_convertlock_fd = open (fname , O_CREAT | O_TRUNC | O_RDWR , 0666 );
133
+ if (cyrusdb_convertlock_fd < 0 ) {
134
+ if (!cyrus_mkdir (fname , 0755 )) {
135
+ cyrusdb_convertlock_fd = open (fname , O_CREAT | O_TRUNC | O_RDWR , 0666 );
136
+ }
137
+ }
138
+ buf_free (& namebuf );
139
+ if (cyrusdb_convertlock_fd < 0 )
140
+ return CYRUSDB_IOERROR ;
141
+ }
142
+
143
+ // lock the lock file
144
+ if (lock_setlock (cyrusdb_convertlock_fd , 1 , 0 , "cyrusdb_convert.lock" ))
145
+ return CYRUSDB_IOERROR ;
149
146
150
147
/* magic time - we need to work out if the file was created by a different
151
148
* backend and convert if possible */
152
-
153
- realname = cyrusdb_detect (fname );
149
+ const char * realname = cyrusdb_detect (fname );
154
150
if (!realname ) {
155
151
xsyslog (LOG_ERR , "DBERROR: failed to detect DB type" ,
156
- "fname=<%s> backend=<%s> r=<%d>" ,
157
- fname , backend , r );
158
- /* r is still set */
159
- goto done ;
152
+ "fname=<%s> backend=<%s>" ,
153
+ fname , backend );
154
+ r = CYRUSDB_IOERROR ;
160
155
}
161
156
162
157
/* different type */
163
- if (strcmp (realname , backend )) {
164
- if (flags & CYRUSDB_CONVERT ) {
158
+ if (! r && strcmp (realname , backend )) {
159
+ if (flags & CYRUSDB_CONVERT || libcyrus_config_getswitch ( CYRUSOPT_CYRUSDB_AUTOCONVERT ) ) {
165
160
r = cyrusdb_convert (fname , fname , realname , backend );
166
161
if (r ) {
167
- xsyslog (LOG_ERR , "DBERROR: failed to convert, maybe someone beat us " ,
162
+ xsyslog (LOG_ERR , "DBERROR: failed to convert" ,
168
163
"fname=<%s> from=<%s> to=<%s>" ,
169
164
fname , realname , backend );
170
165
}
@@ -180,6 +175,42 @@ static int _myopen(const char *backend, const char *fname,
180
175
}
181
176
}
182
177
178
+ lock_unlock (cyrusdb_convertlock_fd , "cyrusdb_convert.lock" );
179
+
180
+ return r ;
181
+ }
182
+
183
+ static int _myopen (const char * backend , const char * fname ,
184
+ int flags , struct db * * ret , struct txn * * tid )
185
+ {
186
+ struct db * db = xzmalloc (sizeof (struct db ));
187
+ int r = 0 ;
188
+
189
+ if (!backend ) backend = DEFAULT_BACKEND ; /* not used yet, later */
190
+ db -> backend = cyrusdb_fromname (backend );
191
+
192
+ /* Check if shared lock is requested */
193
+ if (flags & CYRUSDB_SHARED ) {
194
+ assert (tid && * tid == NULL );
195
+ if (flags & CYRUSDB_CONVERT ) {
196
+ xsyslog (LOG_ERR ,
197
+ "DBERROR: CONVERT and SHARED are mutually exclusive,"
198
+ " won't open db" ,
199
+ "fname=<%s> backend=<%s>" ,
200
+ fname , backend );
201
+ r = CYRUSDB_INTERNAL ;
202
+ goto done ;
203
+ }
204
+ }
205
+
206
+ /* check if it opens normally. Horray */
207
+ r = db -> backend -> open (fname , flags , & db -> engine , tid );
208
+ if (r == CYRUSDB_NOTFOUND ) goto done ; /* no open flags */
209
+ if (!r ) goto done ;
210
+
211
+ r = _detect_or_convert (db , backend , fname , flags );
212
+ if (r ) goto done ;
213
+
183
214
r = db -> backend -> open (fname , flags , & db -> engine , tid );
184
215
185
216
#ifdef DEBUGDB
@@ -549,26 +580,6 @@ EXPORTED int cyrusdb_convert(const char *fromfname, const char *tofname,
549
580
struct txn * totid = NULL ;
550
581
int r ;
551
582
552
- // make sure we have a lock file fd
553
- if (cyrusdb_convertlock_fd < 0 ) {
554
- struct buf namebuf = BUF_INITIALIZER ;
555
- buf_printf (& namebuf , "%s/lock/cyrusdb_convert.lock" , config_dir );
556
- const char * fname = buf_cstring (& namebuf );
557
- cyrusdb_convertlock_fd = open (fname , O_CREAT | O_TRUNC | O_RDWR , 0666 );
558
- if (cyrusdb_convertlock_fd < 0 ) {
559
- if (!cyrus_mkdir (fname , 0755 ))
560
- cyrusdb_convertlock_fd = open (fname , O_CREAT | O_TRUNC | O_RDWR , 0666 );
561
- }
562
- }
563
- buf_free (& namebuf );
564
- }
565
- if (cyrusdb_convertlock_fd < 0 )
566
- return CYRUSDB_IOERROR ;
567
-
568
- // lock the lock file
569
- if (lock_setlock (cyrusdb_convertlock_fd , LOCK_EXCLUSIVE , 0 , "cyrusdb_convert.lock" ))
570
- return CYRUSDB_IOERROR ;
571
-
572
583
/* open source database */
573
584
r = cyrusdb_open (frombackend , fromfname , 0 , & fromdb );
574
585
if (r ) goto err ;
@@ -610,8 +621,6 @@ EXPORTED int cyrusdb_convert(const char *fromfname, const char *tofname,
610
621
611
622
free (newfname );
612
623
613
- lock_unlock (cyrusdb_convertlock_fd , "cyrusdb_convert.lock" );
614
-
615
624
return 0 ;
616
625
617
626
err :
@@ -623,8 +632,6 @@ EXPORTED int cyrusdb_convert(const char *fromfname, const char *tofname,
623
632
xunlink (tofname );
624
633
free (newfname );
625
634
626
- lock_unlock (cyrusdb_convertlock_fd , "cyrusdb_convert.lock" );
627
-
628
635
return r ;
629
636
}
630
637
0 commit comments