00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 #include <string.h>
00015 #endif
00016
00017 #include "db_int.h"
00018 #include "dbinc/db_page.h"
00019 #include "dbinc/db_shash.h"
00020 #include "dbinc/db_am.h"
00021 #include "dbinc/fop.h"
00022 #include "dbinc/lock.h"
00023 #include "dbinc/log.h"
00024 #include "dbinc/mp.h"
00025
00026 static int __db_subdb_rename __P((DB *,
00027 DB_TXN *, const char *, const char *, const char *));
00028
00029
00030
00031
00032
00033
00034
00035
00036 int
00037 __env_dbrename_pp(dbenv, txn, name, subdb, newname, flags)
00038 DB_ENV *dbenv;
00039 DB_TXN *txn;
00040 const char *name, *subdb, *newname;
00041 u_int32_t flags;
00042 {
00043 DB *dbp;
00044 DB_THREAD_INFO *ip;
00045 int handle_check, ret, t_ret, txn_local;
00046
00047 dbp = NULL;
00048 txn_local = 0;
00049
00050 PANIC_CHECK(dbenv);
00051 ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->dbrename");
00052
00053
00054
00055
00056
00057 if ((ret = __db_fchk(dbenv, "DB->rename", flags, DB_AUTO_COMMIT)) != 0)
00058 return (ret);
00059
00060 ENV_ENTER(dbenv, ip);
00061
00062
00063 handle_check = IS_ENV_REPLICATED(dbenv);
00064 if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) {
00065 handle_check = 0;
00066 goto err;
00067 }
00068
00069
00070
00071
00072
00073 if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) {
00074 if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0)
00075 goto err;
00076 txn_local = 1;
00077 } else
00078 if (txn != NULL && !TXN_ON(dbenv)) {
00079 ret = __db_not_txn_env(dbenv);
00080 goto err;
00081 }
00082
00083 LF_CLR(DB_AUTO_COMMIT);
00084
00085 if ((ret = db_create(&dbp, dbenv, 0)) != 0)
00086 goto err;
00087
00088 ret = __db_rename_int(dbp, txn, name, subdb, newname);
00089
00090 if (txn_local) {
00091
00092
00093
00094
00095
00096 LOCK_INIT(dbp->handle_lock);
00097 dbp->lid = DB_LOCK_INVALIDID;
00098 } else if (txn != NULL) {
00099
00100
00101
00102
00103
00104
00105
00106 dbp->lid = DB_LOCK_INVALIDID;
00107 }
00108
00109 err: if (txn_local && (t_ret =
00110 __db_txn_auto_resolve(dbenv, txn, 0, ret)) != 0 && ret == 0)
00111 ret = t_ret;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 if (dbp != NULL &&
00123 (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
00124 ret = t_ret;
00125
00126 if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00127 ret = t_ret;
00128
00129 ENV_LEAVE(dbenv, ip);
00130 return (ret);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 int
00141 __db_rename_pp(dbp, name, subdb, newname, flags)
00142 DB *dbp;
00143 const char *name, *subdb, *newname;
00144 u_int32_t flags;
00145 {
00146 DB_ENV *dbenv;
00147 DB_THREAD_INFO *ip;
00148 int handle_check, ret, t_ret;
00149
00150 dbenv = dbp->dbenv;
00151 handle_check = 0;
00152
00153 PANIC_CHECK(dbenv);
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
00166 return (__db_mi_open(dbenv, "DB->rename", 1));
00167
00168
00169 if ((ret = __db_fchk(dbenv, "DB->rename", flags, 0)) != 0)
00170 return (ret);
00171
00172
00173 if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0)
00174 return (ret);
00175
00176 ENV_ENTER(dbenv, ip);
00177
00178 handle_check = IS_ENV_REPLICATED(dbenv);
00179 if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) {
00180 handle_check = 0;
00181 goto err;
00182 }
00183
00184
00185 ret = __db_rename(dbp, NULL, name, subdb, newname);
00186
00187 if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
00188 ret = t_ret;
00189 err: ENV_LEAVE(dbenv, ip);
00190 return (ret);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 int
00201 __db_rename(dbp, txn, name, subdb, newname)
00202 DB *dbp;
00203 DB_TXN *txn;
00204 const char *name, *subdb, *newname;
00205 {
00206 int ret, t_ret;
00207
00208 ret = __db_rename_int(dbp, txn, name, subdb, newname);
00209
00210 if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
00211 ret = t_ret;
00212
00213 return (ret);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int
00225 __db_rename_int(dbp, txn, name, subdb, newname)
00226 DB *dbp;
00227 DB_TXN *txn;
00228 const char *name, *subdb, *newname;
00229 {
00230 DB_ENV *dbenv;
00231 int ret;
00232 char *old, *real_name;
00233
00234 dbenv = dbp->dbenv;
00235 real_name = NULL;
00236
00237 DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name);
00238
00239 if (name == NULL && subdb == NULL) {
00240 __db_err(dbenv, "Rename on temporary files invalid");
00241 ret = EINVAL;
00242 goto err;
00243 }
00244
00245 if (name == NULL)
00246 MAKE_INMEM(dbp);
00247 else if (subdb != NULL) {
00248 ret = __db_subdb_rename(dbp, txn, name, subdb, newname);
00249 goto err;
00250 }
00251
00252
00253
00254
00255
00256
00257 if (F_ISSET(dbp, DB_AM_INMEM)) {
00258 old = (char *)subdb;
00259 real_name = (char *)subdb;
00260 } else {
00261 if ((ret = __db_appname(dbenv,
00262 DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
00263 goto err;
00264 old = (char *)name;
00265 }
00266
00267 if ((ret = __fop_remove_setup(dbp, txn, real_name, 0)) != 0)
00268 goto err;
00269
00270 if (dbp->db_am_rename != NULL &&
00271 (ret = dbp->db_am_rename(dbp, txn, name, subdb, newname)) != 0)
00272 goto err;
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 if (txn != NULL) {
00283 if ((ret = __fop_dummy(dbp, txn, old, newname, 0)) != 0)
00284 goto err;
00285 } else {
00286 if ((ret = __fop_dbrename(dbp, old, newname)) != 0)
00287 goto err;
00288 }
00289
00290
00291
00292
00293
00294 DB_ASSERT(dbp->log_filename == NULL ||
00295 dbp->log_filename->id == DB_LOGFILEID_INVALID);
00296
00297 DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, newname);
00298
00299 DB_TEST_RECOVERY_LABEL
00300 err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL)
00301 __os_free(dbenv, real_name);
00302
00303 return (ret);
00304 }
00305
00306
00307
00308
00309
00310 static int
00311 __db_subdb_rename(dbp, txn, name, subdb, newname)
00312 DB *dbp;
00313 DB_TXN *txn;
00314 const char *name, *subdb, *newname;
00315 {
00316 DB *mdbp;
00317 DB_ENV *dbenv;
00318 PAGE *meta;
00319 int ret, t_ret;
00320
00321 mdbp = NULL;
00322 meta = NULL;
00323 dbenv = dbp->dbenv;
00324
00325
00326
00327
00328
00329 F_SET(dbp, DB_AM_SUBDB);
00330
00331
00332
00333
00334
00335
00336
00337 if ((ret = __db_master_open(dbp, txn, name, 0, 0, &mdbp)) != 0)
00338 goto err;
00339
00340 if ((ret = __db_master_update(mdbp, dbp, txn, subdb, dbp->type,
00341 MU_OPEN, NULL, 0)) != 0)
00342 goto err;
00343
00344 if ((ret = __memp_fget(mdbp->mpf, &dbp->meta_pgno, 0, &meta)) != 0)
00345 goto err;
00346 memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN);
00347 if ((ret = __fop_lock_handle(dbenv,
00348 dbp, mdbp->lid, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0)
00349 goto err;
00350
00351 ret = __memp_fput(mdbp->mpf, meta, 0);
00352 meta = NULL;
00353 if (ret != 0)
00354 goto err;
00355
00356 if ((ret = __db_master_update(mdbp, dbp, txn,
00357 subdb, dbp->type, MU_RENAME, newname, 0)) != 0)
00358 goto err;
00359
00360 DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name);
00361
00362 DB_TEST_RECOVERY_LABEL
00363 err:
00364 if (meta != NULL &&
00365 (t_ret = __memp_fput(mdbp->mpf, meta, 0)) != 0 && ret == 0)
00366 ret = t_ret;
00367
00368 if (mdbp != NULL &&
00369 (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0)
00370 ret = t_ret;
00371
00372 return (ret);
00373 }