2 $Id: cmd_dbd_scanvol.c,v 1.11 2009-11-25 14:59:15 franklahm Exp $
4 Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
19 #endif /* HAVE_CONFIG_H */
23 #include <sys/types.h>
30 #include <atalk/adouble.h>
31 #include <atalk/unicode.h>
32 #include <atalk/volinfo.h>
33 #include <atalk/cnid_dbd_private.h>
39 /* Some defines to ease code parsing */
40 #define ADDIR_OK (addir_ok == 0)
41 #define ADFILE_OK (adfile_ok == 0)
43 /* These must be accessible for cmd_dbd_* funcs */
44 struct volinfo *volinfo;
45 char cwdbuf[MAXPATHLEN+1];
47 /* Some static vars */
49 static DBD *dbd_rebuild;
50 static dbd_flags_t dbd_flags;
51 static char stamp[CNID_DEV_LEN];
52 static char *netatalk_dirs[] = {
57 static struct cnid_dbd_rqst rqst;
58 static struct cnid_dbd_rply rply;
62 Taken form afpd/desktop.c
64 static char *utompath(char *upath)
66 static char mpath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
68 uint16_t flags = CONV_IGNORE | CONV_UNESCAPEHEX;
76 outlen = strlen(upath);
78 if ((volinfo->v_casefold & AFPVOL_UTOMUPPER))
79 flags |= CONV_TOUPPER;
80 else if ((volinfo->v_casefold & AFPVOL_UTOMLOWER))
81 flags |= CONV_TOLOWER;
83 if ((volinfo->v_flags & AFPVOL_EILSEQ)) {
84 flags |= CONV__EILSEQ;
87 /* convert charsets */
88 if ((size_t)-1 == ( outlen = convert_charset(volinfo->v_volcharset,
90 volinfo->v_maccharset,
91 u, outlen, mpath, MAXPATHLEN, &flags)) ) {
92 dbd_log( LOGSTD, "Conversion from %s to %s for %s failed.",
93 volinfo->v_volcodepage, volinfo->v_maccodepage, u);
101 Taken form afpd/desktop.c
103 static char *mtoupath(char *mpath)
105 static char upath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
114 if ( *mpath == '\0' ) {
118 /* set conversion flags */
119 if (!(volinfo->v_flags & AFPVOL_NOHEX))
120 flags |= CONV_ESCAPEHEX;
121 if (!(volinfo->v_flags & AFPVOL_USEDOTS))
122 flags |= CONV_ESCAPEDOTS;
124 if ((volinfo->v_casefold & AFPVOL_MTOUUPPER))
125 flags |= CONV_TOUPPER;
126 else if ((volinfo->v_casefold & AFPVOL_MTOULOWER))
127 flags |= CONV_TOLOWER;
129 if ((volinfo->v_flags & AFPVOL_EILSEQ)) {
130 flags |= CONV__EILSEQ;
139 if ((size_t)-1 == (outlen = convert_charset(CH_UTF8_MAC,
140 volinfo->v_volcharset,
141 volinfo->v_maccharset,
142 m, inplen, u, outlen, &flags)) ) {
143 dbd_log( LOGSTD, "conversion from UTF8-MAC to %s for %s failed.",
144 volinfo->v_volcodepage, mpath);
152 Check for wrong encoding e.g. "." at the beginning is not CAP encoded (:2e) although volume is default !AFPVOL_USEDOTS.
153 We do it by roundtripiping from volcharset to UTF8-MAC and back and then compare the result.
155 static int check_name_encoding(char *uname)
159 roundtripped = mtoupath(utompath(uname));
161 dbd_log( LOGSTD, "Error checking encoding for '%s/%s'", cwdbuf, uname);
165 if ( STRCMP(uname, !=, roundtripped)) {
166 dbd_log( LOGSTD, "Bad encoding for '%s/%s'", cwdbuf, uname);
174 Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
175 Returns pointer to name or NULL.
177 static const char *check_netatalk_dirs(const char *name)
181 for (c=0; netatalk_dirs[c]; c++) {
182 if ((strcmp(name, netatalk_dirs[c])) == 0)
183 return netatalk_dirs[c];
189 Check for .AppleDouble file, create if missing
191 static int check_adfile(const char *fname, const struct stat *st)
197 if (S_ISREG(st->st_mode))
200 adflags = ADFLAGS_DIR;
202 adname = volinfo->ad_path(fname, adflags);
204 if ((ret = access( adname, F_OK)) != 0) {
205 if (errno != ENOENT) {
206 dbd_log(LOGSTD, "Access error for ad-file '%s/%s': %s",
207 cwdbuf, adname, strerror(errno));
210 /* Missing. Log and create it */
211 dbd_log(LOGSTD, "Missing AppleDouble file '%s/%s'", cwdbuf, adname);
213 if (dbd_flags & DBD_FLAGS_SCAN)
214 /* Scan only requested, dont change anything */
218 ad_init(&ad, volinfo->v_adouble, volinfo->v_ad_options);
220 if ((ret = ad_open_metadata( fname, adflags, O_CREAT, &ad)) != 0) {
221 dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s",
222 cwdbuf, adname, strerror(errno));
227 /* Set name in ad-file */
228 ad_setname(&ad, utompath((char *)fname));
230 ad_close_metadata(&ad);
232 chown(adname, st->st_uid, st->st_gid);
233 /* FIXME: should we inherit mode too here ? */
235 chmod(adname, st->st_mode);
238 ad_init(&ad, volinfo->v_adouble, volinfo->v_ad_options);
239 if (ad_open_metadata( fname, adflags, O_RDONLY, &ad) != 0) {
240 dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname);
243 ad_close_metadata(&ad);
249 Check for .AppleDouble folder and .Parent, create if missing
251 static int check_addir(int volroot)
253 int addir_ok, adpar_ok;
258 /* Check for ad-dir */
259 if ( (addir_ok = access(ADv2_DIRNAME, F_OK)) != 0) {
260 if (errno != ENOENT) {
261 dbd_log(LOGSTD, "Access error in directory %s: %s", cwdbuf, strerror(errno));
264 dbd_log(LOGSTD, "Missing %s for '%s'", ADv2_DIRNAME, cwdbuf);
267 /* Check for ".Parent" */
268 if ( (adpar_ok = access(volinfo->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) {
269 if (errno != ENOENT) {
270 dbd_log(LOGSTD, "Access error on '%s/%s': %s",
271 cwdbuf, volinfo->ad_path(".", ADFLAGS_DIR), strerror(errno));
274 dbd_log(LOGSTD, "Missing .AppleDouble/.Parent for '%s'", cwdbuf);
277 /* Is one missing ? */
278 if ((addir_ok != 0) || (adpar_ok != 0)) {
279 /* Yes, but are we only scanning ? */
280 if (dbd_flags & DBD_FLAGS_SCAN) {
281 /* Yes: missing .Parent is not a problem, but missing ad-dir
282 causes later checking of ad-files to fail. So we have to return appropiately */
285 else /* (adpar_ok != 0) */
289 /* Create ad dir and set name */
290 ad_init(&ad, volinfo->v_adouble, volinfo->v_ad_options);
292 if (ad_open_metadata( ".", ADFLAGS_DIR, O_CREAT, &ad) != 0) {
293 dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno));
297 /* Get basename of cwd from cwdbuf */
298 utompath(strrchr(cwdbuf, '/') + 1);
300 /* Update name in ad file */
301 ad_setname(&ad, mname);
303 ad_close_metadata(&ad);
305 /* Inherit owner/group from "." to ".AppleDouble" and ".Parent" */
306 if ((stat(".", &st)) != 0) {
307 dbd_log( LOGSTD, "Couldnt stat %s: %s", cwdbuf, strerror(errno));
310 chown(ADv2_DIRNAME, st.st_uid, st.st_gid);
311 chown(volinfo->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid);
318 Check files and dirs inside .AppleDouble folder:
319 - remove orphaned files
322 static int read_addir(void)
327 static char fname[MAXPATHLEN] = "../";
329 if ((chdir(ADv2_DIRNAME)) != 0) {
330 dbd_log(LOGSTD, "Couldn't chdir to '%s/%s': %s",
331 cwdbuf, ADv2_DIRNAME, strerror(errno));
335 if ((dp = opendir(".")) == NULL) {
336 dbd_log(LOGSTD, "Couldn't open the directory '%s/%s': %s",
337 cwdbuf, ADv2_DIRNAME, strerror(errno));
341 while ((ep = readdir(dp))) {
342 /* Check if its "." or ".." */
343 if (DIR_DOT_OR_DOTDOT(ep->d_name))
346 if (STRCMP(ep->d_name, ==, ".Parent"))
349 if ((stat(ep->d_name, &st)) < 0) {
350 dbd_log( LOGSTD, "Lost file or dir while enumeratin dir '%s/%s/%s', probably removed: %s",
351 cwdbuf, ADv2_DIRNAME, ep->d_name, strerror(errno));
356 if (S_ISDIR(st.st_mode)) {
357 dbd_log( LOGSTD, "Unexpected directory '%s' in AppleDouble dir '%s/%s'",
358 ep->d_name, cwdbuf, ADv2_DIRNAME);
362 /* Check for data file */
363 strcpy(fname+3, ep->d_name);
364 if ((access( fname, F_OK)) != 0) {
365 if (errno != ENOENT) {
366 dbd_log(LOGSTD, "Access error for file '%s/%s': %s",
367 cwdbuf, ep->d_name, strerror(errno));
370 /* Orphaned ad-file*/
371 dbd_log(LOGSTD, "Orphaned AppleDoube file '%s/%s/%s'",
372 cwdbuf, ADv2_DIRNAME, ep->d_name);
374 if (dbd_flags & DBD_FLAGS_SCAN)
375 /* Scan only requested, dont change anything */
378 if ((unlink(ep->d_name)) != 0) {
379 dbd_log(LOGSTD, "Error unlinking orphaned AppleDoube file '%s/%s/%s'",
380 cwdbuf, ADv2_DIRNAME, ep->d_name);
386 if ((chdir("..")) != 0) {
387 dbd_log(LOGSTD, "Couldn't chdir back to '%s' from AppleDouble dir: %s",
388 cwdbuf, strerror(errno));
389 /* This really is EOT! */
399 Check CNID for a file/dir, both from db and from ad-file.
400 For detailed specs see intro.
402 static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok, int adflags)
405 cnid_t db_cnid, ad_cnid;
408 /* Get CNID from ad-file if volume is using AFPVOL_CACHE */
410 if ( (volinfo->v_flags & AFPVOL_CACHE) && ADFILE_OK) {
411 ad_init(&ad, volinfo->v_adouble, volinfo->v_ad_options);
412 if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) {
413 dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
417 if (dbd_flags & DBD_FLAGS_FORCE) {
418 ad_cnid = ad_forcegetid(&ad);
419 /* This ensures the changed stamp is written */
420 ad_setid( &ad, st->st_dev, st->st_ino, ad_cnid, did, stamp);
424 ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, did, stamp);
427 dbd_log( LOGSTD, "Incorrect CNID data in .AppleDouble data for '%s/%s' (bad stamp?)", cwdbuf, name);
429 ad_close_metadata(&ad);
432 /* Get CNID from database */
434 /* Prepare request data */
435 memset(&rqst, 0, sizeof(struct cnid_dbd_rqst));
436 memset(&rply, 0, sizeof(struct cnid_dbd_rply));
438 if ( ! (volinfo->v_flags & AFPVOL_NODEV))
439 rqst.dev = st->st_dev;
440 rqst.ino = st->st_ino;
441 rqst.type = S_ISDIR(st->st_mode)?1:0;
442 rqst.name = (char *)name;
443 rqst.namelen = strlen(name);
445 /* Query the database */
446 ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0);
447 dbif_txn_close(dbd, ret);
448 if (rply.result == CNID_DBD_RES_OK) {
450 } else if (rply.result == CNID_DBD_RES_NOTFOUND) {
451 if ( ! (dbd_flags & DBD_FLAGS_FORCE))
452 dbd_log( LOGSTD, "No CNID for '%s/%s' in database", cwdbuf, name);
455 dbd_log( LOGSTD, "Fatal error resolving '%s/%s'", cwdbuf, name);
459 /* Compare results from both CNID searches */
460 if (ad_cnid && db_cnid && (ad_cnid == db_cnid)) {
461 /* Everything is fine */
463 } else if (ad_cnid && db_cnid && (ad_cnid != db_cnid)) {
464 /* Mismatch ? Delete both from db and re-add data from file */
465 dbd_log( LOGSTD, "CNID mismatch for '%s/%s', db: %u, ad-file: %u", cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid));
466 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
468 ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
469 dbif_txn_close(dbd, ret);
472 ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
473 dbif_txn_close(dbd, ret);
475 ret = dbd_rebuild_add(dbd, &rqst, &rply);
476 dbif_txn_close(dbd, ret);
479 } else if (ad_cnid && (db_cnid == 0)) {
480 /* in ad-file but not in db */
481 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
482 dbd_log( LOGDEBUG, "CNID rebuild add for '%s/%s', adding with CNID from ad-file: %u", cwdbuf, name, ntohl(ad_cnid));
484 ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
485 dbif_txn_close(dbd, ret);
486 ret = dbd_rebuild_add(dbd, &rqst, &rply);
487 dbif_txn_close(dbd, ret);
490 } else if ((db_cnid == 0) && (ad_cnid == 0)) {
491 /* No CNID at all, we clearly have to allocate a fresh one... */
492 /* Note: the next test will use this new CNID too! */
493 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
495 ret = dbd_add(dbd, &rqst, &rply, 1);
496 dbif_txn_close(dbd, ret);
498 dbd_log( LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
502 if ((ad_cnid == 0) && db_cnid) {
503 /* in db but zeroID in ad-file, write it to ad-file if AFPVOL_CACHE */
504 if ((volinfo->v_flags & AFPVOL_CACHE) && ADFILE_OK) {
505 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
506 dbd_log( LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file", cwdbuf, name, ntohl(db_cnid));
507 ad_init(&ad, volinfo->v_adouble, volinfo->v_ad_options);
508 if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) {
509 dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
512 ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
514 ad_close_metadata(&ad);
524 This is called recursively for all dirs.
525 volroot=1 means we're in the volume root dir, 0 means we aren't.
526 We use this when checking for netatalk private folders like .AppleDB.
527 did is our parents CNID.
529 static int dbd_readdir(int volroot, cnid_t did)
531 int cwd, ret = 0, adflags, adfile_ok, addir_ok, encoding_ok;
536 static struct stat st; /* Save some stack space */
538 /* Check again for .AppleDouble folder, check_adfile also checks/creates it */
539 if ((addir_ok = check_addir(volroot)) != 0)
540 if ( ! (dbd_flags & DBD_FLAGS_SCAN))
541 /* Fatal on rebuild run, continue if only scanning ! */
544 /* Check AppleDouble files in AppleDouble folder, but only if it exists or could be created */
546 if ((read_addir()) != 0)
547 if ( ! (dbd_flags & DBD_FLAGS_SCAN))
548 /* Fatal on rebuild run, continue if only scanning ! */
551 if ((dp = opendir (".")) == NULL) {
552 dbd_log(LOGSTD, "Couldn't open the directory: %s",strerror(errno));
556 while ((ep = readdir (dp))) {
557 /* Check if we got a termination signal */
559 longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
561 /* Check if its "." or ".." */
562 if (DIR_DOT_OR_DOTDOT(ep->d_name))
565 /* Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" */
566 if ((name = check_netatalk_dirs(ep->d_name)) != NULL) {
568 dbd_log(LOGSTD, "Nested %s in %s", name, cwdbuf);
572 /* Skip .AppleDouble dir in this loop */
573 if (STRCMP(ep->d_name, == , ADv2_DIRNAME))
576 if ((ret = stat(ep->d_name, &st)) < 0) {
577 dbd_log( LOGSTD, "Lost file while reading dir '%s/%s', probably removed: %s", cwdbuf, ep->d_name, strerror(errno));
580 if (S_ISREG(st.st_mode))
583 adflags = ADFLAGS_DIR;
585 /**************************************************************************
587 **************************************************************************/
590 if ( -1 == (encoding_ok = check_name_encoding(ep->d_name)) ) {
591 /* If its a file: skipp all other tests now ! */
592 /* For dirs we could try to get a CNID for it and recurse, but currently I prefer not to */
596 /* Check for appledouble file, create if missing, but only if we have addir */
599 adfile_ok = check_adfile(ep->d_name, &st);
603 cnid = check_cnid(ep->d_name, did, &st, adfile_ok, adflags);
605 /* Now add this object to our rebuild dbd */
607 rqst.cnid = rply.cnid;
608 dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
609 if (rply.result != CNID_DBD_RES_OK) {
610 dbd_log( LOGDEBUG, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
611 cnid, cwdbuf, ep->d_name);
617 /**************************************************************************
619 **************************************************************************/
620 if (S_ISDIR(st.st_mode) && (cnid || nocniddb)) { /* If we have no cnid for it we cant recur */
622 strcat(cwdbuf, ep->d_name);
623 dbd_log( LOGDEBUG, "Entering directory: %s", cwdbuf);
624 if (-1 == (cwd = open(".", O_RDONLY))) {
625 dbd_log( LOGSTD, "Cant open directory '%s': %s", cwdbuf, strerror(errno));
628 if (0 != chdir(ep->d_name)) {
629 dbd_log( LOGSTD, "Cant chdir to directory '%s': %s", cwdbuf, strerror(errno));
634 ret = dbd_readdir(0, cnid);
638 *(strrchr(cwdbuf, '/')) = 0;
645 Use results of previous checks
652 static int scanvol(struct volinfo *vi, dbd_flags_t flags)
654 /* Dont scanvol on no-appledouble vols */
655 if (vi->v_flags & AFPVOL_NOADOUBLE) {
656 dbd_log( LOGSTD, "Volume without AppleDouble support: skipping volume scanning.");
660 /* Make this stuff accessible from all funcs easily */
664 /* Run with umask 0 */
668 strcpy(cwdbuf, volinfo->v_path);
669 if (cwdbuf[strlen(cwdbuf) - 1] == '/')
670 cwdbuf[strlen(cwdbuf) - 1] = 0;
671 chdir(volinfo->v_path);
673 /* Start recursion */
674 if (dbd_readdir(1, htonl(2)) < 0) /* 2 = volumeroot CNID */
681 Remove all CNIDs from dbd that are not in dbd_rebuild
683 static void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags)
685 int ret, deleted = 0;
686 cnid_t dbd_cnid = 0, rebuild_cnid = 0;
687 struct cnid_dbd_rqst rqst;
688 struct cnid_dbd_rply rply;
690 /* jump over rootinfo key */
691 if ( dbif_idwalk(dbd, &dbd_cnid, 0) != 1)
693 if ( dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0) != 1)
696 /* Get first id from dbd_rebuild */
697 if ((dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1)
700 /* Start main loop through dbd: get CNID from dbd */
701 while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
705 if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
706 dbd_log(LOGSTD, "Error checkpointing!");
711 /* This should be the normal case: CNID is in both dbs */
712 if (dbd_cnid == rebuild_cnid) {
713 /* Get next CNID from rebuild db */
714 if ((ret = dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1) {
717 } else if (ret == 0) {
718 /* end of rebuild_cnid, delete all remaining CNIDs from dbd */
719 while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
720 dbd_log(LOGSTD, "Orphaned CNID in database: %u", dbd_cnid);
721 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
722 rqst.cnid = htonl(dbd_cnid);
723 ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
724 dbif_txn_close(dbd, ret);
730 /* Normal case (ret=1): continue while loop */
734 if (dbd_cnid < rebuild_cnid) {
735 /* CNID is orphaned -> delete */
736 dbd_log(LOGSTD, "Orphaned CNID in database: %u.", dbd_cnid);
737 if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
738 rqst.cnid = htonl(dbd_cnid);
739 ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
740 dbif_txn_close(dbd, ret);
746 if (dbd_cnid > rebuild_cnid) {
747 dbd_log(LOGSTD, "Ghost CNID: %u. This is fatal! Dumping rebuild db:\n", rebuild_cnid);
748 dbif_dump(dbd_rebuild, 0);
749 dbd_log(LOGSTD, "Send this dump and a `dbd -d ...` dump to the Netatalk Dev team!");
750 dbif_txn_close(dbd, ret);
751 dbif_idwalk(dbd, NULL, 1); /* Close cursor */
752 dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
758 dbif_idwalk(dbd, NULL, 1); /* Close cursor */
759 dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
764 Main func called from cmd_dbd.c
766 int cmd_dbd_scanvol(DBD *dbd_ref, struct volinfo *volinfo, dbd_flags_t flags)
770 /* Make it accessible for all funcs */
773 /* We only support unicode volumes ! */
774 if ( volinfo->v_volcharset != CH_UTF8) {
775 dbd_log( LOGSTD, "Not a Unicode volume: %s, %u != %u", volinfo->v_volcodepage, volinfo->v_volcharset, CH_UTF8);
780 /* Get volume stamp */
781 dbd_getstamp(dbd, &rqst, &rply);
782 if (rply.result != CNID_DBD_RES_OK)
784 memcpy(stamp, rply.name, CNID_DEV_LEN);
786 /* open/create rebuild dbd, copy rootinfo key */
787 if (NULL == (dbd_rebuild = dbif_init(NULL, NULL)))
789 if (0 != (dbif_open(dbd_rebuild, NULL, 0)))
791 if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild)))
795 if (setjmp(jmp) != 0)
796 goto exit_cleanup; /* Got signal, jump from dbd_readdir */
799 if ( (scanvol(volinfo, flags)) != 0)
803 /* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
804 other clients in between our pass 1 and 2 */
805 if (flags & DBD_FLAGS_EXCL)
806 delete_orphaned_cnids(dbd, dbd_rebuild, flags);
811 dbif_close(dbd_rebuild);