00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #if TIME_WITH_SYS_TIME
00014 #include <sys/time.h>
00015 #include <time.h>
00016 #else
00017 #if HAVE_SYS_TIME_H
00018 #include <sys/time.h>
00019 #else
00020 #include <time.h>
00021 #endif
00022 #endif
00023
00024 #include <string.h>
00025 #endif
00026
00027 #include "db_int.h"
00028 #include "dbinc/db_page.h"
00029 #include "dbinc/db_am.h"
00030 #include "dbinc/log.h"
00031
00032 static int __rep_egen_init __P((DB_ENV *, REP *));
00033
00034
00035
00036
00037
00038
00039
00040 int
00041 __rep_region_init(dbenv)
00042 DB_ENV *dbenv;
00043 {
00044 REGENV *renv;
00045 REGINFO *infop;
00046 DB_REP *db_rep;
00047 REP *rep;
00048 int ret;
00049
00050 db_rep = dbenv->rep_handle;
00051 infop = dbenv->reginfo;
00052 renv = infop->primary;
00053 ret = 0;
00054
00055 if (renv->rep_off == INVALID_ROFF) {
00056
00057 if ((ret = __db_shalloc(infop, sizeof(REP), 0, &rep)) != 0)
00058 return (ret);
00059 memset(rep, 0, sizeof(*rep));
00060 rep->tally_off = INVALID_ROFF;
00061 rep->v2tally_off = INVALID_ROFF;
00062 renv->rep_off = R_OFFSET(infop, rep);
00063
00064 if ((ret = __mutex_alloc(
00065 dbenv, MTX_REP_REGION, 0, &rep->mtx_region)) != 0)
00066 return (ret);
00067
00068
00069
00070
00071
00072
00073
00074
00075 if ((ret = __mutex_alloc(
00076 dbenv, MTX_REP_DATABASE, 0, &rep->mtx_clientdb)) != 0)
00077 return (ret);
00078
00079
00080 rep->eid = DB_EID_INVALID;
00081 rep->master_id = DB_EID_INVALID;
00082 rep->gen = 0;
00083 if ((ret = __rep_egen_init(dbenv, rep)) != 0)
00084 return (ret);
00085
00086
00087
00088
00089 rep->request_gap = DB_REP_REQUEST_GAP;
00090 rep->max_gap = DB_REP_MAX_GAP;
00091 F_SET(rep, REP_F_NOARCHIVE);
00092 (void)time(&renv->rep_timestamp);
00093 renv->op_timestamp = 0;
00094 F_CLR(renv, DB_REGENV_REPLOCKED);
00095 } else
00096 rep = R_ADDR(infop, renv->rep_off);
00097
00098 db_rep->region = rep;
00099
00100 return (0);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 int
00110 __rep_region_destroy(dbenv)
00111 DB_ENV *dbenv;
00112 {
00113 DB_REP *db_rep;
00114 REGENV *renv;
00115 REGINFO *infop;
00116 int ret, t_ret;
00117
00118 if (!REP_ON(dbenv))
00119 return (0);
00120
00121 ret = 0;
00122
00123 db_rep = dbenv->rep_handle;
00124 if (db_rep->region != NULL) {
00125 ret = __mutex_free(dbenv, &db_rep->region->mtx_region);
00126 if ((t_ret = __mutex_free(
00127 dbenv, &db_rep->region->mtx_clientdb)) != 0 && ret == 0)
00128 ret = t_ret;
00129 }
00130
00131 infop = dbenv->reginfo;
00132 renv = infop->primary;
00133 if (renv->rep_off != INVALID_ROFF)
00134 __db_shalloc_free(infop, R_ADDR(infop, renv->rep_off));
00135
00136 return (ret);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 void
00146 __rep_dbenv_refresh(dbenv)
00147 DB_ENV *dbenv;
00148 {
00149 if (REP_ON(dbenv))
00150 ((DB_REP *)dbenv->rep_handle)->region = NULL;
00151 return;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 int
00161 __rep_dbenv_close(dbenv)
00162 DB_ENV *dbenv;
00163 {
00164 if (REP_ON(dbenv)) {
00165 __os_free(dbenv, dbenv->rep_handle);
00166 dbenv->rep_handle = NULL;
00167 dbenv->rep_send = NULL;
00168 }
00169
00170 return (0);
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 int
00181 __rep_preclose(dbenv)
00182 DB_ENV *dbenv;
00183 {
00184 DB_LOG *dblp;
00185 DB_REP *db_rep;
00186 LOG *lp;
00187 REP_BULK bulk;
00188 int ret, t_ret;
00189
00190 ret = 0;
00191
00192 db_rep = dbenv->rep_handle;
00193 dblp = dbenv->lg_handle;
00194 lp = dblp->reginfo.primary;
00195
00196 MUTEX_LOCK(dbenv, db_rep->region->mtx_clientdb);
00197 if (db_rep->rep_db != NULL) {
00198 ret = __db_close(db_rep->rep_db, NULL, DB_NOSYNC);
00199 db_rep->rep_db = NULL;
00200 }
00201
00202 if ((t_ret = __dbreg_close_files(dbenv)) != 0 && ret == 0)
00203 ret = t_ret;
00204 F_CLR(db_rep, DBREP_OPENFILES);
00205
00206
00207
00208
00209 if (lp->bulk_off != 0 && dbenv->rep_send != NULL) {
00210 memset(&bulk, 0, sizeof(bulk));
00211 bulk.addr = R_ADDR(&dblp->reginfo, lp->bulk_buf);
00212 bulk.offp = &lp->bulk_off;
00213 bulk.len = lp->bulk_len;
00214 bulk.type = REP_BULK_LOG;
00215 bulk.eid = DB_EID_BROADCAST;
00216 bulk.flagsp = &lp->bulk_flags;
00217 if ((t_ret = __rep_send_bulk(dbenv, &bulk, 0)) != 0 && ret == 0)
00218 ret = t_ret;
00219 }
00220 MUTEX_UNLOCK(dbenv, db_rep->region->mtx_clientdb);
00221 return (ret);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 static int
00232 __rep_egen_init(dbenv, rep)
00233 DB_ENV *dbenv;
00234 REP *rep;
00235 {
00236 DB_FH *fhp;
00237 int ret;
00238 size_t cnt;
00239 char *p;
00240 #ifdef DIAGNOSTIC
00241 DB_MSGBUF mb;
00242 #endif
00243
00244 if ((ret =
00245 __db_appname(dbenv, DB_APP_NONE, REP_EGENNAME, 0, NULL, &p)) != 0)
00246 return (ret);
00247
00248
00249
00250 if (__os_exists(p, NULL) != 0) {
00251 rep->egen = rep->gen + 1;
00252 if ((ret = __rep_write_egen(dbenv, rep->egen)) != 0)
00253 goto err;
00254 } else {
00255
00256
00257
00258 if ((ret = __os_open(dbenv, p, DB_OSO_RDONLY,
00259 __db_omode(OWNER_RW), &fhp)) != 0)
00260 goto err;
00261 if ((ret = __os_read(dbenv, fhp, &rep->egen, sizeof(u_int32_t),
00262 &cnt)) < 0 || cnt == 0)
00263 goto err1;
00264 RPRINT(dbenv, rep, (dbenv, &mb, "Read in egen %lu",
00265 (u_long)rep->egen));
00266 err1: (void)__os_closehandle(dbenv, fhp);
00267 }
00268 err: __os_free(dbenv, p);
00269 return (ret);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 int
00279 __rep_write_egen(dbenv, egen)
00280 DB_ENV *dbenv;
00281 u_int32_t egen;
00282 {
00283 DB_FH *fhp;
00284 int ret;
00285 size_t cnt;
00286 char *p;
00287
00288 if ((ret =
00289 __db_appname(dbenv, DB_APP_NONE, REP_EGENNAME, 0, NULL, &p)) != 0)
00290 return (ret);
00291 if ((ret = __os_open(dbenv, p, DB_OSO_CREATE | DB_OSO_TRUNC,
00292 __db_omode(OWNER_RW), &fhp)) == 0) {
00293 if ((ret = __os_write(dbenv, fhp, &egen, sizeof(u_int32_t),
00294 &cnt)) != 0 || ((ret = __os_fsync(dbenv, fhp)) != 0))
00295 __db_err(dbenv, "%s: %s", p, db_strerror(ret));
00296 (void)__os_closehandle(dbenv, fhp);
00297 }
00298 __os_free(dbenv, p);
00299 return (ret);
00300 }