Main Page   Modules   Compound List   File List   Compound Members   File Members   Related Pages  

lib/dbconfig.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <db3/db.h>
00008 
00009 #include <rpmlib.h>
00010 #include <rpmmacro.h>
00011 
00012 #include "rpmdb.h"
00013 #include "debug.h"
00014 
00015 /*@access rpmdb@*/
00016 /*@access dbiIndex@*/
00017 /*@access dbiIndexSet@*/
00018 
00019 #if DB_VERSION_MAJOR == 3
00020 #define __USE_DB3       1
00021 
00022 struct _dbiIndex db3dbi;
00023 
00027 struct dbOption {
00028     const char * longName;      /* may be NULL */
00029     int argInfo;
00030     void * arg;                 /* depends on argInfo */
00031     int val;                    /* 0 means don't return, just update flag */
00032 };
00033 
00034 #define _POPT_SET_BIT   (POPT_ARG_VAL|POPT_ARGFLAG_OR)
00035 
00036 /*@-immediatetrans@*/
00039 struct dbOption rdbOptions[] = {
00040  /* XXX DB_CXX_NO_EXCEPTIONS */
00041  { "xa_create", _POPT_SET_BIT,          &db3dbi.dbi_cflags, DB_XA_CREATE },
00042 
00043  { "create",    _POPT_SET_BIT,          &db3dbi.dbi_oeflags, DB_CREATE },
00044  { "nommap",    _POPT_SET_BIT,          &db3dbi.dbi_oeflags, DB_NOMMAP },
00045  { "thread",    _POPT_SET_BIT,          &db3dbi.dbi_oeflags, DB_THREAD },
00046 
00047  { "force",     _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_FORCE },
00048  { "cdb",       _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_INIT_CDB },
00049  { "lock",      _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_INIT_LOCK },
00050  { "log",       _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_INIT_LOG },
00051  { "mpool",     _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_INIT_MPOOL },
00052  { "txn",       _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_INIT_TXN },
00053  { "recover",   _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_RECOVER },
00054  { "recover_fatal", _POPT_SET_BIT,      &db3dbi.dbi_eflags, DB_RECOVER_FATAL },
00055  { "shared",    _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_SYSTEM_MEM },
00056  { "txn_nosync", _POPT_SET_BIT,         &db3dbi.dbi_eflags, DB_TXN_NOSYNC },
00057  { "use_environ_root", _POPT_SET_BIT,   &db3dbi.dbi_eflags, DB_USE_ENVIRON_ROOT },
00058  { "use_environ", _POPT_SET_BIT,        &db3dbi.dbi_eflags, DB_USE_ENVIRON },
00059  { "lockdown",  _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_LOCKDOWN },
00060  { "private",   _POPT_SET_BIT,          &db3dbi.dbi_eflags, DB_PRIVATE },
00061 
00062  { "txn_sync",  _POPT_SET_BIT,          &db3dbi.dbi_tflags, DB_TXN_SYNC },
00063  { "txn_nowait",_POPT_SET_BIT,          &db3dbi.dbi_tflags, DB_TXN_NOWAIT },
00064 
00065  { "excl",      _POPT_SET_BIT,          &db3dbi.dbi_oflags, DB_EXCL },
00066  { "rdonly",    _POPT_SET_BIT,          &db3dbi.dbi_oflags, DB_RDONLY },
00067  { "truncate",  _POPT_SET_BIT,          &db3dbi.dbi_oflags, DB_TRUNCATE },
00068  { "fcntl_locking",_POPT_SET_BIT,       &db3dbi.dbi_oflags, DB_FCNTL_LOCKING },
00069 
00070  { "btree",     POPT_ARG_VAL,           &db3dbi.dbi_type, DB_BTREE },
00071  { "hash",      POPT_ARG_VAL,           &db3dbi.dbi_type, DB_HASH },
00072  { "recno",     POPT_ARG_VAL,           &db3dbi.dbi_type, DB_RECNO },
00073  { "queue",     POPT_ARG_VAL,           &db3dbi.dbi_type, DB_QUEUE },
00074  { "unknown",   POPT_ARG_VAL,           &db3dbi.dbi_type, DB_UNKNOWN },
00075 
00076  { "root",      POPT_ARG_STRING,        &db3dbi.dbi_root, 0 },
00077  { "home",      POPT_ARG_STRING,        &db3dbi.dbi_home, 0 },
00078  { "file",      POPT_ARG_STRING,        &db3dbi.dbi_file, 0 },
00079  { "subfile",   POPT_ARG_STRING,        &db3dbi.dbi_subfile, 0 },
00080  { "mode",      POPT_ARG_INT,           &db3dbi.dbi_mode, 0 },
00081  { "perms",     POPT_ARG_INT,           &db3dbi.dbi_perms, 0 },
00082 
00083  { "teardown",  POPT_ARG_NONE,          &db3dbi.dbi_tear_down, 0 },
00084  { "usecursors",POPT_ARG_NONE,          &db3dbi.dbi_use_cursors, 0 },
00085  { "usedbenv",  POPT_ARG_NONE,          &db3dbi.dbi_use_dbenv, 0 },
00086  { "rmwcursor", POPT_ARG_NONE,          &db3dbi.dbi_get_rmw_cursor, 0 },
00087  { "nofsync",   POPT_ARG_NONE,          &db3dbi.dbi_no_fsync, 0 },
00088  { "nodbsync",  POPT_ARG_NONE,          &db3dbi.dbi_no_dbsync, 0 },
00089  { "lockdbfd",  POPT_ARG_NONE,          &db3dbi.dbi_lockdbfd, 0 },
00090  { "temporary", POPT_ARG_NONE,          &db3dbi.dbi_temporary, 0 },
00091  { "debug",     POPT_ARG_NONE,          &db3dbi.dbi_debug, 0 },
00092 
00093  { "cachesize", POPT_ARG_INT,           &db3dbi.dbi_cachesize, 0 },
00094  { "errpfx",    POPT_ARG_STRING,        &db3dbi.dbi_errpfx, 0 },
00095  { "region_init", POPT_ARG_VAL,         &db3dbi.dbi_region_init, 1 },
00096  { "tas_spins", POPT_ARG_INT,           &db3dbi.dbi_tas_spins, 0 },
00097 
00098  { "chkpoint",  _POPT_SET_BIT,          &db3dbi.dbi_verbose, DB_VERB_CHKPOINT },
00099  { "deadlock",  _POPT_SET_BIT,          &db3dbi.dbi_verbose, DB_VERB_DEADLOCK },
00100  { "recovery",  _POPT_SET_BIT,          &db3dbi.dbi_verbose, DB_VERB_RECOVERY },
00101  { "waitsfor",  _POPT_SET_BIT,          &db3dbi.dbi_verbose, DB_VERB_WAITSFOR },
00102  { "verbose",   POPT_ARG_VAL,           &db3dbi.dbi_verbose, -1 },
00103 
00104  { "lk_oldest", POPT_ARG_VAL,           &db3dbi.dbi_lk_detect, DB_LOCK_OLDEST },
00105  { "lk_random", POPT_ARG_VAL,           &db3dbi.dbi_lk_detect, DB_LOCK_RANDOM },
00106  { "lk_youngest", POPT_ARG_VAL,         &db3dbi.dbi_lk_detect, DB_LOCK_YOUNGEST },
00107 /* XXX lk_conflicts matrix */
00108  { "lk_max",    POPT_ARG_INT,           &db3dbi.dbi_lk_max, 0 },
00109 
00110  { "lg_bsize",  POPT_ARG_INT,           &db3dbi.dbi_lg_bsize, 0 },
00111  { "lg_max",    POPT_ARG_INT,           &db3dbi.dbi_lg_max, 0 },
00112 
00113 /* XXX tx_recover */
00114  { "tx_max",    POPT_ARG_INT,           &db3dbi.dbi_tx_max, 0 },
00115 
00116  { "lorder",    POPT_ARG_INT,           &db3dbi.dbi_lorder, 0 },
00117 
00118  { "mp_mmapsize", POPT_ARG_INT,         &db3dbi.dbi_mp_mmapsize, 0 },
00119  { "mp_size",   POPT_ARG_INT,           &db3dbi.dbi_mp_size, 0 },
00120  { "pagesize",  POPT_ARG_INT,           &db3dbi.dbi_pagesize, 0 },
00121 
00122 /* XXX bt_minkey */
00123 /* XXX bt_compare */
00124 /* XXX bt_dup_compare */
00125 /* XXX bt_prefix */
00126  { "bt_dup",    _POPT_SET_BIT,          &db3dbi.dbi_bt_flags, DB_DUP },
00127  { "bt_dupsort",_POPT_SET_BIT,          &db3dbi.dbi_bt_flags, DB_DUPSORT },
00128  { "bt_recnum", _POPT_SET_BIT,          &db3dbi.dbi_bt_flags, DB_RECNUM },
00129  { "bt_revsplitoff", _POPT_SET_BIT,     &db3dbi.dbi_bt_flags, DB_REVSPLITOFF },
00130 
00131  { "h_dup",     _POPT_SET_BIT,          &db3dbi.dbi_h_flags, DB_DUP },
00132  { "h_dupsort", _POPT_SET_BIT,          &db3dbi.dbi_h_flags, DB_DUPSORT },
00133  { "h_ffactor", POPT_ARG_INT,           &db3dbi.dbi_h_ffactor, 0 },
00134  { "h_nelem",   POPT_ARG_INT,           &db3dbi.dbi_h_nelem, 0 },
00135 
00136  { "re_renumber", _POPT_SET_BIT,        &db3dbi.dbi_re_flags, DB_RENUMBER },
00137  { "re_snapshot",_POPT_SET_BIT,         &db3dbi.dbi_re_flags, DB_SNAPSHOT },
00138  { "re_delim",  POPT_ARG_INT,           &db3dbi.dbi_re_delim, 0 },
00139  { "re_len",    POPT_ARG_INT,           &db3dbi.dbi_re_len, 0 },
00140  { "re_pad",    POPT_ARG_INT,           &db3dbi.dbi_re_pad, 0 },
00141  { "re_source", POPT_ARG_STRING,        &db3dbi.dbi_re_source, 0 },
00142 
00143  { NULL, 0, NULL, 0 }
00144 };
00145 /*@=immediatetrans@*/
00146 
00147 static int dbSaveLong(const struct dbOption * opt, long aLong) {
00148     if (opt->argInfo & POPT_ARGFLAG_NOT)
00149         aLong = ~aLong;
00150     switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
00151     case 0:
00152         *((long *) opt->arg) = aLong;
00153         break;
00154     case POPT_ARGFLAG_OR:
00155         *((long *) opt->arg) |= aLong;
00156         break;
00157     case POPT_ARGFLAG_AND:
00158         *((long *) opt->arg) &= aLong;
00159         break;
00160     case POPT_ARGFLAG_XOR:
00161         *((long *) opt->arg) ^= aLong;
00162         break;
00163     default:
00164         return POPT_ERROR_BADOPERATION;
00165         /*@notreached@*/ break;
00166     }
00167     return 0;
00168 }
00169 
00170 static int dbSaveInt(const struct dbOption * opt, long aLong) {
00171     if (opt->argInfo & POPT_ARGFLAG_NOT)
00172         aLong = ~aLong;
00173     switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
00174     case 0:
00175         *((int *) opt->arg) = aLong;
00176         break;
00177     case POPT_ARGFLAG_OR:
00178         *((int *) opt->arg) |= aLong;
00179         break;
00180     case POPT_ARGFLAG_AND:
00181         *((int *) opt->arg) &= aLong;
00182         break;
00183     case POPT_ARGFLAG_XOR:
00184         *((int *) opt->arg) ^= aLong;
00185         break;
00186     default:
00187         return POPT_ERROR_BADOPERATION;
00188         /*@notreached@*/ break;
00189     }
00190     return 0;
00191 }
00192 
00193 void db3Free(dbiIndex dbi) {
00194     if (dbi) {
00195         if (dbi->dbi_root)      free((void *)dbi->dbi_root);
00196         if (dbi->dbi_home)      free((void *)dbi->dbi_home);
00197         if (dbi->dbi_file)      free((void *)dbi->dbi_file);
00198         if (dbi->dbi_subfile)   free((void *)dbi->dbi_subfile);
00199         if (dbi->dbi_errpfx)    free((void *)dbi->dbi_errpfx);
00200         if (dbi->dbi_re_source) free((void *)dbi->dbi_re_source);
00201         if (dbi->dbi_dbenv)     free(dbi->dbi_dbenv);
00202         if (dbi->dbi_dbinfo)    free(dbi->dbi_dbinfo);
00203         free((void *)dbi);
00204     }
00205 }
00206 
00207 static const char *db3_config_default =
00208     "db3:hash:mpool:cdb:usecursors:verbose:mp_mmapsize=8Mb:mp_size=512Kb:pagesize=512:perms=0644";
00209 
00210 dbiIndex db3New(rpmdb rpmdb, int rpmtag)
00211 {
00212     dbiIndex dbi = xcalloc(1, sizeof(*dbi));
00213     char dbiTagMacro[128];
00214     char * dbOpts;
00215 
00216     sprintf(dbiTagMacro, "%%{_dbi_config_%s}", tagName(rpmtag));
00217     dbOpts = rpmExpand(dbiTagMacro, NULL);
00218     if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
00219         if (dbOpts) {
00220             free(dbOpts);
00221             dbOpts = NULL;
00222         }
00223         dbOpts = rpmExpand("%{_dbi_config}", NULL);
00224         if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
00225             dbOpts = rpmExpand(db3_config_default, NULL);
00226         }
00227     }
00228 
00229     if (dbOpts && *dbOpts && *dbOpts != '%') {
00230         char *o, *oe;
00231         char *p, *pe;
00232         for (o = dbOpts; o && *o; o = oe) {
00233             struct dbOption *opt;
00234 
00235             while (*o && isspace(*o))
00236                 o++;
00237             for (oe = o; oe && *oe; oe++) {
00238                 if (isspace(*oe))
00239                     break;
00240                 if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/'))
00241                     break;
00242             }
00243             if (oe && *oe)
00244                 *oe++ = '\0';
00245             if (*o == '\0')
00246                 continue;
00247             for (pe = o; pe && *pe && *pe != '='; pe++)
00248                 ;
00249             p = (pe ? *pe++ = '\0', pe : NULL);
00250 
00251             for (opt = rdbOptions; opt->longName != NULL; opt++) {
00252                 if (strcmp(o, opt->longName))
00253                     continue;
00254                 break;
00255             }
00256             if (opt->longName == NULL) {
00257                 rpmError(RPMERR_DBCONFIG,
00258                         _("unrecognized db option: \"%s\" ignored\n"), o);
00259                 continue;
00260             }
00261 
00262             switch (opt->argInfo & POPT_ARG_MASK) {
00263             long aLong;
00264 
00265             case POPT_ARG_NONE:
00266                 (void) dbSaveInt(opt, 1L);
00267                 break;
00268             case POPT_ARG_VAL:
00269                 (void) dbSaveInt(opt, (long)opt->val);
00270                 break;
00271             case POPT_ARG_STRING:
00272             {   const char ** t = opt->arg;
00273                 if (*t) free((void *)*t);
00274                 *t = xstrdup( (p ? p : "") );
00275             }   break;
00276 
00277             case POPT_ARG_INT:
00278             case POPT_ARG_LONG:
00279                 aLong = strtol(p, &pe, 0);
00280                 if (pe) {
00281                     if (!xstrncasecmp(pe, "Mb", 2))
00282                         aLong *= 1024 * 1024;
00283                     else if (!xstrncasecmp(pe, "Kb", 2))
00284                         aLong *= 1024;
00285                     else if (*pe != '\0') {
00286                         rpmError(RPMERR_DBCONFIG,
00287                                 _("%s has invalid numeric value, skipped\n"),
00288                                 opt->longName);
00289                         continue;
00290                     }
00291                 }
00292 
00293                 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
00294                     if (aLong == LONG_MIN || aLong == LONG_MAX) {
00295                         rpmError(RPMERR_DBCONFIG,
00296                                 _("%s has too large or too small long value, skipped\n"),
00297                                 opt->longName);
00298                         continue;
00299                     }
00300                     (void) dbSaveLong(opt, aLong);
00301                     break;
00302                 } else {
00303                     if (aLong > INT_MAX || aLong < INT_MIN) {
00304                         rpmError(RPMERR_DBCONFIG,
00305                                 _("%s has too large or too small integer value, skipped\n"),
00306                                 opt->longName);
00307                         continue;
00308                     }
00309                     (void) dbSaveInt(opt, aLong);
00310                 }
00311                 break;
00312             default:
00313                 break;
00314             }
00315         }
00316     }
00317 
00318     free(dbOpts);
00319 
00320     *dbi = db3dbi;      /* structure assignment */
00321     memset(&db3dbi, 0, sizeof(db3dbi));
00322 
00323     if (!(dbi->dbi_perms & 0600))
00324         dbi->dbi_perms = 0644;
00325     dbi->dbi_mode = rpmdb->db_mode;
00326     dbi->dbi_rpmdb = rpmdb;
00327     dbi->dbi_rpmtag = rpmtag;
00328     
00329     switch (rpmtag) {
00330     case RPMDBI_PACKAGES:
00331     case RPMDBI_DEPENDS:
00332         dbi->dbi_jlen = 1 * sizeof(int_32);
00333         break;
00334     default:
00335         dbi->dbi_jlen = 2 * sizeof(int_32);
00336         break;
00337     }
00338     return dbi;
00339 }
00340 
00341 const char *const prDbiOpenFlags(int dbflags, int print_dbenv_flags)
00342 {
00343     static char buf[256];
00344     struct dbOption *opt;
00345     char * oe;
00346 
00347     oe = buf;
00348     *oe = '\0';
00349     for (opt = rdbOptions; opt->longName != NULL; opt++) {
00350         if (opt->argInfo != _POPT_SET_BIT)
00351             continue;
00352         if (print_dbenv_flags) {
00353             if (!(opt->arg == &db3dbi.dbi_oeflags ||
00354                   opt->arg == &db3dbi.dbi_eflags))
00355                 continue;
00356         } else {
00357             if (!(opt->arg == &db3dbi.dbi_oeflags ||
00358                   opt->arg == &db3dbi.dbi_oflags))
00359                 continue;
00360         }
00361         if ((dbflags & opt->val) != opt->val)
00362             continue;
00363         if (oe != buf)
00364             *oe++ = ':';
00365         oe = stpcpy(oe, opt->longName);
00366         dbflags &= ~opt->val;
00367     }
00368     if (dbflags) {
00369         if (oe != buf)
00370             *oe++ = ':';
00371             sprintf(oe, "0x%x", (unsigned)dbflags);
00372     }
00373     return buf;
00374 }
00375 
00376 #endif

Generated at Mon May 21 08:53:39 2001 for rpm by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001