qam_verify.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1999, 2000
00005  *      Sleepycat Software.  All rights reserved.
00006  */
00007 
00008 #include "config.h"
00009 
00010 #ifndef lint
00011 static const char revid[] = "$Id: qam__verify_8c-source.html,v 1.1 2008/06/08 10:21:47 sebdiaz Exp $";
00012 #endif /* not lint */
00013 
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016 
00017 #endif
00018 
00019 #include "db_int.h"
00020 #include "db_page.h"
00021 #include "db_verify.h"
00022 #include "qam.h"
00023 #include "db_ext.h"
00024 
00025 /*
00026  * CDB___qam_vrfy_meta --
00027  *      Verify the queue-specific part of a metadata page.
00028  *
00029  * PUBLIC: int CDB___qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *,
00030  * PUBLIC:     db_pgno_t, u_int32_t));
00031  */
00032 int
00033 CDB___qam_vrfy_meta(dbp, vdp, meta, pgno, flags)
00034         DB *dbp;
00035         VRFY_DBINFO *vdp;
00036         QMETA *meta;
00037         db_pgno_t pgno;
00038         u_int32_t flags;
00039 {
00040         VRFY_PAGEINFO *pip;
00041         int isbad, ret, t_ret;
00042 
00043         if ((ret = CDB___db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
00044                 return (ret);
00045         isbad = 0;
00046 
00047         /*
00048          * Queue can't be used in subdatabases, so if this isn't set
00049          * something very odd is going on.
00050          */
00051         if (!F_ISSET(pip, VRFY_INCOMPLETE))
00052                 EPRINT((dbp->dbenv, "Queue databases must be one-per-file."));
00053 
00054         /* start */
00055         if (meta->start != 1) {
00056                 EPRINT((dbp->dbenv,
00057                     "Queue start offset of %lu", meta->start));
00058                 isbad = 1;
00059         }
00060 
00061         /* first_recno, cur_recno */
00062         if (meta->cur_recno < meta->first_recno) {
00063                 EPRINT((dbp->dbenv,
00064                     "Wrongly ordered first/current recnos, %lu/%lu",
00065                      meta->first_recno, meta->cur_recno));
00066                 isbad = 1;
00067         }
00068 
00069         /* cur_recno/rec_page */
00070         if (vdp->last_pgno > 0 &&
00071             (1 + ((meta->cur_recno - meta->start) / meta->rec_page)) !=
00072             vdp->last_pgno) {
00073                 EPRINT((dbp->dbenv,
00074                     "Incorrect last page number in queue database"));
00075                 isbad = 1;
00076         }
00077 
00078         /*
00079          * re_len:  If this is bad, we can't safely verify queue data pages, so
00080          * return DB_VERIFY_FATAL
00081          */
00082         if (ALIGN(meta->re_len + sizeof(QAMDATA) - 1, sizeof(u_int32_t)) *
00083             meta->rec_page + sizeof(QPAGE) > dbp->pgsize) {
00084                 EPRINT((dbp->dbenv,
00085    "Queue record length %lu impossibly high for page size and records per page",
00086                     meta->re_len));
00087                 ret = DB_VERIFY_FATAL;
00088                 goto err;
00089         } else {
00090                 vdp->re_len = meta->re_len;
00091                 vdp->rec_page = meta->rec_page;
00092         }
00093 
00094 err:    if ((t_ret = CDB___db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
00095                 ret = t_ret;
00096         return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret);
00097 }
00098 
00099 /*
00100  * CDB___qam_vrfy_data --
00101  *      Verify a queue data page.
00102  *
00103  * PUBLIC: int CDB___qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *,
00104  * PUBLIC:     db_pgno_t, u_int32_t));
00105  */
00106 int
00107 CDB___qam_vrfy_data(dbp, vdp, h, pgno, flags)
00108         DB *dbp;
00109         VRFY_DBINFO *vdp;
00110         QPAGE *h;
00111         db_pgno_t pgno;
00112         u_int32_t flags;
00113 {
00114         DB fakedb;
00115         struct __queue fakeq;
00116         QAMDATA *qp;
00117         db_recno_t i;
00118         u_int8_t qflags;
00119 
00120         /*
00121          * Not much to do here, except make sure that flags are reasonable.
00122          *
00123          * QAM_GET_RECORD assumes a properly initialized q_internal
00124          * structure, however, and we don't have one, so we play
00125          * some gross games to fake it out.
00126          */
00127         fakedb.q_internal = &fakeq;
00128         fakeq.re_len = vdp->re_len;
00129 
00130         for (i = 0; i < vdp->rec_page; i++) {
00131                 qp = QAM_GET_RECORD(&fakedb, h, i);
00132                 if ((u_int8_t *)qp >= (u_int8_t *)h + dbp->pgsize) {
00133                         EPRINT((dbp->dbenv,
00134                             "Queue record %lu extends past end of page %lu",
00135                             i, pgno));
00136                         return (DB_VERIFY_BAD);
00137                 }
00138 
00139                 qflags = qp->flags;
00140                 qflags &= !(QAM_VALID | QAM_SET);
00141                 if (qflags != 0) {
00142                         EPRINT((dbp->dbenv,
00143                             "Queue record %lu on page %lu has bad flags",
00144                             i, pgno));
00145                         return (DB_VERIFY_BAD);
00146                 }
00147         }
00148 
00149         return (0);
00150 }
00151 
00152 /*
00153  * CDB___qam_vrfy_structure --
00154  *      Verify a queue database structure, such as it is.
00155  *
00156  * PUBLIC: int CDB___qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
00157  */
00158 int
00159 CDB___qam_vrfy_structure(dbp, vdp, flags)
00160         DB *dbp;
00161         VRFY_DBINFO *vdp;
00162         u_int32_t flags;
00163 {
00164         VRFY_PAGEINFO *pip;
00165         db_pgno_t i;
00166         int ret, isbad;
00167 
00168         isbad = 0;
00169 
00170         if ((ret = CDB___db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
00171                 return (ret);
00172 
00173         if (pip->type != P_QAMMETA) {
00174                 EPRINT((dbp->dbenv,
00175                     "Queue database has no meta page"));
00176                 isbad = 1;
00177                 goto err;
00178         }
00179 
00180         if ((ret = CDB___db_vrfy_pgset_inc(vdp->pgset, 0)) != 0)
00181                 goto err;
00182 
00183         for (i = 1; i <= vdp->last_pgno; i++) {
00184                 if ((ret = CDB___db_vrfy_putpageinfo(vdp, pip)) != 0 ||
00185                     (ret = CDB___db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
00186                         return (ret);
00187                 if (!F_ISSET(pip, VRFY_IS_ALLZEROES) &&
00188                     pip->type != P_QAMDATA) {
00189                         EPRINT((dbp->dbenv,
00190                             "Queue database page %lu of incorrect type %lu",
00191                             i, pip->type));
00192                         isbad = 1;
00193                         goto err;
00194                 } else if ((ret = CDB___db_vrfy_pgset_inc(vdp->pgset, i)) != 0)
00195                         goto err;
00196         }
00197 
00198 err:    if ((ret = CDB___db_vrfy_putpageinfo(vdp, pip)) != 0)
00199                 return (ret);
00200         return (isbad == 1 ? DB_VERIFY_BAD : 0);
00201 }

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by  doxygen 1.5.5