Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

db_setid.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2000-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_setid.c,v 12.8 2005/10/18 14:17:08 mjc Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <string.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 #include "dbinc/db_page.h"
00020 #include "dbinc/db_shash.h"
00021 #include "dbinc/db_swap.h"
00022 #include "dbinc/db_am.h"
00023 #include "dbinc/mp.h"
00024 
00025 static int __env_fileid_reset __P((DB_ENV *, const char *, int));
00026 
00027 /*
00028  * __env_fileid_reset_pp --
00029  *      DB_ENV->fileid_reset pre/post processing.
00030  *
00031  * PUBLIC: int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t));
00032  */
00033 int
00034 __env_fileid_reset_pp(dbenv, name, flags)
00035         DB_ENV *dbenv;
00036         const char *name;
00037         u_int32_t flags;
00038 {
00039         DB_THREAD_INFO *ip;
00040         int handle_check, ret, t_ret;
00041 
00042         PANIC_CHECK(dbenv);
00043         ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->fileid_reset");
00044 
00045         /*
00046          * !!!
00047          * The actual argument checking is simple, do it inline, outside of
00048          * the replication block.
00049          */
00050         if (flags != 0 && flags != DB_ENCRYPT)
00051                 return (__db_ferr(dbenv, "DB_ENV->fileid_reset", 0));
00052 
00053         ENV_ENTER(dbenv, ip);
00054 
00055         /* Check for replication block. */
00056         handle_check = IS_ENV_REPLICATED(dbenv);
00057         if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0)
00058                 goto err;
00059 
00060         ret = __env_fileid_reset(dbenv, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0);
00061 
00062         if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00063                 ret = t_ret;
00064 
00065 err:    ENV_LEAVE(dbenv, ip);
00066         return (ret);
00067 }
00068 
00069 /*
00070  * __env_fileid_reset --
00071  *      Reset the file IDs for every database in the file.
00072  */
00073 static int
00074 __env_fileid_reset(dbenv, name, encrypted)
00075         DB_ENV *dbenv;
00076         const char *name;
00077         int encrypted;
00078 {
00079         DB *dbp;
00080         DBC *dbcp;
00081         DBT key, data;
00082         DB_MPOOLFILE *mpf;
00083         db_pgno_t pgno;
00084         int t_ret, ret;
00085         void *pagep;
00086         char *real_name;
00087         u_int8_t fileid[DB_FILE_ID_LEN];
00088 
00089         dbp = NULL;
00090         dbcp = NULL;
00091         real_name = NULL;
00092 
00093         /* Get the real backing file name. */
00094         if ((ret =
00095             __db_appname(dbenv, DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
00096                 return (ret);
00097 
00098         /* Get a new file ID. */
00099         if ((ret = __os_fileid(dbenv, real_name, 1, fileid)) != 0)
00100                 goto err;
00101 
00102         /* Create the DB object. */
00103         if ((ret = db_create(&dbp, dbenv, 0)) != 0)
00104                 goto err;
00105 
00106         /* If configured with a password, the databases are encrypted. */
00107         if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
00108                 goto err;
00109 
00110         /*
00111          * Open the DB file.
00112          *
00113          * !!!
00114          * Note DB_RDWRMASTER flag, we need to open the master database file
00115          * for writing in this case.
00116          */
00117         if ((ret = __db_open(dbp, NULL,
00118             name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0)
00119                 goto err;
00120 
00121         mpf = dbp->mpf;
00122 
00123         pgno = PGNO_BASE_MD;
00124         if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
00125                 goto err;
00126         memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN);
00127         if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
00128                 goto err;
00129 
00130         /*
00131          * If the database file doesn't support subdatabases, we only have
00132          * to update a single metadata page.  Otherwise, we have to open a
00133          * cursor and step through the master database, and update all of
00134          * the subdatabases' metadata pages.
00135          */
00136         if (!F_ISSET(dbp, DB_AM_SUBDB))
00137                 goto err;
00138 
00139         memset(&key, 0, sizeof(key));
00140         memset(&data, 0, sizeof(data));
00141         if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0)
00142                 goto err;
00143         while ((ret = __db_c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
00144                 /*
00145                  * XXX
00146                  * We're handling actual data, not on-page meta-data, so it
00147                  * hasn't been converted to/from opposite endian architectures.
00148                  * Do it explicitly, now.
00149                  */
00150                 memcpy(&pgno, data.data, sizeof(db_pgno_t));
00151                 DB_NTOHL(&pgno);
00152                 if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
00153                         goto err;
00154                 memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN);
00155                 if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
00156                         goto err;
00157         }
00158         if (ret == DB_NOTFOUND)
00159                 ret = 0;
00160 
00161 err:    if (dbcp != NULL && (t_ret = __db_c_close(dbcp)) != 0 && ret == 0)
00162                 ret = t_ret;
00163         if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
00164                 ret = t_ret;
00165         if (real_name != NULL)
00166                 __os_free(dbenv, real_name);
00167 
00168         return (ret);
00169 }

Generated on Sun Dec 25 12:14:21 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2