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
00015 #ifdef HAVE_VXWORKS
00016 #include <rpcLib.h>
00017 #endif
00018 #include <rpc/rpc.h>
00019
00020 #include <ctype.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #endif
00024
00025 #include "db_server.h"
00026
00027 #include "db_int.h"
00028 #include "dbinc/db_page.h"
00029 #include "dbinc/db_am.h"
00030 #include "dbinc/txn.h"
00031 #include "dbinc_auto/rpc_client_ext.h"
00032
00033 static int __dbcl_c_destroy __P((DBC *));
00034 static int __dbcl_txn_close __P((DB_ENV *));
00035
00036
00037
00038
00039
00040
00041
00042
00043 int
00044 __dbcl_env_set_rpc_server(dbenv, clnt, host, tsec, ssec, flags)
00045 DB_ENV *dbenv;
00046 void *clnt;
00047 const char *host;
00048 long tsec, ssec;
00049 u_int32_t flags;
00050 {
00051 CLIENT *cl;
00052 struct timeval tp;
00053
00054 COMPQUIET(flags, 0);
00055
00056 #ifdef HAVE_VXWORKS
00057 if (rpcTaskInit() != 0) {
00058 __db_err(dbenv, "Could not initialize VxWorks RPC");
00059 return (ERROR);
00060 }
00061 #endif
00062 if (RPC_ON(dbenv)) {
00063 __db_err(dbenv, "Already set an RPC handle");
00064 return (EINVAL);
00065 }
00066
00067
00068
00069
00070 if (clnt == NULL) {
00071 if ((cl = clnt_create((char *)host, DB_RPC_SERVERPROG,
00072 DB_RPC_SERVERVERS, "tcp")) == NULL) {
00073 __db_err(dbenv, clnt_spcreateerror((char *)host));
00074 return (DB_NOSERVER);
00075 }
00076 if (tsec != 0) {
00077 tp.tv_sec = tsec;
00078 tp.tv_usec = 0;
00079 (void)clnt_control(cl, CLSET_TIMEOUT, (char *)&tp);
00080 }
00081 } else {
00082 cl = (CLIENT *)clnt;
00083 F_SET(dbenv, DB_ENV_RPCCLIENT_GIVEN);
00084 }
00085 dbenv->cl_handle = cl;
00086
00087 return (__dbcl_env_create(dbenv, ssec));
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 int
00100 __dbcl_env_close_wrap(dbenv, flags)
00101 DB_ENV * dbenv;
00102 u_int32_t flags;
00103 {
00104 int ret, t_ret;
00105
00106 ret = __dbcl_env_close(dbenv, flags);
00107 t_ret = __dbcl_refresh(dbenv);
00108 if (ret == 0 && t_ret != 0)
00109 ret = t_ret;
00110 return (ret);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int
00123 __dbcl_env_open_wrap(dbenv, home, flags, mode)
00124 DB_ENV * dbenv;
00125 const char * home;
00126 u_int32_t flags;
00127 int mode;
00128 {
00129 int ret;
00130
00131 if (LF_ISSET(DB_THREAD)) {
00132 __db_err(dbenv, "DB_THREAD not allowed on RPC clients");
00133 return (EINVAL);
00134 }
00135 if ((ret = __db_home(dbenv, home, flags)) != 0)
00136 return (ret);
00137 return (__dbcl_env_open(dbenv, dbenv->db_home, flags, mode));
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 int
00151 __dbcl_db_open_wrap(dbp, txnp, name, subdb, type, flags, mode)
00152 DB * dbp;
00153 DB_TXN * txnp;
00154 const char * name;
00155 const char * subdb;
00156 DBTYPE type;
00157 u_int32_t flags;
00158 int mode;
00159 {
00160 return (__dbcl_db_open(dbp, txnp, name, subdb, type, flags, mode));
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 int
00170 __dbcl_refresh(dbenv)
00171 DB_ENV *dbenv;
00172 {
00173 CLIENT *cl;
00174 int ret;
00175
00176 cl = (CLIENT *)dbenv->cl_handle;
00177
00178 ret = 0;
00179 if (dbenv->tx_handle != NULL) {
00180
00181
00182
00183
00184
00185 ret = __dbcl_txn_close(dbenv);
00186 dbenv->tx_handle = NULL;
00187 }
00188 if (!F_ISSET(dbenv, DB_ENV_RPCCLIENT_GIVEN) && cl != NULL)
00189 clnt_destroy(cl);
00190 dbenv->cl_handle = NULL;
00191 if (dbenv->db_home != NULL) {
00192 __os_free(dbenv, dbenv->db_home);
00193 dbenv->db_home = NULL;
00194 }
00195 return (ret);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 int
00207 __dbcl_retcopy(dbenv, dbt, data, len, memp, memsize)
00208 DB_ENV *dbenv;
00209 DBT *dbt;
00210 void *data;
00211 u_int32_t len;
00212 void **memp;
00213 u_int32_t *memsize;
00214 {
00215 int ret;
00216 u_int32_t orig_flags;
00217
00218
00219
00220
00221
00222
00223
00224 orig_flags = dbt->flags;
00225 F_CLR(dbt, DB_DBT_PARTIAL);
00226 if (dbt->data != NULL && dbt->size == len &&
00227 memcmp(dbt->data, data, len) == 0)
00228 ret = 0;
00229 else
00230 ret = __db_retcopy(dbenv, dbt, data, len, memp, memsize);
00231 dbt->flags = orig_flags;
00232 return (ret);
00233 }
00234
00235
00236
00237
00238
00239 static int
00240 __dbcl_txn_close(dbenv)
00241 DB_ENV *dbenv;
00242 {
00243 DB_TXN *txnp;
00244 DB_TXNMGR *tmgrp;
00245 int ret;
00246
00247 ret = 0;
00248 tmgrp = dbenv->tx_handle;
00249
00250
00251
00252
00253
00254
00255
00256
00257 while ((txnp = TAILQ_FIRST(&tmgrp->txn_chain)) != NULL)
00258 __dbcl_txn_end(txnp);
00259
00260 __os_free(dbenv, tmgrp);
00261 return (ret);
00262
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 void
00273 __dbcl_txn_end(txnp)
00274 DB_TXN *txnp;
00275 {
00276 DB_ENV *dbenv;
00277 DB_TXN *kids;
00278 DB_TXNMGR *mgr;
00279
00280 mgr = txnp->mgrp;
00281 dbenv = mgr->dbenv;
00282
00283
00284
00285
00286 for (kids = TAILQ_FIRST(&txnp->kids);
00287 kids != NULL;
00288 kids = TAILQ_FIRST(&txnp->kids))
00289 __dbcl_txn_end(kids);
00290
00291
00292
00293
00294
00295
00296
00297 if (txnp->parent != NULL)
00298 TAILQ_REMOVE(&txnp->parent->kids, txnp, klinks);
00299 TAILQ_REMOVE(&mgr->txn_chain, txnp, links);
00300 __os_free(dbenv, txnp);
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 void
00310 __dbcl_txn_setup(dbenv, txn, parent, id)
00311 DB_ENV *dbenv;
00312 DB_TXN *txn;
00313 DB_TXN *parent;
00314 u_int32_t id;
00315 {
00316 txn->mgrp = dbenv->tx_handle;
00317 txn->parent = parent;
00318 txn->txnid = id;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 TAILQ_INSERT_TAIL(&txn->mgrp->txn_chain, txn, links);
00330
00331 TAILQ_INIT(&txn->kids);
00332
00333 if (parent != NULL)
00334 TAILQ_INSERT_HEAD(&parent->kids, txn, klinks);
00335
00336 __dbcl_txn_init(txn);
00337
00338 txn->flags = TXN_MALLOC;
00339 }
00340
00341
00342
00343
00344
00345 static int
00346 __dbcl_c_destroy(dbc)
00347 DBC *dbc;
00348 {
00349 DB *dbp;
00350
00351 dbp = dbc->dbp;
00352
00353 TAILQ_REMOVE(&dbp->free_queue, dbc, links);
00354
00355 if (dbc->my_rskey.data != NULL)
00356 __os_free(dbc->dbp->dbenv, dbc->my_rskey.data);
00357 if (dbc->my_rkey.data != NULL)
00358 __os_free(dbc->dbp->dbenv, dbc->my_rkey.data);
00359 if (dbc->my_rdata.data != NULL)
00360 __os_free(dbc->dbp->dbenv, dbc->my_rdata.data);
00361 __os_free(NULL, dbc);
00362
00363 return (0);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372 void
00373 __dbcl_c_refresh(dbc)
00374 DBC *dbc;
00375 {
00376 DB *dbp;
00377
00378 dbp = dbc->dbp;
00379 dbc->flags = 0;
00380 dbc->cl_id = 0;
00381
00382
00383
00384
00385
00386 if (dbp != NULL) {
00387 TAILQ_REMOVE(&dbp->active_queue, dbc, links);
00388 TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links);
00389 }
00390 }
00391
00392
00393
00394
00395
00396
00397
00398 int
00399 __dbcl_c_setup(cl_id, dbp, dbcp)
00400 u_int cl_id;
00401 DB *dbp;
00402 DBC **dbcp;
00403 {
00404 DBC *dbc, tmpdbc;
00405 int ret;
00406
00407 if ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
00408 TAILQ_REMOVE(&dbp->free_queue, dbc, links);
00409 else {
00410 if ((ret =
00411 __os_calloc(dbp->dbenv, 1, sizeof(DBC), &dbc)) != 0) {
00412
00413
00414
00415
00416 tmpdbc.dbp = NULL;
00417 tmpdbc.cl_id = cl_id;
00418 (void)__dbcl_dbc_c_close(&tmpdbc);
00419 return (ret);
00420 }
00421
00422 __dbcl_dbc_init(dbc);
00423
00424
00425
00426
00427
00428
00429 dbc->c_am_destroy = __dbcl_c_destroy;
00430 }
00431 dbc->cl_id = cl_id;
00432 dbc->dbp = dbp;
00433 TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
00434 *dbcp = dbc;
00435 return (0);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 int
00445 __dbcl_dbclose_common(dbp)
00446 DB *dbp;
00447 {
00448 int ret, t_ret;
00449 DBC *dbc;
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 ret = 0;
00461 while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
00462 __dbcl_c_refresh(dbc);
00463 while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
00464 if ((t_ret = __dbcl_c_destroy(dbc)) != 0 && ret == 0)
00465 ret = t_ret;
00466
00467 TAILQ_INIT(&dbp->free_queue);
00468 TAILQ_INIT(&dbp->active_queue);
00469
00470 if (dbp->my_rskey.data != NULL)
00471 __os_free(dbp->dbenv, dbp->my_rskey.data);
00472 if (dbp->my_rkey.data != NULL)
00473 __os_free(dbp->dbenv, dbp->my_rkey.data);
00474 if (dbp->my_rdata.data != NULL)
00475 __os_free(dbp->dbenv, dbp->my_rdata.data);
00476
00477 memset(dbp, CLEAR_BYTE, sizeof(*dbp));
00478 __os_free(NULL, dbp);
00479 return (ret);
00480 }