script.
NOTE: cnid_add calls this before adding a new CNID.
4) when you delete a file or directory, you need to call
cnid_delete with the CNID for that file/directory.
- 5) if you're just moving a CNID, call cnid_move with the CNID
- and the new dev/ino,did/name pairs.
- 6) call cnid_close when closing the volume.
+ 5) call cnid_close when closing the volume.
/*
- * $Id: cnid_add.c,v 1.27 2002-01-29 21:12:18 jmarcus Exp $
+ * $Id: cnid_add.c,v 1.28 2002-02-01 19:51:09 jmarcus Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
int rc;
if (!(db = CNID) || !st || !name) {
- errno = CNID_ERR_PARAM;
+ errno = CNID_ERR_PARAM;
return -1;
}
if ((data.data = make_cnid_data(st, did, name, len)) == NULL) {
LOG(log_error, logtype_default, "cnid_add: Path name is too long");
errno = CNID_ERR_PATH;
- return -1;
+ return -1;
}
data.size = CNID_HEADER_LEN + len + 1;
case DB_KEYEXIST: /* Need to use RootInfo after all. */
break;
default:
- LOG(log_error, logtype_default, "cnid_add: Unable to add CNID %u: %s",
- ntohl(hint), db_strerror(rc));
+ LOG(log_error, logtype_default, "cnid_add: Unable to add CNID %u: %s", ntohl(hint), db_strerror(rc));
errno = CNID_ERR_DB;
- return -1;
+ return -1;
case 0:
#ifdef DEBUG
- LOG(log_info, logtype_default, "cnid_add: Used hint for did %u, name %s as %u",
- ntohl(did), name, ntohl(hint));
+ LOG(log_info, logtype_default, "cnid_add: Used hint for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
#endif
return hint;
}
if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
LOG(log_error, logtype_default, "cnid_add: Failed to begin transaction: %s", db_strerror(rc));
errno = CNID_ERR_DB;
- return -1;
+ return -1;
}
/* Get the key. */
if ((rc = txn_abort(tid)) != 0) {
LOG(log_error, logtype_default, "cnid_add: txn_abort: %s", db_strerror(rc));
errno = CNID_ERR_DB;
- return -1;
+ return -1;
}
goto retry;
case 0:
memcpy(&hint, rootinfo_data.data, sizeof(hint));
- id = ntohl(hint);
- /* If we've hit the max CNID allowed, we return a fatal error. CNID
- * needs to be recycled before proceding. */
- if (++id == CNID_INVALID) {
- txn_abort(tid);
- LOG(log_error, logtype_default, "cnid_add: FATAL: Cannot add CNID for %s. CNID database has reached its limit.", name);
- errno = CNID_ERR_MAX;
- return -1;
- }
- hint = htonl(id);
+ id = ntohl(hint);
+ /* If we've hit the max CNID allowed, we return a fatal error. CNID
+ * needs to be recycled before proceding. */
+ if (++id == CNID_INVALID) {
+ txn_abort(tid);
+ LOG(log_error, logtype_default, "cnid_add: FATAL: Cannot add CNID for %s. CNID database has reached its limit.", name);
+ errno = CNID_ERR_MAX;
+ return -1;
+ }
+ hint = htonl(id);
#ifdef DEBUG
LOG(log_info, logtype_default, "cnid_add: Found rootinfo for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
#endif
if ((rc = txn_abort(tid)) != 0) {
LOG(log_error, logtype_default, "cnid_add: txn_abort: %s", db_strerror(rc));
errno = CNID_ERR_DB;
- return -1;
+ return -1;
}
goto retry;
case 0:
- /* The transaction finished, commit it. */
- if ((rc = txn_commit(tid, 0)) != 0) {
- LOG(log_error, logtype_default, "cnid_add: Unable to commit transaction: %s", db_strerror(rc));
- errno = CNID_ERR_DB;
- return -1;
- }
- break;
+ /* The transaction finished, commit it. */
+ if ((rc = txn_commit(tid, 0)) != 0) {
+ LOG(log_error, logtype_default, "cnid_add: Unable to commit transaction: %s", db_strerror(rc));
+ errno = CNID_ERR_DB;
+ return -1;
+ }
+ break;
default:
LOG(log_error, logtype_default, "cnid_add: Unable to update rootinfo: %s", db_strerror(rc));
goto cleanup_abort;
if (rc) {
LOG(log_error, logtype_default, "cnid_add: Failed to add CNID for %s to database using hint %u: %s", name, ntohl(hint), db_strerror(rc));
errno = CNID_ERR_DB;
- return -1;
+ return -1;
}
#ifdef DEBUG
txn_abort(tid);
errno = CNID_ERR_DB;
- return -1;
+ return -1;
}
#endif /* CNID_DB */
/*
- * $Id: cnid_close.c,v 1.21 2002-01-29 21:12:18 jmarcus Exp $
+ * $Id: cnid_close.c,v 1.22 2002-02-01 19:51:09 jmarcus Exp $
*/
#ifdef HAVE_CONFIG_H
char **list, **first;
int cfd = -1;
- if ((cfd = open(db->close_file, O_RDWR | O_CREAT, 0666)) > -1) {
- /* Checkpoint the databases until we can checkpoint no
- * more. */
+ /* Checkpoint the databases until we can checkpoint no
+ * more. */
+ rc = txn_checkpoint(db->dbenv, 0, 0, 0);
+ while (rc == DB_INCOMPLETE) {
rc = txn_checkpoint(db->dbenv, 0, 0, 0);
- while (rc == DB_INCOMPLETE) {
- rc = txn_checkpoint(db->dbenv, 0, 0, 0);
- }
+ }
#if DB_VERSION_MINOR > 2
- if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS)) != 0) {
+ if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS)) != 0) {
#else /* DB_VERSION_MINOR < 2 */
- if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS, NULL)) != 0) {
+ if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS, NULL)) != 0) {
#endif /* DB_VERSION_MINOR */
- LOG(log_error, logtype_default, "cnid_close: Unable to archive logfiles: %s",
- db_strerror(rc));
- }
+ LOG(log_error, logtype_default, "cnid_close: Unable to archive logfiles: %s", db_strerror(rc));
+ }
- if (list != NULL) {
- for (first = list; *list != NULL; ++list) {
- if ((rc = remove(*list)) != 0) {
+ if (list != NULL) {
+ for (first = list; *list != NULL; ++list) {
+ if ((rc = remove(*list)) != 0) {
#ifdef DEBUG
- LOG(log_info, logtype_default, "cnid_close: failed to remove %s: %s",
- *list, strerror(rc));
+ LOG(log_info, logtype_default, "cnid_close: failed to remove %s: %s", *list, strerror(rc));
#endif
- }
}
- free(first);
}
- (void)remove(db->close_file);
- close(cfd);
- }
- else {
- LOG(log_error, logtype_default, "cnid_close: Failed to open database closing lock file: %s", strerror(errno));
+ free(first);
}
}
- (void)remove(db->lock_file);
+ (void)remove(db->lock_file);
}
db->db_didname->close(db->db_didname, 0);
/*
- * $Id: cnid_open.c,v 1.37 2002-01-29 21:12:18 jmarcus Exp $
+ * $Id: cnid_open.c,v 1.38 2002-02-01 19:51:09 jmarcus Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
#endif /* DB_VERSION_MINOR */
}
-static int have_lock = 0;
-
void *cnid_open(const char *dir) {
struct stat st, rsb, lsb, csb;
struct flock lock;
char path[MAXPATHLEN + 1];
- char recover_file[MAXPATHLEN + 1];
CNID_private *db;
DBT key, data;
DB_TXN *tid;
- u_int32_t DBEXTRAS = 0;
int open_flag, len;
- int no_recover_flag = 0;
- int rc, rfd = -1;
+ int rc;
if (!dir) {
return NULL;
strcat(path, "/");
len++;
- strcpy(db->close_file, path);
- strcat(db->close_file, DBCLOSEFILE);
-
- /* Check to make sure that a client isn't in the process of closing
- * the database environment. To do this, select on the close file. */
- while(stat(db->close_file, &csb) == 0) {
- struct timeval ct;
- ct.tv_sec = 1;
- ct.tv_usec = 0;
- (void)select(0, NULL, NULL, NULL, &ct);
- }
-
- strcpy(recover_file, path);
- strcat(recover_file, DBRECOVERFILE);
-
/* Search for a byte lock. This allows us to cleanup the log files
* at cnid_close() in a clean fashion.
*
* NOTE: This won't work if multiple volumes for the same user refer
* to the sahe directory. */
strcat(path, DBLOCKFILE);
- strcpy(db->lock_file, path);
- if (stat(path, &lsb) == 0) {
- no_recover_flag = 1;
- }
+ strcpy(db->lock_file, path);
if ((db->lockfd = open(path, O_RDWR | O_CREAT, 0666)) > -1) {
lock.l_start = 0;
lock.l_len = 1;
LOG(log_error, logtype_default, "cnid_open: Cannot establish logfile cleanup lock for database environment %s (open() failed)", path);
}
- /* Create a file to represent database recovery. While this file
- * exists, the database is being recovered, and all other clients will
- * select until recovery is complete, and this file goes away. */
- if (!have_lock && db->lockfd > -1 && lock.l_start == 0 &&
- no_recover_flag == 0) {
- if (stat(recover_file, &rsb) == 0) {
- (void)remove(recover_file);
- }
- if ((rfd = open(recover_file, O_RDWR | O_CREAT, 0666)) > -1) {
- DBEXTRAS |= DB_RECOVER;
- have_lock = 1;
- }
- }
- else if (!have_lock) {
- while (stat(recover_file, &rsb) == 0) {
- struct timeval rt;
- rt.tv_sec = 1;
- rt.tv_usec = 0;
- (void)select(0, NULL, NULL, NULL, &rt);
- }
- }
-
path[len + DBHOMELEN] = '\0';
open_flag = DB_CREATE;
#endif /* DB_VERSION_MINOR > 1 */
/* Open the database environment. */
- if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS | DBEXTRAS, 0666)) != 0) {
+ if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666)) != 0) {
if (rc == DB_RUNRECOVERY) {
/* This is the mother of all errors. We _must_ fail here. */
LOG(log_error, logtype_default, "cnid_open: CATASTROPHIC ERROR opening database environment %s. Run db_recovery -c immediately", path);
LOG(log_info, logtype_default, "cnid_open: Obtained read-only database environment %s", path);
}
- /* If we have the recovery lock, close the file, remove it, so other
- * clients can proceed opening the DB environment. */
- if (rfd > -1) {
- if (remove(recover_file) < 0) {
- switch(errno) {
- case ENOENT:
- break;
- default:
- LOG(log_error, logtype_default, "cnid_open: Unable to remove %s: %s", recover_file, strerror(errno));
- }
- }
- close(rfd);
- rfd = -1;
- }
-
/* did/name reverse mapping. We use a BTree for this one. */
if ((rc = db_create(&db->db_didname, db->dbenv, 0)) != 0) {
LOG(log_error, logtype_default, "cnid_open: Failed to create did/name database: %s",
fail_lock:
if (db->lockfd > -1) {
close(db->lockfd);
- }
- if (rfd > -1) {
- (void)remove(recover_file);
- close(rfd);
+ (void)remove(db->lock_file);
}
fail_adouble:
/*
- * $Id: cnid_private.h,v 1.7 2002-01-29 21:12:18 jmarcus Exp $
+ * $Id: cnid_private.h,v 1.8 2002-02-01 19:51:09 jmarcus Exp $
*/
#ifndef LIBATALK_CNID_PRIVATE_H
#endif /* EXTENDED_DB */
DB_ENV* dbenv;
int lockfd, flags;
- char close_file[MAXPATHLEN + 1];
char lock_file[MAXPATHLEN + 1];
} CNID_private;