/* -------------------- */ static int transmit(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) { time_t orig, t; int clean = 1; /* no errors so far - to prevent sleep on first try */ while (1) { if (db->fd == -1) { LOG(log_maxdebug, logtype_cnid, "transmit: connecting to cnid_dbd ..."); if ((db->fd = init_tsock(db)) < 0) { goto transmit_fail; } if (db->notfirst) { LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd"); } else { /* db->notfirst == 0 */ db->notfirst = 1; } LOG(log_debug, logtype_cnid, "transmit: attached to '%s'", db->vol->v_localname); } if (!dbd_rpc(db, rqst, rply)) { LOG(log_maxdebug, logtype_cnid, "transmit: {done}"); return 0; } transmit_fail: if (db->fd != -1) { close(db->fd); db->fd = -1; /* FD not valid... will need to reconnect */ } if (errno == ECONNREFUSED) { /* errno carefully injected in tsock_getfd */ /* give up */ LOG(log_error, logtype_cnid, "transmit: connection refused (volume %s)", db->vol->v_localname); return -1; } if (!clean) { /* don't sleep if just got disconnected by cnid server */ time(&t); if (t - orig > MAX_DELAY) { LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (volume %s) timed out.", db->vol->v_localname); return -1; } /* sleep a little before retry */ delay(1); } else { clean = 0; /* false... next time sleep */ time(&orig); } } return -1; }
/* -------------------- */ static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) { time_t orig, t; int clean = 1; /* no errors so far - to prevent sleep on first try */ if (db->changed) { /* volume and db don't have the same timestamp */ return -1; } while (1) { if (db->fd == -1) { struct cnid_dbd_rqst rqst_stamp; struct cnid_dbd_rply rply_stamp; char stamp[ADEDLEN_PRIVSYN]; LOG(log_maxdebug, logtype_cnid, "transmit: connecting to cnid_dbd ..."); if ((db->fd = init_tsock(db)) < 0) { goto transmit_fail; } dbd_initstamp(&rqst_stamp); memset(stamp, 0, ADEDLEN_PRIVSYN); rply_stamp.name = stamp; rply_stamp.namelen = ADEDLEN_PRIVSYN; if (dbd_rpc(db, &rqst_stamp, &rply_stamp) < 0) goto transmit_fail; if (dbd_reply_stamp(&rply_stamp ) < 0) goto transmit_fail; if (db->notfirst) { LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd, comparing database stamps..."); if (memcmp(stamp, db->stamp, ADEDLEN_PRIVSYN)) { LOG(log_error, logtype_cnid, "transmit: ... not the same db!"); db->changed = 1; return -1; } LOG(log_debug7, logtype_cnid, "transmit: ... OK."); } else { /* db->notfirst == 0 */ db->notfirst = 1; if (db->client_stamp) memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN); memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN); } LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.", db->db_dir, *(uint64_t *)stamp); } if (!dbd_rpc(db, rqst, rply)) { LOG(log_maxdebug, logtype_cnid, "transmit: {done}"); return 0; } transmit_fail: if (db->fd != -1) { close(db->fd); db->fd = -1; /* FD not valid... will need to reconnect */ } if (errno == ECONNREFUSED) { /* errno carefully injected in tsock_getfd */ /* give up */ LOG(log_error, logtype_cnid, "transmit: connection refused (db_dir %s)", db->db_dir); return -1; } if (!clean) { /* don't sleep if just got disconnected by cnid server */ time(&t); if (t - orig > MAX_DELAY) { LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (db_dir %s) timed out.", db->db_dir); return -1; } /* sleep a little before retry */ delay(1); } else { clean = 0; /* false... next time sleep */ time(&orig); } } return -1; }