00001
00002
00003 #include "db_config.h"
00004
00005 #ifndef NO_SYSTEM_INCLUDES
00006 #include <sys/types.h>
00007
00008 #include <ctype.h>
00009 #include <string.h>
00010 #endif
00011
00012 #include "db_int.h"
00013 #include "dbinc/crypto.h"
00014 #include "dbinc/db_page.h"
00015 #include "dbinc/db_dispatch.h"
00016 #include "dbinc/db_am.h"
00017 #include "dbinc/log.h"
00018 #include "dbinc/txn.h"
00019
00020
00021
00022
00023
00024
00025 int
00026 __dbreg_register_log(dbenv, txnid, ret_lsnp, flags,
00027 opcode, name, uid, fileid, ftype, meta_pgno,
00028 id)
00029 DB_ENV *dbenv;
00030 DB_TXN *txnid;
00031 DB_LSN *ret_lsnp;
00032 u_int32_t flags;
00033 u_int32_t opcode;
00034 const DBT *name;
00035 const DBT *uid;
00036 int32_t fileid;
00037 DBTYPE ftype;
00038 db_pgno_t meta_pgno;
00039 u_int32_t id;
00040 {
00041 DBT logrec;
00042 DB_TXNLOGREC *lr;
00043 DB_LSN *lsnp, null_lsn, *rlsnp;
00044 u_int32_t zero, uinttmp, rectype, txn_num;
00045 u_int npad;
00046 u_int8_t *bp;
00047 int is_durable, ret;
00048
00049 COMPQUIET(lr, NULL);
00050
00051 rectype = DB___dbreg_register;
00052 npad = 0;
00053 rlsnp = ret_lsnp;
00054
00055 ret = 0;
00056
00057 if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
00058 if (txnid == NULL)
00059 return (0);
00060 is_durable = 0;
00061 } else
00062 is_durable = 1;
00063
00064 if (txnid == NULL) {
00065 txn_num = 0;
00066 lsnp = &null_lsn;
00067 null_lsn.file = null_lsn.offset = 0;
00068 } else {
00069 if (TAILQ_FIRST(&txnid->kids) != NULL &&
00070 (ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
00071 return (ret);
00072
00073
00074
00075
00076
00077
00078 DB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);
00079 txn_num = txnid->txnid;
00080 }
00081
00082 logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
00083 + sizeof(u_int32_t)
00084 + sizeof(u_int32_t) + (name == NULL ? 0 : name->size)
00085 + sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size)
00086 + sizeof(u_int32_t)
00087 + sizeof(u_int32_t)
00088 + sizeof(u_int32_t)
00089 + sizeof(u_int32_t);
00090 if (CRYPTO_ON(dbenv)) {
00091 npad =
00092 ((DB_CIPHER *)dbenv->crypto_handle)->adj_size(logrec.size);
00093 logrec.size += npad;
00094 }
00095
00096 if (is_durable || txnid == NULL) {
00097 if ((ret =
00098 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
00099 return (ret);
00100 } else {
00101 if ((ret = __os_malloc(dbenv,
00102 logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
00103 return (ret);
00104 #ifdef DIAGNOSTIC
00105 if ((ret =
00106 __os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
00107 __os_free(dbenv, lr);
00108 return (ret);
00109 }
00110 #else
00111 logrec.data = lr->data;
00112 #endif
00113 }
00114 if (npad > 0)
00115 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
00116
00117 bp = logrec.data;
00118
00119 memcpy(bp, &rectype, sizeof(rectype));
00120 bp += sizeof(rectype);
00121
00122 memcpy(bp, &txn_num, sizeof(txn_num));
00123 bp += sizeof(txn_num);
00124
00125 memcpy(bp, lsnp, sizeof(DB_LSN));
00126 bp += sizeof(DB_LSN);
00127
00128 uinttmp = (u_int32_t)opcode;
00129 memcpy(bp, &uinttmp, sizeof(uinttmp));
00130 bp += sizeof(uinttmp);
00131
00132 if (name == NULL) {
00133 zero = 0;
00134 memcpy(bp, &zero, sizeof(u_int32_t));
00135 bp += sizeof(u_int32_t);
00136 } else {
00137 memcpy(bp, &name->size, sizeof(name->size));
00138 bp += sizeof(name->size);
00139 memcpy(bp, name->data, name->size);
00140 bp += name->size;
00141 }
00142
00143 if (uid == NULL) {
00144 zero = 0;
00145 memcpy(bp, &zero, sizeof(u_int32_t));
00146 bp += sizeof(u_int32_t);
00147 } else {
00148 memcpy(bp, &uid->size, sizeof(uid->size));
00149 bp += sizeof(uid->size);
00150 memcpy(bp, uid->data, uid->size);
00151 bp += uid->size;
00152 }
00153
00154 uinttmp = (u_int32_t)fileid;
00155 memcpy(bp, &uinttmp, sizeof(uinttmp));
00156 bp += sizeof(uinttmp);
00157
00158 uinttmp = (u_int32_t)ftype;
00159 memcpy(bp, &uinttmp, sizeof(uinttmp));
00160 bp += sizeof(uinttmp);
00161
00162 uinttmp = (u_int32_t)meta_pgno;
00163 memcpy(bp, &uinttmp, sizeof(uinttmp));
00164 bp += sizeof(uinttmp);
00165
00166 uinttmp = (u_int32_t)id;
00167 memcpy(bp, &uinttmp, sizeof(uinttmp));
00168 bp += sizeof(uinttmp);
00169
00170 DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
00171
00172 if (is_durable || txnid == NULL) {
00173 if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
00174 flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
00175 *lsnp = *rlsnp;
00176 if (rlsnp != ret_lsnp)
00177 *ret_lsnp = *rlsnp;
00178 }
00179 } else {
00180 #ifdef DIAGNOSTIC
00181
00182
00183
00184
00185 memcpy(lr->data, logrec.data, logrec.size);
00186 rectype |= DB_debug_FLAG;
00187 memcpy(logrec.data, &rectype, sizeof(rectype));
00188
00189 ret = __log_put(dbenv,
00190 rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
00191 #else
00192 ret = 0;
00193 #endif
00194 STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
00195 F_SET((TXN_DETAIL *)txnid->td, TXN_DTL_INMEMORY);
00196 LSN_NOT_LOGGED(*ret_lsnp);
00197 }
00198
00199 #ifdef LOG_DIAGNOSTIC
00200 if (ret != 0)
00201 (void)__dbreg_register_print(dbenv,
00202 (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
00203 #endif
00204
00205 #ifdef DIAGNOSTIC
00206 __os_free(dbenv, logrec.data);
00207 #else
00208 if (is_durable || txnid == NULL)
00209 __os_free(dbenv, logrec.data);
00210 #endif
00211 return (ret);
00212 }
00213
00214
00215
00216
00217
00218 int
00219 __dbreg_register_read(dbenv, recbuf, argpp)
00220 DB_ENV *dbenv;
00221 void *recbuf;
00222 __dbreg_register_args **argpp;
00223 {
00224 __dbreg_register_args *argp;
00225 u_int32_t uinttmp;
00226 u_int8_t *bp;
00227 int ret;
00228
00229 if ((ret = __os_malloc(dbenv,
00230 sizeof(__dbreg_register_args) + sizeof(DB_TXN), &argp)) != 0)
00231 return (ret);
00232 bp = recbuf;
00233 argp->txnid = (DB_TXN *)&argp[1];
00234
00235 memcpy(&argp->type, bp, sizeof(argp->type));
00236 bp += sizeof(argp->type);
00237
00238 memcpy(&argp->txnid->txnid, bp, sizeof(argp->txnid->txnid));
00239 bp += sizeof(argp->txnid->txnid);
00240
00241 memcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));
00242 bp += sizeof(DB_LSN);
00243
00244 memcpy(&uinttmp, bp, sizeof(uinttmp));
00245 argp->opcode = (u_int32_t)uinttmp;
00246 bp += sizeof(uinttmp);
00247
00248 memset(&argp->name, 0, sizeof(argp->name));
00249 memcpy(&argp->name.size, bp, sizeof(u_int32_t));
00250 bp += sizeof(u_int32_t);
00251 argp->name.data = bp;
00252 bp += argp->name.size;
00253
00254 memset(&argp->uid, 0, sizeof(argp->uid));
00255 memcpy(&argp->uid.size, bp, sizeof(u_int32_t));
00256 bp += sizeof(u_int32_t);
00257 argp->uid.data = bp;
00258 bp += argp->uid.size;
00259
00260 memcpy(&uinttmp, bp, sizeof(uinttmp));
00261 argp->fileid = (int32_t)uinttmp;
00262 bp += sizeof(uinttmp);
00263
00264 memcpy(&uinttmp, bp, sizeof(uinttmp));
00265 argp->ftype = (DBTYPE)uinttmp;
00266 bp += sizeof(uinttmp);
00267
00268 memcpy(&uinttmp, bp, sizeof(uinttmp));
00269 argp->meta_pgno = (db_pgno_t)uinttmp;
00270 bp += sizeof(uinttmp);
00271
00272 memcpy(&uinttmp, bp, sizeof(uinttmp));
00273 argp->id = (u_int32_t)uinttmp;
00274 bp += sizeof(uinttmp);
00275
00276 *argpp = argp;
00277 return (0);
00278 }
00279
00280
00281
00282
00283
00284 int
00285 __dbreg_init_recover(dbenv, dtabp, dtabsizep)
00286 DB_ENV *dbenv;
00287 int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00288 size_t *dtabsizep;
00289 {
00290 int ret;
00291
00292 if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
00293 __dbreg_register_recover, DB___dbreg_register)) != 0)
00294 return (ret);
00295 return (0);
00296 }