summaryrefslogtreecommitdiff
path: root/lang/tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lang/tcl')
-rw-r--r--lang/tcl/docs/db.html2
-rw-r--r--lang/tcl/docs/env.html2
-rw-r--r--lang/tcl/docs/historic.html2
-rw-r--r--lang/tcl/docs/index.html2
-rw-r--r--lang/tcl/docs/library.html2
-rw-r--r--lang/tcl/docs/lock.html2
-rw-r--r--lang/tcl/docs/log.html2
-rw-r--r--lang/tcl/docs/mpool.html2
-rw-r--r--lang/tcl/docs/rep.html2
-rw-r--r--lang/tcl/docs/sequence.html2
-rw-r--r--lang/tcl/docs/test.html2
-rw-r--r--lang/tcl/docs/txn.html2
-rw-r--r--lang/tcl/tcl_compat.c2
-rw-r--r--lang/tcl/tcl_db.c407
-rw-r--r--lang/tcl/tcl_db_pkg.c560
-rw-r--r--lang/tcl/tcl_dbcursor.c108
-rw-r--r--lang/tcl/tcl_dbstream.c302
-rw-r--r--lang/tcl/tcl_env.c578
-rw-r--r--lang/tcl/tcl_internal.c9
-rw-r--r--lang/tcl/tcl_lock.c38
-rw-r--r--lang/tcl/tcl_log.c125
-rw-r--r--lang/tcl/tcl_mp.c199
-rw-r--r--lang/tcl/tcl_mutex.c41
-rw-r--r--lang/tcl/tcl_rep.c106
-rw-r--r--lang/tcl/tcl_seq.c27
-rw-r--r--lang/tcl/tcl_txn.c36
-rw-r--r--lang/tcl/tcl_util.c2
27 files changed, 2200 insertions, 364 deletions
diff --git a/lang/tcl/docs/db.html b/lang/tcl/docs/db.html
index 6c5bcecf..77b4cc3a 100644
--- a/lang/tcl/docs/db.html
+++ b/lang/tcl/docs/db.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/env.html b/lang/tcl/docs/env.html
index f790cab0..506a4b39 100644
--- a/lang/tcl/docs/env.html
+++ b/lang/tcl/docs/env.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/historic.html b/lang/tcl/docs/historic.html
index 9345208e..6d8e8e03 100644
--- a/lang/tcl/docs/historic.html
+++ b/lang/tcl/docs/historic.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/index.html b/lang/tcl/docs/index.html
index ad08b3ae..6faf388d 100644
--- a/lang/tcl/docs/index.html
+++ b/lang/tcl/docs/index.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/library.html b/lang/tcl/docs/library.html
index fab4ff2f..72f54f24 100644
--- a/lang/tcl/docs/library.html
+++ b/lang/tcl/docs/library.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/lock.html b/lang/tcl/docs/lock.html
index d9b7599c..ba3f5f5d 100644
--- a/lang/tcl/docs/lock.html
+++ b/lang/tcl/docs/lock.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/log.html b/lang/tcl/docs/log.html
index 7df38f80..8451404b 100644
--- a/lang/tcl/docs/log.html
+++ b/lang/tcl/docs/log.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/mpool.html b/lang/tcl/docs/mpool.html
index 42d38e27..2ddb692f 100644
--- a/lang/tcl/docs/mpool.html
+++ b/lang/tcl/docs/mpool.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/rep.html b/lang/tcl/docs/rep.html
index 60c074e1..1a8ee5ca 100644
--- a/lang/tcl/docs/rep.html
+++ b/lang/tcl/docs/rep.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/sequence.html b/lang/tcl/docs/sequence.html
index 8d608d31..3ea7cf2c 100644
--- a/lang/tcl/docs/sequence.html
+++ b/lang/tcl/docs/sequence.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
diff --git a/lang/tcl/docs/test.html b/lang/tcl/docs/test.html
index ff591b7b..3eb7311a 100644
--- a/lang/tcl/docs/test.html
+++ b/lang/tcl/docs/test.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/docs/txn.html b/lang/tcl/docs/txn.html
index 061a221a..9c7f2020 100644
--- a/lang/tcl/docs/txn.html
+++ b/lang/tcl/docs/txn.html
@@ -1,4 +1,4 @@
-<!--Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.-->
+<!--Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
diff --git a/lang/tcl/tcl_compat.c b/lang/tcl/tcl_compat.c
index 57c0b9bc..97900eef 100644
--- a/lang/tcl/tcl_compat.c
+++ b/lang/tcl/tcl_compat.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/lang/tcl/tcl_db.c b/lang/tcl/tcl_db.c
index afe431b8..7c0e1b65 100644
--- a/lang/tcl/tcl_db.c
+++ b/lang/tcl/tcl_db.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -100,11 +100,11 @@ db_Cmd(clientData, interp, objc, objv)
{
static const char *dbcmds[] = {
#ifdef CONFIG_TEST
+ "compact",
+ "compact_stat",
"keyrange",
"pget",
"test",
- "compact",
- "compact_stat",
#endif
"associate",
"associate_foreign",
@@ -113,7 +113,11 @@ db_Cmd(clientData, interp, objc, objv)
"cursor",
"del",
"get",
+ "get_blob_dir",
+ "get_blob_sub_dir",
+ "get_blob_threshold",
"get_bt_minkey",
+ "get_byteswapped",
"get_cachesize",
"get_dbname",
"get_encrypt_flags",
@@ -121,9 +125,11 @@ db_Cmd(clientData, interp, objc, objv)
"get_errpfx",
"get_flags",
"get_heap_regionsize",
+ "get_heapsize",
"get_h_ffactor",
"get_h_nelem",
"get_join",
+ "get_lk_exclusive",
"get_lorder",
"get_open_flags",
"get_pagesize",
@@ -133,9 +139,9 @@ db_Cmd(clientData, interp, objc, objv)
"get_re_pad",
"get_re_source",
"get_type",
- "is_byteswapped",
"join",
- "get_lk_exclusive",
+ "msgfile",
+ "msgfile_close",
"put",
"stat",
"stat_print",
@@ -145,11 +151,11 @@ db_Cmd(clientData, interp, objc, objv)
};
enum dbcmds {
#ifdef CONFIG_TEST
+ DBCOMPACT,
+ DBCOMPACT_STAT,
DBKEYRANGE,
DBPGET,
DBTEST,
- DBCOMPACT,
- DBCOMPACT_STAT,
#endif
DBASSOCIATE,
DBASSOCFOREIGN,
@@ -158,7 +164,11 @@ db_Cmd(clientData, interp, objc, objv)
DBCURSOR,
DBDELETE,
DBGET,
+ DBGETBLOBDIR,
+ DBGETBLOBSUBDIR,
+ DBGETBLOBTHRESHOLD,
DBGETBTMINKEY,
+ DBGETBYTESWAPPED,
DBGETCACHESIZE,
DBGETDBNAME,
DBGETENCRYPTFLAGS,
@@ -166,9 +176,11 @@ db_Cmd(clientData, interp, objc, objv)
DBGETERRPFX,
DBGETFLAGS,
DBGETHEAPREGIONSIZE,
+ DBGETHEAPSIZE,
DBGETHFFACTOR,
DBGETHNELEM,
DBGETJOIN,
+ DBGETLKEXCLUSIVE,
DBGETLORDER,
DBGETOPENFLAGS,
DBGETPAGESIZE,
@@ -178,9 +190,9 @@ db_Cmd(clientData, interp, objc, objv)
DBGETREPAD,
DBGETRESOURCE,
DBGETTYPE,
- DBSWAPPED,
DBJOIN,
- DBGETLKEXCLUSIVE,
+ DBMSGFILE,
+ DBMSGFILECLOSE,
DBPUT,
DBSTAT,
DBSTATPRINT,
@@ -195,8 +207,10 @@ db_Cmd(clientData, interp, objc, objv)
Tcl_Obj *res, *myobjv[3];
int cmdindex, intval, ncache, result, ret, onoff, nowait;
char newname[MSG_SIZE];
+ char *strarg;
u_int32_t bytes, gbytes, value;
const char *strval, *filename, *dbname, *envid;
+ FILE *file;
Tcl_ResetResult(interp);
dbp = (DB *)clientData;
@@ -227,6 +241,14 @@ db_Cmd(clientData, interp, objc, objv)
res = NULL;
switch ((enum dbcmds)cmdindex) {
#ifdef CONFIG_TEST
+ case DBCOMPACT:
+ result = tcl_DbCompact(interp, objc, objv, dbp);
+ break;
+
+ case DBCOMPACT_STAT:
+ result = tcl_DbCompactStat(interp, objc, objv, dbp);
+ break;
+
case DBKEYRANGE:
result = tcl_DbKeyRange(interp, objc, objv, dbp);
break;
@@ -237,14 +259,6 @@ db_Cmd(clientData, interp, objc, objv)
result = tcl_EnvTest(interp, objc, objv, dbp->dbenv);
break;
- case DBCOMPACT:
- result = tcl_DbCompact(interp, objc, objv, dbp);
- break;
-
- case DBCOMPACT_STAT:
- result = tcl_DbCompactStat(interp, objc, objv, dbp);
- break;
-
#endif
case DBASSOCIATE:
result = tcl_DbAssociate(interp, objc, objv, dbp);
@@ -255,100 +269,9 @@ db_Cmd(clientData, interp, objc, objv)
case DBCLOSE:
result = tcl_DbClose(interp, objc, objv, dbp, dbip);
break;
- case DBDELETE:
- result = tcl_DbDelete(interp, objc, objv, dbp);
- break;
- case DBGET:
- result = tcl_DbGet(interp, objc, objv, dbp, 0);
- break;
- case DBPUT:
- result = tcl_DbPut(interp, objc, objv, dbp);
- break;
case DBCOUNT:
result = tcl_DbCount(interp, objc, objv, dbp);
break;
- case DBSWAPPED:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->get_byteswapped(dbp, &intval);
- res = Tcl_NewIntObj(intval);
- break;
- case DBGETTYPE:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->get_type(dbp, &type);
- if (type == DB_BTREE)
- res = NewStringObj("btree", strlen("btree"));
- else if (type == DB_HASH)
- res = NewStringObj("hash", strlen("hash"));
- else if (type == DB_RECNO)
- res = NewStringObj("recno", strlen("recno"));
- else if (type == DB_QUEUE)
- res = NewStringObj("queue", strlen("queue"));
- else if (type == DB_HEAP)
- res = NewStringObj("heap", strlen("heap"));
- else {
- Tcl_SetResult(interp,
- "db gettype: Returned unknown type\n", TCL_STATIC);
- result = TCL_ERROR;
- }
- break;
- case DBSTAT:
- result = tcl_DbStat(interp, objc, objv, dbp);
- break;
- case DBSTATPRINT:
- result = tcl_DbStatPrint(interp, objc, objv, dbp);
- break;
- case DBSYNC:
- /*
- * No args for this. Error if there are some.
- */
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- ret = dbp->sync(dbp, 0);
- res = Tcl_NewIntObj(ret);
- if (ret != 0) {
- Tcl_SetObjResult(interp, res);
- result = TCL_ERROR;
- }
-
- /* If we are heap, we have more work to do. */
- ret = dbp->get_type(dbp, &type);
- if (type == DB_HEAP) {
- hrdbp = dbip->hrdbp;
- hsdbp = dbip->hsdbp;
-
- /* sync the associated dbs also */
- ret = dbp->sync(hrdbp, 0);
- res = Tcl_NewIntObj(ret);
- if (ret != 0) {
- Tcl_SetObjResult(interp, res);
- result = TCL_ERROR;
- }
-
- ret = dbp->sync(hsdbp, 0);
- res = Tcl_NewIntObj(ret);
- if (ret != 0) {
- Tcl_SetObjResult(interp, res);
- result = TCL_ERROR;
- }
- }
- break;
case DBCURSOR:
snprintf(newname, sizeof(newname),
"%s.c%d", dbip->i_name, dbip->i_dbdbcid);
@@ -371,27 +294,43 @@ db_Cmd(clientData, interp, objc, objv)
result = TCL_ERROR;
}
break;
- case DBJOIN:
- snprintf(newname, sizeof(newname),
- "%s.c%d", dbip->i_name, dbip->i_dbdbcid);
- ip = _NewInfo(interp, NULL, newname, I_DBC);
- if (ip != NULL) {
- result = tcl_DbJoin(interp, objc, objv, dbp, &dbc);
- if (result == TCL_OK) {
- dbip->i_dbdbcid++;
- ip->i_parent = dbip;
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)dbc_Cmd,
- (ClientData)dbc, NULL);
- res = NewStringObj(newname, strlen(newname));
- _SetInfoData(ip, dbc);
- } else
- _DeleteInfo(ip);
- } else {
- Tcl_SetResult(interp,
- "Could not set up info", TCL_STATIC);
- result = TCL_ERROR;
+ case DBDELETE:
+ result = tcl_DbDelete(interp, objc, objv, dbp);
+ break;
+ case DBGET:
+ result = tcl_DbGet(interp, objc, objv, dbp, 0);
+ break;
+ case DBGETBLOBDIR:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
}
+ ret = dbp->get_blob_dir(dbp, &strval);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db get_blob_dir")) == TCL_OK)
+ res = NewStringObj(strval,
+ strval != NULL ? strlen(strval) : 0);
+ break;
+ case DBGETBLOBSUBDIR:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbp->get_blob_sub_dir(dbp, &strval);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db get_blob_sub_dir")) == TCL_OK)
+ res = NewStringObj(strval,
+ strval != NULL ? strlen(strval) : 0);
+ break;
+ case DBGETBLOBTHRESHOLD:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbp->get_blob_threshold(dbp, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db get_blob_threshold")) == TCL_OK)
+ res = Tcl_NewIntObj((int)value);
break;
case DBGETBTMINKEY:
if (objc != 2) {
@@ -403,6 +342,18 @@ db_Cmd(clientData, interp, objc, objv)
"db get_bt_minkey")) == TCL_OK)
res = Tcl_NewIntObj((int)value);
break;
+ case DBGETBYTESWAPPED:
+ /*
+ * No args for this. Error if there are some.
+ */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = dbp->get_byteswapped(dbp, &intval);
+ res = Tcl_NewIntObj(intval);
+ break;
case DBGETCACHESIZE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -468,6 +419,19 @@ db_Cmd(clientData, interp, objc, objv)
"db get_heap_regionsize")) == TCL_OK)
res = Tcl_NewIntObj((int)value);
break;
+ case DBGETHEAPSIZE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbp->get_heapsize(dbp, &gbytes, &bytes);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db get_heapsize")) == TCL_OK) {
+ myobjv[0] = Tcl_NewIntObj((int)gbytes);
+ myobjv[1] = Tcl_NewIntObj((int)bytes);
+ res = Tcl_NewListObj(2, myobjv);
+ }
+ break;
case DBGETHFFACTOR:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -491,6 +455,19 @@ db_Cmd(clientData, interp, objc, objv)
case DBGETJOIN:
result = tcl_DbGetjoin(interp, objc, objv, dbp);
break;
+ case DBGETLKEXCLUSIVE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbp->get_lk_exclusive(dbp, &onoff, &nowait);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db get_lk_exclusive")) == TCL_OK) {
+ myobjv[0] = Tcl_NewIntObj((int)onoff);
+ myobjv[1] = Tcl_NewIntObj((int)nowait);
+ res = Tcl_NewListObj(2, myobjv);
+ }
+ break;
case DBGETLORDER:
/*
* No args for this. Error if there are some.
@@ -566,17 +543,157 @@ db_Cmd(clientData, interp, objc, objv)
"db get_re_source")) == TCL_OK)
res = NewStringObj(strval, strlen(strval));
break;
- case DBGETLKEXCLUSIVE:
- if (objc != 2) {
+ case DBGETTYPE:
+ /*
+ * No args for this. Error if there are some.
+ */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = dbp->get_type(dbp, &type);
+ if (type == DB_BTREE)
+ res = NewStringObj("btree", strlen("btree"));
+ else if (type == DB_HASH)
+ res = NewStringObj("hash", strlen("hash"));
+ else if (type == DB_RECNO)
+ res = NewStringObj("recno", strlen("recno"));
+ else if (type == DB_QUEUE)
+ res = NewStringObj("queue", strlen("queue"));
+ else if (type == DB_HEAP)
+ res = NewStringObj("heap", strlen("heap"));
+ else {
+ Tcl_SetResult(interp,
+ "db gettype: Returned unknown type\n", TCL_STATIC);
+ result = TCL_ERROR;
+ }
+ break;
+ case DBJOIN:
+ snprintf(newname, sizeof(newname),
+ "%s.c%d", dbip->i_name, dbip->i_dbdbcid);
+ ip = _NewInfo(interp, NULL, newname, I_DBC);
+ if (ip != NULL) {
+ result = tcl_DbJoin(interp, objc, objv, dbp, &dbc);
+ if (result == TCL_OK) {
+ dbip->i_dbdbcid++;
+ ip->i_parent = dbip;
+ (void)Tcl_CreateObjCommand(interp, newname,
+ (Tcl_ObjCmdProc *)dbc_Cmd,
+ (ClientData)dbc, NULL);
+ res = NewStringObj(newname, strlen(newname));
+ _SetInfoData(ip, dbc);
+ } else
+ _DeleteInfo(ip);
+ } else {
+ Tcl_SetResult(interp,
+ "Could not set up info", TCL_STATIC);
+ result = TCL_ERROR;
+ }
+ break;
+ case DBMSGFILE:
+ if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
- ret = dbp->get_lk_exclusive(dbp, &onoff, &nowait);
+ strarg = Tcl_GetStringFromObj(objv[2], NULL);
+ dbenv = dbp->get_env(dbp);
+ if (dbenv != NULL && _PtrToInfo(dbenv) != NULL) {
+ ip = _PtrToInfo(dbenv);
+ } else {
+ ip = dbip;
+ }
+ if (ip->i_msg != NULL && ip->i_msg != stdout &&
+ ip->i_msg != stderr)
+ (void)fclose(ip->i_msg);
+ if (strcmp(strarg, "NULL") == 0)
+ ip->i_msg = NULL;
+ else if (strcmp(strarg, "/dev/stdout") == 0)
+ ip->i_msg = stdout;
+ else if (strcmp(strarg, "/dev/stderr") == 0)
+ ip->i_msg = stderr;
+ else
+ ip->i_msg = fopen(strarg, "a");
+ if (strcmp(strarg, "NULL") == 0 || ip->i_msg != NULL ) {
+ dbp->set_msgfile(dbp, ip->i_msg);
+ ret = TCL_OK;
+ }
+ else
+ ret = TCL_ERROR;
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "db get_lk_exclusive")) == TCL_OK) {
- myobjv[0] = Tcl_NewIntObj((int)onoff);
- myobjv[1] = Tcl_NewIntObj((int)nowait);
- res = Tcl_NewListObj(2, myobjv);
+ "db set_msgfile")) == TCL_OK)
+ res = Tcl_NewIntObj(ret);
+ break;
+ case DBMSGFILECLOSE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = TCL_OK;
+ dbenv = dbp->get_env(dbp);
+ if (dbenv != NULL && _PtrToInfo(dbenv) != NULL) {
+ ip = _PtrToInfo(dbenv);
+ } else {
+ ip = dbip;
+ }
+ dbp->get_msgfile(dbp, &file);
+ if (file != ip->i_msg) {
+ return (TCL_ERROR);
+ }
+ if (file != NULL && file != stdout && file != stderr) {
+ ret = fclose(file);
+ }
+ ip->i_msg = NULL;
+ dbp->set_msgfile(dbp, NULL);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "db close msgfile")) == TCL_OK)
+ res = Tcl_NewIntObj(ret);
+ break;
+ case DBPUT:
+ result = tcl_DbPut(interp, objc, objv, dbp);
+ break;
+ case DBSTAT:
+ result = tcl_DbStat(interp, objc, objv, dbp);
+ break;
+ case DBSTATPRINT:
+ result = tcl_DbStatPrint(interp, objc, objv, dbp);
+ break;
+ case DBSYNC:
+ /*
+ * No args for this. Error if there are some.
+ */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = dbp->sync(dbp, 0);
+ res = Tcl_NewIntObj(ret);
+ if (ret != 0) {
+ Tcl_SetObjResult(interp, res);
+ result = TCL_ERROR;
+ }
+
+ /* If we are heap, we have more work to do. */
+ ret = dbp->get_type(dbp, &type);
+ if (type == DB_HEAP) {
+ hrdbp = dbip->hrdbp;
+ hsdbp = dbip->hsdbp;
+
+ /* sync the associated dbs also */
+ ret = dbp->sync(hrdbp, 0);
+ res = Tcl_NewIntObj(ret);
+ if (ret != 0) {
+ Tcl_SetObjResult(interp, res);
+ result = TCL_ERROR;
+ }
+
+ ret = dbp->sync(hsdbp, 0);
+ res = Tcl_NewIntObj(ret);
+ if (ret != 0) {
+ Tcl_SetObjResult(interp, res);
+ result = TCL_ERROR;
+ }
}
break;
case DBTRUNCATE:
@@ -703,6 +820,7 @@ tcl_DbStat(interp, objc, objv, dbp)
MAKE_STAT_LIST("Number of records", hsp->hash_ndata);
MAKE_STAT_LIST("Fill factor", hsp->hash_ffactor);
MAKE_STAT_LIST("Buckets", hsp->hash_buckets);
+ MAKE_STAT_LIST("Number of blobs", hsp->hash_nblobs);
if (flag != DB_FAST_STAT) {
MAKE_STAT_LIST("Free pages", hsp->hash_free);
MAKE_WSTAT_LIST("Bytes free", hsp->hash_bfree);
@@ -727,6 +845,7 @@ tcl_DbStat(interp, objc, objv, dbp)
MAKE_STAT_LIST("Number of regions", hpsp->heap_nregions);
MAKE_STAT_LIST("Number of pages in a region",
hpsp->heap_regionsize);
+ MAKE_STAT_LIST("Number of blobs", hpsp->heap_nblobs);
} else if (type == DB_QUEUE) {
qsp = (DB_QUEUE_STAT *)sp;
MAKE_STAT_LIST("Magic", qsp->qs_magic);
@@ -738,7 +857,7 @@ tcl_DbStat(interp, objc, objv, dbp)
MAKE_STAT_LIST("Record length", qsp->qs_re_len);
MAKE_STAT_LIST("Record pad", qsp->qs_re_pad);
MAKE_STAT_LIST("First record number", qsp->qs_first_recno);
- MAKE_STAT_LIST("Last record number", qsp->qs_cur_recno);
+ MAKE_STAT_LIST("Next available record number", qsp->qs_cur_recno);
if (flag != DB_FAST_STAT) {
MAKE_STAT_LIST("Number of pages", qsp->qs_pages);
MAKE_WSTAT_LIST("Bytes free", qsp->qs_pgfree);
@@ -749,6 +868,7 @@ tcl_DbStat(interp, objc, objv, dbp)
MAKE_STAT_LIST("Version", bsp->bt_version);
MAKE_STAT_LIST("Number of keys", bsp->bt_nkeys);
MAKE_STAT_LIST("Number of records", bsp->bt_ndata);
+ MAKE_STAT_LIST("Number of blobs", bsp->bt_nblobs);
MAKE_STAT_LIST("Minimum keys per page", bsp->bt_minkey);
MAKE_STAT_LIST("Fixed record length", bsp->bt_re_len);
MAKE_STAT_LIST("Record pad", bsp->bt_re_pad);
@@ -981,6 +1101,7 @@ tcl_DbPut(interp, objc, objv, dbp)
"-nodupdata",
#endif
"-append",
+ "-blob",
"-multiple",
"-multiple_key",
"-nooverwrite",
@@ -995,6 +1116,7 @@ tcl_DbPut(interp, objc, objv, dbp)
DBGET_NODUPDATA,
#endif
DBPUT_APPEND,
+ DBPUT_BLOB,
DBPUT_MULTIPLE,
DBPUT_MULTIPLE_KEY,
DBPUT_NOOVER,
@@ -1104,6 +1226,9 @@ tcl_DbPut(interp, objc, objv, dbp)
FLAG_CHECK(flag);
flag = DB_APPEND;
break;
+ case DBPUT_BLOB:
+ data.flags |= DB_DBT_BLOB;
+ break;
case DBPUT_MULTIPLE:
FLAG_CHECK(multiflag);
multiflag = DB_MULTIPLE;
@@ -2564,7 +2689,7 @@ tcl_DbDelete(interp, objc, objv, dbp)
result = _ReturnSetup(interp,
ret, DB_RETOK_DBPUT(ret),
"db del heap bulk");
- goto out;
+ goto loopend;
}
DB_MULTIPLE_WRITE_NEXT(ptr,
&key, hkey.data, hkey.size);
@@ -2682,7 +2807,7 @@ tcl_DbDelete(interp, objc, objv, dbp)
result = _ReturnSetup(interp,
ret, DB_RETOK_DBPUT(ret),
"db del heap bulk");
- goto out;
+ goto loopend;
}
DB_MULTIPLE_KEY_WRITE_NEXT(ptr,
&key, hkey.data, hkey.size,
@@ -3710,7 +3835,7 @@ tcl_DbGetFlags(interp, objc, objv, dbp)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, db_flags[i].arg, sizeof(buf));
+ buf, db_flags[i].arg, sizeof(buf) - 1);
}
res = NewStringObj(buf, strlen(buf));
@@ -3766,7 +3891,7 @@ tcl_DbGetOpenFlags(interp, objc, objv, dbp)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
+ buf, open_flags[i].arg, sizeof(buf) - 1);
}
res = NewStringObj(buf, strlen(buf));
@@ -4216,7 +4341,7 @@ tcl_DbCompact(interp, objc, objv, dbp)
key = &stop;
key->data = &srecno;
}
- if (type == DB_RECNO || type == DB_QUEUE) {
+ if (type == DB_RECNO || type == DB_HASH) {
result = _GetUInt32(
interp, objv[i], key->data);
if (result == TCL_OK) {
diff --git a/lang/tcl/tcl_db_pkg.c b/lang/tcl/tcl_db_pkg.c
index a190f9de..6de1e449 100644
--- a/lang/tcl/tcl_db_pkg.c
+++ b/lang/tcl/tcl_db_pkg.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -47,16 +47,17 @@ static int bdb_GetConfig __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_Handles __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_MsgType __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-static int tcl_bt_compare __P((DB *, const DBT *, const DBT *));
+static int tcl_bt_compare __P((DB *, const DBT *, const DBT *, size_t *));
static int tcl_compare_callback __P((DB *, const DBT *, const DBT *,
Tcl_Obj *, char *));
static void tcl_db_free __P((void *));
static void * tcl_db_malloc __P((size_t));
static void * tcl_db_realloc __P((void *, size_t));
-static int tcl_dup_compare __P((DB *, const DBT *, const DBT *));
+static int tcl_dup_compare __P((DB *, const DBT *, const DBT *, size_t *));
static u_int32_t tcl_h_hash __P((DB *, const void *, u_int32_t));
static int tcl_isalive __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t));
static u_int32_t tcl_part_callback __P((DB *, DBT *));
+static int tcl_rep_view __P((DB_ENV *, const char *, int *, u_int32_t));
static int tcl_set_partition_dirs
__P((Tcl_Interp *, DB *, Tcl_Obj *));
static int tcl_set_partition_keys
@@ -219,6 +220,7 @@ berkdb_Cmd(notused, interp, objc, objv)
COMPQUIET(hrip, NULL);
COMPQUIET(hsdbp, NULL);
COMPQUIET(hsip, NULL);
+ COMPQUIET(dbenv, NULL);
Tcl_ResetResult(interp);
memset(newname, 0, MSG_SIZE);
@@ -476,9 +478,11 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
"-lock",
"-lock_conflict",
"-lock_detect",
- "-lock_locks",
"-lock_lockers",
+ "-lock_locks",
+ "-lock_logid",
"-lock_objects",
+ "-lock_thread",
"-lock_max_locks",
"-lock_max_lockers",
"-lock_max_objects",
@@ -487,6 +491,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
"-lock_timeout",
"-log",
"-log_filemode",
+ "-log_blob",
"-log_buffer",
"-log_inmemory",
"-log_max",
@@ -499,6 +504,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
"-mpool_mutex_count",
"-mpool_nommap",
"-multiversion",
+ "-mutex_failchk_timeout",
"-mutex_set_align",
"-mutex_set_incr",
"-mutex_set_init",
@@ -511,11 +517,18 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
"-region_init",
"-rep",
"-rep_client",
+ "-rep_config",
"-rep_inmem_files",
"-rep_lease",
+ "-rep_limit",
"-rep_master",
"-rep_nsites",
+ "-rep_priority",
+ "-rep_request",
+ "-rep_timeout",
"-rep_transport",
+ "-rep_view",
+ "-repmgr_ack_policy",
"-set_intermediate_dir_mode",
"-snapshot",
"-tablesize",
@@ -530,6 +543,8 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
"-zero_log",
#endif
"-add_dir",
+ "-blob_dir",
+ "-blob_threshold",
"-cachesize",
"-cache_max",
"-create",
@@ -574,9 +589,11 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
TCL_ENV_LOCK,
TCL_ENV_CONFLICT,
TCL_ENV_DETECT,
- TCL_ENV_LOCK_LOCKS,
TCL_ENV_LOCK_LOCKERS,
+ TCL_ENV_LOCK_LOCKS,
+ TCL_ENV_LOCK_LOGID,
TCL_ENV_LOCK_OBJECTS,
+ TCL_ENV_LOCK_THREAD,
TCL_ENV_LOCK_MAX_LOCKS,
TCL_ENV_LOCK_MAX_LOCKERS,
TCL_ENV_LOCK_MAX_OBJECTS,
@@ -585,6 +602,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
TCL_ENV_LOCK_TIMEOUT,
TCL_ENV_LOG,
TCL_ENV_LOG_FILEMODE,
+ TCL_ENV_LOG_BLOB,
TCL_ENV_LOG_BUFFER,
TCL_ENV_LOG_INMEMORY,
TCL_ENV_LOG_MAX,
@@ -597,6 +615,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
TCL_ENV_MUTEXCOUNT,
TCL_ENV_MPOOL_NOMMAP,
TCL_ENV_MULTIVERSION,
+ TCL_ENV_MUT_FAILCHK_TIMEOUT,
TCL_ENV_MUTSETALIGN,
TCL_ENV_MUTSETINCR,
TCL_ENV_MUTSETINIT,
@@ -609,11 +628,18 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
TCL_ENV_REGION_INIT,
TCL_ENV_REP,
TCL_ENV_REP_CLIENT,
+ TCL_ENV_REP_CONFIG,
TCL_ENV_REP_INMEM_FILES,
TCL_ENV_REP_LEASE,
+ TCL_ENV_REP_LIMIT,
TCL_ENV_REP_MASTER,
TCL_ENV_REP_NSITES,
+ TCL_ENV_REP_PRIORITY,
+ TCL_ENV_REP_REQUEST,
+ TCL_ENV_REP_TIMEOUT,
TCL_ENV_REP_TRANSPORT,
+ TCL_ENV_REP_VIEW,
+ TCL_ENV_REPMGR_ACK_POLICY,
TCL_ENV_SET_INTERMEDIATE_DIR,
TCL_ENV_SNAPSHOT,
TCL_ENV_TABLESIZE,
@@ -628,6 +654,8 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
TCL_ENV_ZEROLOG,
#endif
TCL_ENV_ADD_DIR,
+ TCL_ENV_BLOB_DIR,
+ TCL_ENV_BLOB_THRESHOLD,
TCL_ENV_CACHESIZE,
TCL_ENV_CACHE_MAX,
TCL_ENV_CREATE,
@@ -875,9 +903,11 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock_detect");
break;
- case TCL_ENV_LOCK_LOCKS:
case TCL_ENV_LOCK_LOCKERS:
+ case TCL_ENV_LOCK_LOCKS:
+ case TCL_ENV_LOCK_LOGID:
case TCL_ENV_LOCK_OBJECTS:
+ case TCL_ENV_LOCK_THREAD:
case TCL_ENV_LOCK_MAX_LOCKS:
case TCL_ENV_LOCK_MAX_LOCKERS:
case TCL_ENV_LOCK_MAX_OBJECTS:
@@ -893,18 +923,26 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
if (result == TCL_OK) {
_debug_check();
switch ((enum envopen)optindex) {
+ case TCL_ENV_LOCK_LOCKERS:
+ ret = dbenv->set_memory_init(dbenv,
+ DB_MEM_LOCKER, uintarg);
+ break;
case TCL_ENV_LOCK_LOCKS:
ret = dbenv->set_memory_init(dbenv,
DB_MEM_LOCK, uintarg);
break;
- case TCL_ENV_LOCK_LOCKERS:
+ case TCL_ENV_LOCK_LOGID:
ret = dbenv->set_memory_init(dbenv,
- DB_MEM_LOCKER, uintarg);
+ DB_MEM_LOGID, uintarg);
break;
case TCL_ENV_LOCK_OBJECTS:
ret = dbenv->set_memory_init(dbenv,
DB_MEM_LOCKOBJECT, uintarg);
break;
+ case TCL_ENV_LOCK_THREAD:
+ ret = dbenv->set_memory_init(dbenv,
+ DB_MEM_THREAD, uintarg);
+ break;
case TCL_ENV_LOCK_MAX_LOCKS:
ret = dbenv->set_lk_max_locks(dbenv,
uintarg);
@@ -971,6 +1009,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
case TCL_ENV_TXN_TIME:
case TCL_ENV_TXN_TIMEOUT:
case TCL_ENV_LOCK_TIMEOUT:
+ case TCL_ENV_MUT_FAILCHK_TIMEOUT:
case TCL_ENV_REG_TIMEOUT:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -995,6 +1034,10 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
else if ((enum envopen)optindex ==
TCL_ENV_REG_TIMEOUT)
time_flag = DB_SET_REG_TIMEOUT;
+ else if ((enum envopen)optindex ==
+ TCL_ENV_MUT_FAILCHK_TIMEOUT)
+ time_flag =
+ DB_SET_MUTEX_FAILCHK_TIMEOUT;
else
time_flag = DB_SET_TXN_TIMEOUT;
@@ -1007,6 +1050,12 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
case TCL_ENV_LOG:
FLD_SET(open_flags, DB_INIT_LOG | DB_INIT_MPOOL);
break;
+ case TCL_ENV_LOG_BLOB:
+ ret =
+ dbenv->log_set_config(dbenv, DB_LOG_BLOB, 1);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "log_blob");
+ break;
case TCL_ENV_LOG_BUFFER:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -1061,15 +1110,8 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
result = TCL_ERROR;
break;
}
- result = _GetUInt32(interp, objv[i++], &uintarg);
- if (result == TCL_OK && logbufset) {
- _debug_check();
- ret = dbenv->set_lg_max(dbenv, uintarg);
- result = _ReturnSetup(interp, ret,
- DB_RETOK_STD(ret), "log_max");
- logbufset = 0;
- } else
- logmaxset = uintarg;
+ result = tcl_LogSetMax(
+ interp, dbenv, objv[i++], &logbufset, &logmaxset);
break;
case TCL_ENV_LOG_REGIONMAX:
if (i >= objc) {
@@ -1259,6 +1301,58 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
rep_flags = DB_REP_CLIENT;
FLD_SET(open_flags, DB_INIT_REP);
break;
+ case TCL_ENV_REP_CONFIG:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_config {which onoff}");
+ result = TCL_ERROR;
+ break;
+ }
+ result = tcl_RepConfig(interp, dbenv, objv[i]);
+ if (result == TCL_OK) {
+ i++;
+ FLD_SET(open_flags, DB_INIT_REP);
+ }
+ break;
+ case TCL_ENV_REP_INMEM_FILES:
+ result = tcl_RepInmemFiles(interp,dbenv);
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
+ case TCL_ENV_REP_LEASE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_lease {timeout clockskew}");
+ result = TCL_ERROR;
+ break;
+ }
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ result = tcl_RepLease(interp, myobjc, myobjv, dbenv);
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
+ case TCL_ENV_REP_LIMIT:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_limit {gbytes bytes}");
+ result = TCL_ERROR;
+ break;
+ }
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ result = tcl_RepLimit(interp, myobjc, myobjv, dbenv);
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
case TCL_ENV_REP_MASTER:
rep_flags = DB_REP_MASTER;
FLD_SET(open_flags, DB_INIT_REP);
@@ -1280,15 +1374,27 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
if (result == TCL_OK)
FLD_SET(open_flags, DB_INIT_REP);
break;
- case TCL_ENV_REP_INMEM_FILES:
- result = tcl_RepInmemFiles(interp,dbenv);
+ case TCL_ENV_REP_PRIORITY:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_priority priority");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &uintarg);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->rep_set_priority(dbenv, uintarg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "rep_set_priority");
+ }
if (result == TCL_OK)
FLD_SET(open_flags, DB_INIT_REP);
break;
- case TCL_ENV_REP_LEASE:
+ case TCL_ENV_REP_REQUEST:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
- "-rep_lease {timeout clockskew}");
+ "-rep_request {minTime maxTime}");
result = TCL_ERROR;
break;
}
@@ -1298,7 +1404,31 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
i++;
else
break;
- result = tcl_RepLease(interp, myobjc, myobjv, dbenv);
+ result = tcl_RepRequest(interp, myobjc, myobjv, dbenv);
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
+ case TCL_ENV_REP_TIMEOUT:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_timout {which timeout}");
+ result = TCL_ERROR;
+ break;
+ }
+ if ((result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv)) != TCL_OK )
+ break;
+ _debug_check();
+ if ((result =
+ Tcl_GetIntFromObj(interp, myobjv[0], &intarg)) != TCL_OK)
+ break;
+ if ((result =
+ _GetUInt32(interp, myobjv[1], &uintarg)) != TCL_OK)
+ break;
+ i++;
+ ret = dbenv->rep_set_timeout(dbenv, intarg, uintarg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "rep_set_timeout");
if (result == TCL_OK)
FLD_SET(open_flags, DB_INIT_REP);
break;
@@ -1320,6 +1450,56 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
if (result == TCL_OK)
FLD_SET(open_flags, DB_INIT_REP);
break;
+ case TCL_ENV_REP_VIEW:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_view {viewproc}");
+ result = TCL_ERROR;
+ break;
+ }
+
+ /*
+ * We use a list here instead of just sending in the
+ * proc name so that an empty list can indicate to
+ * use the BDB default full view and we send in NULL.
+ */
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ if (myobjc == 0) {
+ ip->i_rep_view = NULL;
+ _debug_check();
+ ret = dbenv->rep_set_view(dbenv, NULL);
+ } else {
+ ip->i_rep_view = myobjv[0];
+ Tcl_IncrRefCount(ip->i_rep_view);
+ _debug_check();
+ ret = dbenv->rep_set_view(dbenv, tcl_rep_view);
+ }
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "rep_set_view");
+ break;
+ case TCL_ENV_REPMGR_ACK_POLICY:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-rep_ack_policy {ack_policy}");
+ result = TCL_ERROR;
+ break;
+ }
+ result = Tcl_GetIntFromObj(interp, objv[i++], &intarg);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->
+ repmgr_set_ack_policy(dbenv, intarg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "repmgr_set_ack_policy");
+ }
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
case TCL_ENV_SNAPSHOT:
FLD_SET(set_flags, DB_TXN_SNAPSHOT);
break;
@@ -1464,7 +1644,29 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
case TCL_ENV_USE_ENVIRON:
FLD_SET(open_flags, DB_USE_ENVIRON);
break;
+ case TCL_ENV_BLOB_THRESHOLD:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-blob_threshold bytes?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &bytes);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->set_blob_threshold(dbenv,
+ bytes, 0);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "set_blob_threshold");
+ }
+ break;
case TCL_ENV_CACHESIZE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-cachesize {gbytes bytes ncaches}?");
+ result = TCL_ERROR;
+ break;
+ }
result = Tcl_ListObjGetElements(interp, objv[i],
&myobjc, &myobjv);
if (result == TCL_OK)
@@ -1580,8 +1782,8 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
break;
}
arg = Tcl_GetStringFromObj(objv[i++], NULL);
- tcl_EnvSetMsgfile(interp, dbenv, ip, arg);
- break;
+ result = tcl_EnvSetMsgfile(interp, dbenv, ip, arg);
+ break;
case TCL_ENV_ERRPFX:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -1593,9 +1795,10 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
_debug_check();
result = tcl_EnvSetErrpfx(interp, dbenv, ip, arg);
break;
- case TCL_ENV_DATA_DIR:
case TCL_ENV_ADD_DIR:
+ case TCL_ENV_BLOB_DIR:
case TCL_ENV_CREATE_DIR:
+ case TCL_ENV_DATA_DIR:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"-xxx_dir dir");
@@ -1605,15 +1808,18 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp)
arg = Tcl_GetStringFromObj(objv[i++], NULL);
_debug_check();
switch ((enum envopen)optindex) {
- case TCL_ENV_DATA_DIR:
- ret = dbenv->set_data_dir(dbenv, arg);
- break;
case TCL_ENV_ADD_DIR:
ret = dbenv->add_data_dir(dbenv, arg);
break;
+ case TCL_ENV_BLOB_DIR:
+ ret = dbenv->set_blob_dir(dbenv, arg);
+ break;
case TCL_ENV_CREATE_DIR:
ret = dbenv->set_create_dir(dbenv, arg);
break;
+ case TCL_ENV_DATA_DIR:
+ ret = dbenv->set_data_dir(dbenv, arg);
+ break;
default:
break;
}
@@ -1785,6 +1991,8 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
"-thread",
#endif
"-auto_commit",
+ "-blob_dir",
+ "-blob_threshold",
"-btree",
"-cachesize",
"-chksum",
@@ -1806,6 +2014,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
"-hash",
"-heap",
"-heap_regionsize",
+ "-heapsize",
"-inorder",
"-len",
"-lk_exclusive",
@@ -1848,6 +2057,8 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
TCL_DB_THREAD,
#endif
TCL_DB_AUTO_COMMIT,
+ TCL_DB_BLOB_DIR,
+ TCL_DB_BLOB_THRESHOLD,
TCL_DB_BTREE,
TCL_DB_CACHESIZE,
TCL_DB_CHKSUM,
@@ -1869,6 +2080,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
TCL_DB_HASH,
TCL_DB_HEAP,
TCL_DB_HEAP_REGIONSIZE,
+ TCL_DB_HEAPSIZE,
TCL_DB_INORDER,
TCL_DB_LEN,
TCL_DB_LK_EXCLUSIVE,
@@ -1908,7 +2120,8 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
size_t nlen;
type = DB_UNKNOWN;
- endarg = encenble = mode = nlen = set_err = set_msg = set_flags = 0;
+ endarg = encenble = mode = set_err = set_msg = set_flags = 0;
+ nlen = 0;
set_pfx = 0;
result = TCL_OK;
subdbtmp = NULL;
@@ -2122,6 +2335,34 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
DB_RETOK_STD(ret), "set_heap_regionsize");
}
break;
+ case TCL_DB_HEAPSIZE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-heapsize {gbytes bytes}?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = Tcl_ListObjGetElements(interp, objv[i++],
+ &myobjc, &myobjv);
+ if (result != TCL_OK)
+ break;
+ if (myobjc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-heapsize {gbytes bytes}?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, myobjv[0], &gbytes);
+ if (result != TCL_OK)
+ break;
+ result = _GetUInt32(interp, myobjv[1], &bytes);
+ if (result != TCL_OK)
+ break;
+ _debug_check();
+ ret = (*dbp)->set_heapsize(*dbp, gbytes, bytes, 0);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "set_heapsize");
+ break;
case TCL_DB_LORDER:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -2533,6 +2774,37 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
DB_RETOK_STD(ret), "set_q_extentsize");
}
break;
+ case TCL_DB_BLOB_DIR:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-blob_threshold dir?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (arg != NULL && strlen(arg) != 0) {
+ _debug_check();
+ ret = (*dbp)->set_blob_dir(*dbp, arg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "set_blob_dir");
+ }
+ break;
+ case TCL_DB_BLOB_THRESHOLD:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-blob_threshold bytes?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &bytes);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = (*dbp)->set_blob_threshold(*dbp,
+ bytes, 0);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "set_blob_threshold");
+ }
+ break;
case TCL_DB_CACHESIZE:
result = Tcl_ListObjGetElements(interp, objv[i++],
&myobjc, &myobjv);
@@ -2615,18 +2887,22 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
if (errip->i_msg != NULL &&
errip->i_msg != stdout && errip->i_msg != stderr)
(void)fclose(errip->i_msg);
- if (strcmp(arg, "/dev/stdout") == 0)
+ if (strcmp(arg, "NULL") == 0)
+ errip->i_msg = NULL;
+ else if (strcmp(arg, "/dev/stdout") == 0)
errip->i_msg = stdout;
else if (strcmp(arg, "/dev/stderr") == 0)
errip->i_msg = stderr;
else
errip->i_msg = fopen(arg, "a");
- if (errip->i_msg != NULL) {
+ if (strcmp(arg, "NULL") == 0 || errip->i_msg != NULL) {
_debug_check();
(*dbp)->set_msgfile(*dbp, errip->i_msg);
set_msg = 1;
}
- break;
+ else
+ set_msg = 0;
+ break;
case TCL_DB_ERRPFX:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -2818,7 +3094,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
dbr[nlen] = '2';
if (subdbr != NULL)
subdbr[nlen] = '2';
-
+
+ /* Disable blobs in case they are enabled environment wide. */
+ (void)hsdbp->set_blob_threshold(hsdbp, 0, 0);
/*
* Use same flags as heap, note: heap does not use of
* DB_AFTER/DB_BEFORE on cursor puts, but recno can.
@@ -2968,8 +3246,8 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
db_recno_t recno;
db_seq_t min, max, value;
Tcl_WideInt tcl_value;
- u_int32_t flags, oflags;
- int cache, endarg, i, optindex, result, ret, setrange, setvalue, v;
+ u_int32_t cache, flags, oflags;
+ int endarg, i, optindex, result, ret, setrange, setvalue, v;
char *arg, *db, msg[MSG_SIZE];
COMPQUIET(ip, NULL);
@@ -3017,7 +3295,7 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
result = TCL_ERROR;
break;
}
- result = Tcl_GetIntFromObj(interp, objv[i++], &cache);
+ result = _GetUInt32(interp, objv[i++], &cache);
break;
case TCL_SEQ_INIT:
if (i >= objc) {
@@ -3175,6 +3453,7 @@ bdb_DbRemove(interp, objc, objv)
{
static const char *bdbrem[] = {
"-auto_commit",
+ "-blob_dir",
"-encrypt",
"-encryptaes",
"-encryptany",
@@ -3186,6 +3465,7 @@ bdb_DbRemove(interp, objc, objv)
};
enum bdbrem {
TCL_DBREM_AUTOCOMMIT,
+ TCL_DBREM_BLOBDIR,
TCL_DBREM_ENCRYPT,
TCL_DBREM_ENCRYPT_AES,
TCL_DBREM_ENCRYPT_ANY,
@@ -3201,18 +3481,19 @@ bdb_DbRemove(interp, objc, objv)
u_int32_t enc_flag, iflags, set_flags;
int endarg, i, optindex, result, ret, subdblen;
u_char *subdbtmp;
- char *arg, *db, *dbr, msg[MSG_SIZE], *passwd, *subdb, *subdbr;
+ char *arg, *bdir, *db, *dbr, msg[MSG_SIZE], *passwd, *subdb, *subdbr;
size_t nlen;
dbp = NULL;
dbenv = NULL;
txn = NULL;
env = NULL;
- enc_flag = iflags = set_flags = subdblen = 0;
- endarg = nlen = 0;
+ enc_flag = iflags = set_flags = 0;
+ endarg = subdblen = 0;
+ nlen = 0;
result = TCL_OK;
subdbtmp = NULL;
- db = dbr = passwd = subdb = subdbr = NULL;
+ bdir = db = dbr = passwd = subdb = subdbr = NULL;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
@@ -3241,6 +3522,16 @@ bdb_DbRemove(interp, objc, objv)
iflags |= DB_AUTO_COMMIT;
_debug_check();
break;
+ case TCL_DBREM_BLOBDIR:
+ /* Make sure we have an arg to check against! */
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-blob_dir dir?");
+ result = TCL_ERROR;
+ break;
+ }
+ bdir = Tcl_GetStringFromObj(objv[i++], NULL);
+ break;
case TCL_DBREM_ENCRYPT:
set_flags |= DB_ENCRYPT;
_debug_check();
@@ -3372,6 +3663,14 @@ bdb_DbRemove(interp, objc, objv)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_flags");
}
+
+ if (bdir != NULL) {
+ ret = dbp->set_blob_dir(dbp, bdir);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "set_blob_dir");
+ if (ret != 0)
+ goto error;
+ }
}
/*
@@ -3922,6 +4221,7 @@ bdb_DbVerify(interp, objc, objv, ip)
DBTCL_INFO *ip; /* Our internal info */
{
static const char *bdbverify[] = {
+ "-blob_dir",
"-btcompare",
"-dupcompare",
"-hashcompare",
@@ -3940,6 +4240,7 @@ bdb_DbVerify(interp, objc, objv, ip)
NULL
};
enum bdbvrfy {
+ TCL_DBVRFY_BLOBDIR,
TCL_DBVRFY_BTCOMPARE,
TCL_DBVRFY_DUPCOMPARE,
TCL_DBVRFY_HASHCOMPARE,
@@ -3959,20 +4260,20 @@ bdb_DbVerify(interp, objc, objv, ip)
DB_ENV *dbenv;
DB *dbp;
FILE *errf;
- int (*bt_compare) __P((DB *, const DBT *, const DBT *));
- int (*dup_compare) __P((DB *, const DBT *, const DBT *));
- int (*h_compare) __P((DB *, const DBT *, const DBT *));
+ int (*bt_compare) __P((DB *, const DBT *, const DBT *, size_t *));
+ int (*dup_compare) __P((DB *, const DBT *, const DBT *, size_t *));
+ int (*h_compare) __P((DB *, const DBT *, const DBT *, size_t *));
u_int32_t (*h_hash)__P((DB *, const void *, u_int32_t));
u_int32_t enc_flag, flags, set_flags;
int endarg, i, optindex, result, ret, subdblen;
- char *arg, *db, *errpfx, *passwd, *subdb;
+ char *arg, *bldir, *db, *errpfx, *passwd, *subdb;
u_char *subdbtmp;
dbenv = NULL;
dbp = NULL;
passwd = NULL;
result = TCL_OK;
- db = errpfx = subdb = NULL;
+ bldir = db = errpfx = subdb = NULL;
errf = NULL;
bt_compare = NULL;
dup_compare = NULL;
@@ -4004,6 +4305,27 @@ bdb_DbVerify(interp, objc, objv, ip)
}
i++;
switch ((enum bdbvrfy)optindex) {
+ case TCL_DBVRFY_BLOBDIR:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-blobdir dir");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(objv[i++], NULL);
+ /*
+ * If the user already set one, free it.
+ */
+ if (bldir != NULL)
+ __os_free(dbenv != NULL ?
+ dbenv->env : NULL, bldir);
+ if ((ret = __os_strdup(NULL, arg, &bldir)) != 0) {
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "__os_strdup");
+ break;
+ }
+ _debug_check();
+ break;
case TCL_DBVRFY_BTCOMPARE:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -4222,6 +4544,13 @@ bdb_DbVerify(interp, objc, objv, ip)
/* Hang our info pointer on the DB handle, so we can do callbacks. */
dbp->api_internal = ip;
+ if (bldir != NULL && dbenv == NULL &&
+ (ret = dbp->set_blob_dir(dbp, bldir)) != 0) {
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "set_blob_dir");
+ goto error;
+ }
+
if (errf != NULL)
dbp->set_errfile(dbp, errf);
if (errpfx != NULL)
@@ -4272,6 +4601,8 @@ bdb_DbVerify(interp, objc, objv, ip)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db verify");
dbp = NULL;
error:
+ if (bldir != NULL)
+ __os_free(dbenv != NULL ? dbenv->env : NULL, bldir);
if (errf != NULL && errf != stdout && errf != stderr)
(void)fclose(errf);
if (errpfx != NULL)
@@ -4405,6 +4736,9 @@ bdb_GetConfig(interp, objc, objv)
#ifdef DIAGNOSTIC
ADD_CONFIG_NAME("diagnostic");
#endif
+#ifdef HAVE_FAILCHK_BROADCAST
+ ADD_CONFIG_NAME("failchk_broadcast");
+#endif
#ifdef HAVE_PARTITION
ADD_CONFIG_NAME("partition");
#endif
@@ -4484,8 +4818,9 @@ bdb_MsgType(interp, objc, objv)
* Add "no_type" for 0 so that we directly index.
*/
static const char *msgnames[] = {
- "no_type", "alive", "alive_req", "all_req",
- "bulk_log", "bulk_page",
+ "no_type", "alive", "alive_req", "all_req", "blob_all_req",
+ "blob_chunk", "blob_chunk_req", "blob_update",
+ "blob_update_req", "bulk_log", "bulk_page",
"dupmaster", "file", "file_fail", "file_req", "lease_grant",
"log", "log_more", "log_req", "master_req", "newclient",
"newfile", "newmaster", "newsite", "page",
@@ -4535,23 +4870,27 @@ bdb_DbUpgrade(interp, objc, objv)
Tcl_Obj *CONST objv[]; /* The argument objects */
{
static const char *bdbupg[] = {
- "-dupsort", "-env", "--", NULL
+ "-dupsort", "-env", "-P", "--", NULL
};
enum bdbupg {
TCL_DBUPG_DUPSORT,
TCL_DBUPG_ENV,
+ TCL_DBUPG_PASSWORD,
TCL_DBUPG_ENDARG
};
DB_ENV *dbenv;
DB *dbp;
+ ENV *env;
u_int32_t flags;
int endarg, i, optindex, result, ret;
- char *arg, *db;
+ char *arg, *db, *dbr, *passwd;
+ size_t nlen;
dbenv = NULL;
dbp = NULL;
+ env = NULL;
result = TCL_OK;
- db = NULL;
+ db = dbr = passwd = NULL;
flags = endarg = 0;
if (objc < 2) {
@@ -4585,6 +4924,16 @@ bdb_DbUpgrade(interp, objc, objv)
TCL_STATIC);
return (TCL_ERROR);
}
+ env = dbenv->env;
+ break;
+ case TCL_DBUPG_PASSWORD:
+ /* Make sure we have an arg to check against! */
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-P passwd?");
+ return (TCL_ERROR);
+ }
+ passwd = Tcl_GetStringFromObj(objv[i++], NULL);
break;
case TCL_DBUPG_ENDARG:
endarg = 1;
@@ -4630,11 +4979,40 @@ bdb_DbUpgrade(interp, objc, objv)
dbp->set_errpfx(dbp, "DbUpgrade");
dbp->set_errcall(dbp, _ErrorFunc);
}
+ if (passwd != NULL) {
+ if ((ret = dbp->set_encrypt(
+ dbp, passwd, DB_ENCRYPT_AES)) != 0 ) {
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "set_encrypt");
+ goto error;
+ }
+ }
ret = dbp->upgrade(dbp, db, flags);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db upgrade");
+
+ if (ret == 0 && db != NULL) {
+ nlen = strlen(db);
+ if ((ret = __os_malloc(env, nlen + 2, &dbr)) != 0) {
+ Tcl_SetResult(interp, db_strerror(ret),
+ TCL_STATIC);
+ return (0);
+ }
+ memcpy(dbr, db, nlen);
+ dbr[nlen] = '1';
+ dbr[nlen+1] = '\0';
+ /* If the associated heap databases exist, upgrade them. */
+ if (__os_exists(env, dbr, NULL) == 0) {
+ if ((ret = dbp->upgrade(dbp, dbr, flags)) != 0)
+ goto end;
+ dbr[nlen] = '2';
+ ret = dbp->upgrade(dbp, dbr, flags);
+ }
+ }
+end: result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db upgrade");
error:
if (dbp)
(void)dbp->close(dbp, 0);
+ if (dbr)
+ __os_free(env, dbr);
return (result);
}
@@ -4645,19 +5023,23 @@ error:
* reporting and the Tcl_Obj representing their respective procs.
*/
static int
-tcl_bt_compare(dbp, dbta, dbtb)
+tcl_bt_compare(dbp, dbta, dbtb, locp)
DB *dbp;
const DBT *dbta, *dbtb;
+ size_t *locp;
{
+ COMPQUIET(locp, NULL);
return (tcl_compare_callback(dbp, dbta, dbtb,
((DBTCL_INFO *)dbp->api_internal)->i_compare, "bt_compare"));
}
static int
-tcl_dup_compare(dbp, dbta, dbtb)
+tcl_dup_compare(dbp, dbta, dbtb, locp)
DB *dbp;
const DBT *dbta, *dbtb;
+ size_t *locp;
{
+ COMPQUIET(locp, NULL);
return (tcl_compare_callback(dbp, dbta, dbtb,
((DBTCL_INFO *)dbp->api_internal)->i_dupcompare, "dup_compare"));
}
@@ -4771,6 +5153,10 @@ err: __db_errx(dbp->env, "Tcl h_hash callback failed");
return (0);
}
+/*
+ * We only support testing that the process is alive for now, because that
+ * seems easiest, and that's all we need for our tests for the moment.
+ */
static int
tcl_isalive(dbenv, pid, tid, flags)
DB_ENV *dbenv;
@@ -4790,12 +5176,6 @@ tcl_isalive(dbenv, pid, tid, flags)
if (mypid == pid && (LF_ISSET(DB_MUTEX_PROCESS_ONLY) ||
mytid == tid))
return (1);
- /*
- * We only support the PROCESS_ONLY case for now, because that seems
- * easiest, and that's all we need for our tests for the moment.
- */
- if (!LF_ISSET(DB_MUTEX_PROCESS_ONLY))
- return (1);
ip = (DBTCL_INFO *)dbenv->app_private;
interp = ip->i_interp;
@@ -4971,6 +5351,64 @@ err: __db_errx(dbenv->env,
return (ret);
}
+
+static int
+tcl_rep_view(dbenv, name, result, flags)
+ DB_ENV *dbenv;
+ const char *name;
+ int *result;
+ u_int32_t flags;
+{
+#define TCLDB_VIEWITEMS 3
+ ENV *env;
+ DBTCL_INFO *ip;
+ Tcl_Interp *interp;
+ Tcl_Obj *flags_o, *myobjv[TCLDB_MAXREPFLAGS], *objv[TCLDB_VIEWITEMS];
+ int i, myobjc, res;
+
+ COMPQUIET(flags, 0);
+ ip = (DBTCL_INFO *)dbenv->app_private;
+ interp = ip->i_interp;
+ myobjv[myobjc = 0] = NULL;
+ if (flags == 0)
+ myobjv[myobjc++] = NewStringObj("none", strlen("none"));
+ /*
+ * If we're given an unrecognized flag send "unknown".
+ */
+ if (myobjc == 0)
+ myobjv[myobjc++] = NewStringObj("unknown", strlen("unknown"));
+ for (i = 0; i < myobjc; i++)
+ Tcl_IncrRefCount(myobjv[i]);
+ flags_o = Tcl_NewListObj(myobjc, myobjv);
+
+ objv[0] = ip->i_rep_view;
+ objv[1] = NewStringObj(name, strlen(name));
+ objv[2] = flags_o; /* Flags */
+ Tcl_IncrRefCount(objv[1]);
+ Tcl_IncrRefCount(flags_o);
+
+ res = Tcl_EvalObjv(interp, TCLDB_VIEWITEMS, objv, 0);
+ if (res != TCL_OK)
+ goto err;
+ Tcl_DecrRefCount(objv[1]);
+ for (i = 0; i < myobjc; i++)
+ Tcl_DecrRefCount(myobjv[i]);
+ Tcl_DecrRefCount(flags_o);
+ /*
+ * Put the result "do we replicate or not" into 'result'.
+ */
+ res = Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), result);
+ if (res != TCL_OK)
+ goto err;
+
+ return (0);
+
+err: env = dbenv->env;
+ __db_errx(env, "Tcl rep_view callback failed: %s",
+ Tcl_GetStringResult(interp));
+
+ return (1);
+}
#endif
#ifdef CONFIG_TEST
@@ -4994,7 +5432,7 @@ tcl_db_malloc(size)
Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *)));
buf = Tcl_GetString(obj);
- memcpy(buf, &obj, sizeof(&obj));
+ memcpy(buf, &obj, sizeof(Tcl_Obj *));
buf = (Tcl_Obj **)buf + 1;
return (buf);
@@ -5014,7 +5452,7 @@ tcl_db_realloc(ptr, size)
Tcl_SetObjLength(obj, (int)(size + sizeof(Tcl_Obj *)));
ptr = Tcl_GetString(obj);
- memcpy(ptr, &obj, sizeof(&obj));
+ memcpy(ptr, &obj, sizeof(Tcl_Obj *));
ptr = (Tcl_Obj **)ptr + 1;
return (ptr);
diff --git a/lang/tcl/tcl_dbcursor.c b/lang/tcl/tcl_dbcursor.c
index a6df38dc..ebf0eaa9 100644
--- a/lang/tcl/tcl_dbcursor.c
+++ b/lang/tcl/tcl_dbcursor.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -17,6 +17,8 @@
/*
* Prototypes for procedures defined later in this file:
*/
+static int tcl_DbcDbstream __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DBC *, DB_STREAM **));
static int tcl_DbcDel __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
static int tcl_DbcDup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
static int tcl_DbcCompare __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
@@ -43,6 +45,7 @@ dbc_Cmd(clientData, interp, objc, objv)
#endif
"close",
"cmp",
+ "dbstream",
"del",
"dup",
"get",
@@ -55,18 +58,24 @@ dbc_Cmd(clientData, interp, objc, objv)
#endif
DBCCLOSE,
DBCCOMPARE,
+ DBCDBSTREAM,
DBCDELETE,
DBCDUP,
DBCGET,
DBCPUT
};
DBC *dbc;
- DBTCL_INFO *dbip;
+ DB_STREAM *dbs;
+ DBTCL_INFO *dbip, *ip;
+ Tcl_Obj *res;
+ char newname[MSG_SIZE];
int cmdindex, result, ret;
Tcl_ResetResult(interp);
dbc = (DBC *)clientData;
dbip = _PtrToInfo((void *)dbc);
+ res = NULL;
+ memset(newname, 0, MSG_SIZE);
result = TCL_OK;
if (objc <= 1) {
@@ -120,6 +129,28 @@ dbc_Cmd(clientData, interp, objc, objv)
_debug_check();
result = tcl_DbcCompare(interp, objc, objv, dbc);
break;
+ case DBCDBSTREAM:
+ snprintf(newname, sizeof(newname),
+ "%s.dbs%d", dbip->i_name, dbip->i_dbcdbsid);
+ ip = _NewInfo(interp, NULL, newname, I_DBSTREAM);
+ if (ip != NULL) {
+ result = tcl_DbcDbstream(interp, objc, objv, dbc, &dbs);
+ if (result == TCL_OK) {
+ dbip->i_dbcdbsid++;
+ ip->i_parent = dbip;
+ (void)Tcl_CreateObjCommand(interp, newname,
+ (Tcl_ObjCmdProc *)dbstream_Cmd,
+ (ClientData)dbs, NULL);
+ res = NewStringObj(newname, strlen(newname));
+ _SetInfoData(ip, dbs);
+ } else
+ _DeleteInfo(ip);
+ } else {
+ Tcl_SetResult(interp,
+ "Could not set up info", TCL_STATIC);
+ result = TCL_ERROR;
+ }
+ break;
case DBCDELETE:
result = tcl_DbcDel(interp, objc, objv, dbc);
break;
@@ -133,6 +164,13 @@ dbc_Cmd(clientData, interp, objc, objv)
result = tcl_DbcPut(interp, objc, objv, dbc);
break;
}
+
+ /*
+ * Only set result if we have a res. Otherwise, lower
+ * functions have already done so.
+ */
+ if (result == TCL_OK && res)
+ Tcl_SetObjResult(interp, res);
return (result);
}
@@ -200,6 +238,7 @@ tcl_DbcPut(interp, objc, objv, dbc)
#endif
"-after",
"-before",
+ "-blob",
"-current",
"-keyfirst",
"-keylast",
@@ -213,6 +252,7 @@ tcl_DbcPut(interp, objc, objv, dbc)
#endif
DBCPUT_AFTER,
DBCPUT_BEFORE,
+ DBCPUT_BLOB,
DBCPUT_CURRENT,
DBCPUT_KEYFIRST,
DBCPUT_KEYLAST,
@@ -281,6 +321,9 @@ tcl_DbcPut(interp, objc, objv, dbc)
FLAG_CHECK(flag);
flag = DB_BEFORE;
break;
+ case DBCPUT_BLOB:
+ data.flags |= DB_DBT_BLOB;
+ break;
case DBCPUT_CURRENT:
FLAG_CHECK(flag);
flag = DB_CURRENT;
@@ -990,6 +1033,11 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
hkey.data = &rid;
hkey.ulen = hkey.size = data.size;
hkey.flags = DB_DBT_USERMEM;
+ if (data.data != NULL &&
+ F_ISSET(&data, DB_DBT_MALLOC)) {
+ __os_ufree(dbc->env, data.data);
+ data.data = NULL;
+ }
ret = phsdbp->pget(phsdbp,
dbc->txn, &hkey, &data, &tmpdata, 0);
}
@@ -1336,3 +1384,59 @@ tcl_DbcDel(interp, objc, objv, dbc)
out:
return (result);
}
+
+/*
+ * tcl_DbcDbstream --
+ */
+static int
+tcl_DbcDbstream(interp, objc, objv, dbc, dbsp)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DBC *dbc; /* Cursor pointer */
+ DB_STREAM **dbsp; /* Return database stream pointer */
+{
+ static const char *dbstreamopts[] = {
+ "-rdonly",
+ "-sync",
+ NULL
+ };
+ enum dbstreamopts {
+ DBSTREAM_READ_ONLY,
+ DBSTREAM_SYNC
+ };
+ u_int32_t flag;
+ int i, optindex, result, ret;
+
+ result = TCL_OK;
+ flag = 0;
+ i = 2;
+ while (i < objc) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], dbstreamopts,
+ "option", TCL_EXACT, &optindex) != TCL_OK) {
+ result = IS_HELP(objv[i]);
+ goto out;
+ }
+ i++;
+ switch ((enum dbstreamopts)optindex) {
+ case DBSTREAM_READ_ONLY:
+ flag |= DB_STREAM_READ;
+ break;
+ case DBSTREAM_SYNC:
+ flag |= DB_STREAM_SYNC_WRITE;
+ break;
+ }
+ if (result != TCL_OK)
+ break;
+ }
+ if (result != TCL_OK)
+ goto out;
+
+ _debug_check();
+ ret = dbc->db_stream(dbc, dbsp, flag);
+ if (ret != 0)
+ result = _ErrorSetup(interp, ret, "dbc db_stream");
+out:
+ return (result);
+}
+
diff --git a/lang/tcl/tcl_dbstream.c b/lang/tcl/tcl_dbstream.c
new file mode 100644
index 00000000..1acd06a8
--- /dev/null
+++ b/lang/tcl/tcl_dbstream.c
@@ -0,0 +1,302 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#include <tcl.h>
+#endif
+#include "dbinc/tcl_db.h"
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+static int tcl_DbstreamRead __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB_STREAM *));
+static int tcl_DbstreamWrite __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB_STREAM *));
+
+/*
+ * PUBLIC: int dbstream_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+ *
+ * dbstream_cmd --
+ * Implements the database stream command.
+ */
+int
+dbstream_Cmd(clientData, interp, objc, objv)
+ ClientData clientData; /* Database stream handle */
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+{
+ static const char *dbscmds[] = {
+ "close",
+ "read",
+ "size",
+ "write",
+ NULL
+ };
+ enum dbscmds {
+ DBSTREAMCLOSE,
+ DBSTREAMREAD,
+ DBSTREAMSIZE,
+ DBSTREAMWRITE
+ };
+ DB_STREAM *dbs;
+ Tcl_Obj *res;
+ DBTCL_INFO *dbip;
+ db_off_t size;
+ int cmdindex, result, ret;
+
+ Tcl_ResetResult(interp);
+ dbs = (DB_STREAM *)clientData;
+ dbip = _PtrToInfo((void *)dbs);
+ size = 0;
+ ret = 0;
+ result = TCL_OK;
+
+ if (objc <= 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
+ return (TCL_ERROR);
+ }
+ if (dbs == NULL) {
+ Tcl_SetResult(interp, "NULL dbstream pointer", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ if (dbip == NULL) {
+ Tcl_SetResult(interp, "NULL dbstream info pointer", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ /*
+ * Get the command name index from the object based on the berkdbcmds
+ * defined above.
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[1], dbscmds, "command",
+ TCL_EXACT, &cmdindex) != TCL_OK)
+ return (IS_HELP(objv[1]));
+ switch ((enum dbscmds)cmdindex) {
+ case DBSTREAMCLOSE:
+ /* No args for this. Error if there are some. */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = dbs->close(dbs, 0);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "dbstream size")) == TCL_OK) {
+ (void)Tcl_DeleteCommand(interp, dbip->i_name);
+ _DeleteInfo(dbip);
+ }
+ break;
+ case DBSTREAMSIZE:
+ /* No args for this. Error if there are some. */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = dbs->size(dbs, &size, 0);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "dbstream size")) == TCL_OK) {
+ res = Tcl_NewWideIntObj((Tcl_WideInt)size);
+ Tcl_SetObjResult(interp, res);
+ }
+ break;
+ case DBSTREAMREAD:
+ result = tcl_DbstreamRead(interp, objc, objv, dbs);
+ break;
+ case DBSTREAMWRITE:
+ result = tcl_DbstreamWrite(interp, objc, objv, dbs);
+ break;
+ }
+ return (result);
+}
+
+/*
+ * tcl_DbstreamRead --
+ */
+static int
+tcl_DbstreamRead(interp, objc, objv, dbs)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_STREAM *dbs; /* Database stream pointer */
+{
+ static const char *dbsreadopts[] = {
+ "-offset",
+ "-size",
+ NULL
+ };
+ enum dbsreadopts {
+ DBSTREAMREAD_OFFSET,
+ DBSTREAMREAD_SIZE
+ };
+ Tcl_Obj *res;
+ Tcl_WideInt offtmp;
+ DBT data;
+ db_off_t offset;
+ u_int32_t size;
+ int i, optindex, result, ret;
+
+ offtmp = 0;
+ memset(&data, 0, sizeof(DBT));
+ offset = 0;
+ size = 0;
+ result = TCL_OK;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
+ return (TCL_ERROR);
+ }
+
+ /*
+ * Get the command name index from the object based on the options
+ * defined above.
+ */
+ i = 2;
+ while (i < objc) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], dbsreadopts,
+ "option", TCL_EXACT, &optindex) != TCL_OK) {
+ /*
+ * Reset the result so we don't get
+ * an errant error message if there is another error.
+ */
+ if (IS_HELP(objv[i]) == TCL_OK) {
+ result = TCL_OK;
+ goto out;
+ }
+ Tcl_ResetResult(interp);
+ break;
+ }
+ i++;
+ switch ((enum dbsreadopts)optindex) {
+ case DBSTREAMREAD_OFFSET:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-offset offset?");
+ result = TCL_ERROR;
+ goto out;
+ }
+ if ((result = Tcl_GetWideIntFromObj(interp,
+ objv[i++], &offtmp)) != TCL_OK)
+ goto out;
+ offset = (db_off_t)offtmp;
+ break;
+ case DBSTREAMREAD_SIZE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-size bytes?");
+ result = TCL_ERROR;
+ goto out;
+ }
+ if ((result = _GetUInt32(interp,
+ objv[i++], &size)) != TCL_OK)
+ goto out;
+ break;
+ }
+ }
+ _debug_check();
+ data.flags = DB_DBT_MALLOC;
+ ret = dbs->read(dbs, &data, offset, size, 0);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "dbstream read")) == TCL_OK) {
+ res = NewStringObj(data.data, data.size);
+ Tcl_SetObjResult(interp, res);
+ }
+out: if (data.data != NULL)
+ __os_ufree(dbs->dbc->env, data.data);
+ return (result);
+}
+
+/*
+ * tcl_DbstreamWrite --
+ */
+static int
+tcl_DbstreamWrite(interp, objc, objv, dbs)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_STREAM *dbs; /* Database stream pointer */
+{
+ static const char *dbsreadopts[] = {
+ "-offset",
+ NULL
+ };
+ enum dbsreadopts {
+ DBSTREAMWRITE_OFFSET
+ };
+ Tcl_WideInt offtmp;
+ DBT data;
+ db_off_t offset;
+ int freedata, i, optindex, result, ret;
+
+ offtmp = 0;
+ memset(&data, 0, sizeof(DBT));
+ offset = 0;
+ freedata = 0;
+ result = TCL_OK;
+
+ if (objc != 3 && objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-args? data");
+ return (TCL_ERROR);
+ }
+
+ /*
+ * Get the command name index from the object based on the options
+ * defined above.
+ */
+ i = 2;
+ while (i < objc) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], dbsreadopts,
+ "option", TCL_EXACT, &optindex) != TCL_OK) {
+ /*
+ * Reset the result so we don't get
+ * an errant error message if there is another error.
+ */
+ if (IS_HELP(objv[i]) == TCL_OK) {
+ result = TCL_OK;
+ goto out;
+ }
+ Tcl_ResetResult(interp);
+ break;
+ }
+ i++;
+ switch ((enum dbsreadopts)optindex) {
+ case DBSTREAMWRITE_OFFSET:
+ if (i >= objc || objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-offset offset? data");
+ result = TCL_ERROR;
+ goto out;
+ }
+ if ((result = Tcl_GetWideIntFromObj(interp,
+ objv[i++], &offtmp)) != TCL_OK)
+ goto out;
+ offset = (db_off_t)offtmp;
+ break;
+ }
+ }
+ _debug_check();
+ ret = _CopyObjBytes(interp, objv[objc-1],
+ &data.data, &data.size, &freedata);
+ if (ret != 0) {
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "dbstream write");
+ goto out;
+ }
+ ret = dbs->write(dbs, &data, offset, 0);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "dbstream write");
+
+out: if (freedata && data.data != NULL)
+ __os_free(NULL, data.data);
+ return (result);
+}
diff --git a/lang/tcl/tcl_env.c b/lang/tcl/tcl_env.c
index e79ac2cf..7834e9ab 100644
--- a/lang/tcl/tcl_env.c
+++ b/lang/tcl/tcl_env.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -23,12 +23,14 @@ static void _EnvInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
static int env_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_EventInfo __P((Tcl_Interp *,
- int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+ int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+static int env_EventCount __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
static int env_GetFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetOpenFlag
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-static int env_GetLockDetect
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+static int env_GetOpenFlag __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB_ENV *));
+static int env_GetLockDetect __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
static int env_GetVerbose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
@@ -48,9 +50,12 @@ env_Cmd(clientData, interp, objc, objv)
static const char *envcmds[] = {
#ifdef CONFIG_TEST
"attributes",
+ "backup",
+ "dbbackup",
"errfile",
"errpfx",
"event_info",
+ "event_count",
"failchk",
"id_reset",
"lock_detect",
@@ -74,6 +79,7 @@ env_Cmd(clientData, interp, objc, objv)
"log_put",
"log_stat",
"log_stat_print",
+ "log_verify",
"lsn_reset",
"mpool",
"mpool_stat",
@@ -81,10 +87,13 @@ env_Cmd(clientData, interp, objc, objv)
"mpool_sync",
"mpool_trickle",
"msgfile",
+ "msgfile_close",
"mutex",
+ "mutex_failchk_timeout",
"mutex_free",
"mutex_get_align",
"mutex_get_incr",
+ "mutex_get_init",
"mutex_get_max",
"mutex_get_tas_spins",
"mutex_lock",
@@ -114,11 +123,15 @@ env_Cmd(clientData, interp, objc, objv)
"rep_transport",
"repmgr",
"repmgr_get_ack_policy",
+ "repmgr_get_inqueue_max",
+ "repmgr_get_inqueue_redzone",
+ "repmgr_get_inqueue_fullevent",
"repmgr_get_local_site",
"repmgr_site_list",
"repmgr_stat",
"repmgr_stat_print",
"set_flags",
+ "set_lg_max",
"stat_print",
"test",
"txn_applied",
@@ -133,6 +146,8 @@ env_Cmd(clientData, interp, objc, objv)
"close",
"dbremove",
"dbrename",
+ "get_blob_dir",
+ "get_blob_threshold",
"get_cachesize",
"get_cache_max",
"get_create_dir",
@@ -149,20 +164,26 @@ env_Cmd(clientData, interp, objc, objv)
"get_lk_detect",
"get_lk_init_lockers",
"get_lk_init_locks",
+ "get_lk_init_logid",
"get_lk_init_objects",
+ "get_lk_init_thread",
"get_lk_max_lockers",
"get_lk_max_locks",
"get_lk_max_objects",
"get_lk_partitions",
+ "get_lk_tablesize",
+ "get_memory_max",
"get_metadata_dir",
"get_mp_max_openfd",
"get_mp_max_write",
"get_mp_mmapsize",
"get_mp_mtxcount",
"get_mp_pagesize",
+ "get_mp_tablesize",
"get_open_flags",
"get_shm_key",
"get_tas_spins",
+ "get_thread_count",
"get_timeout",
"get_tmp_dir",
"get_tx_init",
@@ -170,6 +191,7 @@ env_Cmd(clientData, interp, objc, objv)
"get_tx_timestamp",
"get_verbose",
"resize_cache",
+ "set_blob_threshold",
"set_data_dir",
"set_maxcache",
"txn",
@@ -179,9 +201,12 @@ env_Cmd(clientData, interp, objc, objv)
enum envcmds {
#ifdef CONFIG_TEST
ENVATTR,
+ ENVBACKUP,
+ ENVDBBACKUP,
ENVERRFILE,
ENVERRPFX,
ENVEVENTINFO,
+ ENVEVENTCOUNT,
ENVFAILCHK,
ENVIDRESET,
ENVLKDETECT,
@@ -205,6 +230,7 @@ env_Cmd(clientData, interp, objc, objv)
ENVLOGPUT,
ENVLOGSTAT,
ENVLOGSTATPRT,
+ ENVLOGVERIFY,
ENVLSNRESET,
ENVMP,
ENVMPSTAT,
@@ -212,10 +238,13 @@ env_Cmd(clientData, interp, objc, objv)
ENVMPSYNC,
ENVTRICKLE,
ENVMSGFILE,
+ ENVMSGFILECLOSE,
ENVMUTEX,
+ ENVMUTFAILCHKTIMEOUT,
ENVMUTFREE,
ENVMUTGETALIGN,
ENVMUTGETINCR,
+ ENVMUTGETINIT,
ENVMUTGETMAX,
ENVMUTGETTASSPINS,
ENVMUTLOCK,
@@ -245,11 +274,15 @@ env_Cmd(clientData, interp, objc, objv)
ENVREPTRANSPORT,
ENVREPMGR,
ENVREPMGRGETACK,
+ ENVREPMGRGETINQUEUEMAX,
+ ENVREPMGRGETINQUEUEREDZONE,
+ ENVREPMGRGETINQUEUEFEVENT,
ENVREPMGRGETLOCAL,
ENVREPMGRSITELIST,
ENVREPMGRSTAT,
ENVREPMGRSTATPRT,
ENVSETFLAGS,
+ ENVSETLOGMAX,
ENVSTATPRT,
ENVTEST,
ENVTXNAPPLIED,
@@ -264,6 +297,8 @@ env_Cmd(clientData, interp, objc, objv)
ENVCLOSE,
ENVDBREMOVE,
ENVDBRENAME,
+ ENVGETBLOBDIR,
+ ENVGETBLOBTHRESHOLD,
ENVGETCACHESIZE,
ENVGETCACHEMAX,
ENVGETCREATEDIR,
@@ -280,20 +315,26 @@ env_Cmd(clientData, interp, objc, objv)
ENVGETLKDETECT,
ENVGETLKINITLOCKERS,
ENVGETLKINITLOCKS,
+ ENVGETLKINITLOGID,
ENVGETLKINITOBJECTS,
+ ENVGETLKINITTHREAD,
ENVGETLKMAXLOCKERS,
ENVGETLKMAXLOCKS,
ENVGETLKMAXOBJECTS,
ENVGETLKPARTITIONS,
+ ENVGETLKTABLESIZE,
+ ENVGETMEMORYMAX,
ENVGETMETADATADIR,
ENVGETMPMAXOPENFD,
ENVGETMPMAXWRITE,
ENVGETMPMMAPSIZE,
ENVGETMPMTXCOUNT,
ENVGETMPPAGESIZE,
+ ENVGETMPTABLESIZE,
ENVGETOPENFLAG,
ENVGETSHMKEY,
ENVGETTASSPINS,
+ ENVGETTHREADCOUNT,
ENVGETTIMEOUT,
ENVGETTMPDIR,
ENVGETTXINIT,
@@ -301,6 +342,7 @@ env_Cmd(clientData, interp, objc, objv)
ENVGETTXTIMESTAMP,
ENVGETVERBOSE,
ENVRESIZECACHE,
+ ENVSETBLOBTHRESHOLD,
ENVSETDATADIR,
ENVSETMAXCACHE,
ENVTXN,
@@ -353,9 +395,18 @@ env_Cmd(clientData, interp, objc, objv)
res = NULL;
switch ((enum envcmds)cmdindex) {
#ifdef CONFIG_TEST
+ case ENVBACKUP:
+ result = tcl_EnvBackup(interp, objc, objv, dbenv);
+ break;
+ case ENVDBBACKUP:
+ result = tcl_EnvDbBackup(interp, objc, objv, dbenv);
+ break;
case ENVEVENTINFO:
result = env_EventInfo(interp, objc, objv, dbenv, envip);
break;
+ case ENVEVENTCOUNT:
+ result = env_EventCount(interp, objc, objv, dbenv, envip);
+ break;
case ENVFAILCHK:
/*
* No args for this. Error if there are some.
@@ -442,7 +493,8 @@ env_Cmd(clientData, interp, objc, objv)
if (result != TCL_OK)
return (result);
if (dbenv->env->lk_handle == NULL) {
- Tcl_SetResult(interp, "env not configured for locking", NULL);
+ Tcl_SetResult(interp,
+ "env not configured for locking", NULL);
return (TCL_ERROR);
}
ret = dbenv->set_lk_priority(dbenv, lockid, value);
@@ -529,6 +581,9 @@ env_Cmd(clientData, interp, objc, objv)
case ENVLOGSTATPRT:
result = tcl_LogStatPrint(interp, objc, objv, dbenv);
break;
+ case ENVLOGVERIFY:
+ result = tcl_LogVerify(interp, objc, objv, dbenv);
+ break;
case ENVMPSTAT:
result = tcl_MpStat(interp, objc, objv, dbenv);
break;
@@ -547,6 +602,9 @@ env_Cmd(clientData, interp, objc, objv)
case ENVMUTEX:
result = tcl_Mutex(interp, objc, objv, dbenv);
break;
+ case ENVMUTFAILCHKTIMEOUT:
+ result = tcl_MutexFailchkTimeout(interp, objc, objv, dbenv);
+ break;
case ENVMUTFREE:
result = tcl_MutFree(interp, objc, objv, dbenv);
break;
@@ -556,6 +614,9 @@ env_Cmd(clientData, interp, objc, objv)
case ENVMUTGETINCR:
result = tcl_MutGet(interp, dbenv, DBTCL_MUT_INCR);
break;
+ case ENVMUTGETINIT:
+ result = tcl_MutGet(interp, dbenv, DBTCL_MUT_INIT);
+ break;
case ENVMUTGETMAX:
result = tcl_MutGet(interp, dbenv, DBTCL_MUT_MAX);
break;
@@ -658,7 +719,7 @@ env_Cmd(clientData, interp, objc, objv)
listobjc, listobjv, dbenv);
break;
case ENVREPLIMIT:
- result = tcl_RepLimit(interp, objc, objv, dbenv);
+ result = tcl_RepLimit(interp, (objc-2), &objv[2], dbenv);
break;
case ENVREPNSITES:
result = tcl_RepNSites(interp, objc, objv, dbenv);
@@ -667,7 +728,7 @@ env_Cmd(clientData, interp, objc, objv)
result = tcl_RepProcessMessage(interp, objc, objv, dbenv);
break;
case ENVREPREQUEST:
- result = tcl_RepRequest(interp, objc, objv, dbenv);
+ result = tcl_RepRequest(interp, (objc-2), &objv[2], dbenv);
break;
case ENVREPSTART:
result = tcl_RepStart(interp, objc, objv, dbenv);
@@ -698,6 +759,22 @@ env_Cmd(clientData, interp, objc, objv)
case ENVREPMGRGETACK:
result = tcl_RepGetAckPolicy(interp, objc, objv, dbenv);
break;
+ case ENVREPMGRGETINQUEUEMAX:
+ result = tcl_RepGetTwo(interp, dbenv, DBTCL_GETINQUEUE_MAX);
+ break;
+ case ENVREPMGRGETINQUEUEREDZONE:
+ result = tcl_RepGetTwo(interp, dbenv, DBTCL_GETINQUEUE_REDZONE);
+ break;
+ case ENVREPMGRGETINQUEUEFEVENT:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = __repmgr_get_incoming_queue_fullevent(dbenv, &intvalue);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env repmgr_get_inqueue_fullevent")) == TCL_OK)
+ res = Tcl_NewIntObj(intvalue);
+ break;
case ENVREPMGRGETLOCAL:
result = tcl_RepGetLocalSite(interp, objc, objv, dbenv);
break;
@@ -710,6 +787,9 @@ env_Cmd(clientData, interp, objc, objv)
case ENVREPMGRSTATPRT:
result = tcl_RepMgrStatPrint(interp, objc, objv, dbenv);
break;
+ case ENVSETLOGMAX:
+ result = tcl_LogSetMax(interp, dbenv, objv[2], NULL, NULL);
+ break;
case ENVTXNAPPLIED:
result = tcl_RepApplied(interp, objc, objv, dbenv);
break;
@@ -746,7 +826,7 @@ env_Cmd(clientData, interp, objc, objv)
break;
case ENVERRFILE:
/*
- * One args for this. Error if different.
+ * One arg for this. Error if different.
*/
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "errfile");
@@ -758,7 +838,7 @@ env_Cmd(clientData, interp, objc, objv)
break;
case ENVERRPFX:
/*
- * One args for this. Error if different.
+ * One arg for this. Error if different.
*/
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "pfx");
@@ -769,15 +849,27 @@ env_Cmd(clientData, interp, objc, objv)
break;
case ENVMSGFILE:
/*
- * One args for this. Error if different.
+ * One arg for this. Error if different.
*/
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "msgfile");
return (TCL_ERROR);
}
strarg = Tcl_GetStringFromObj(objv[2], NULL);
- tcl_EnvSetMsgfile(interp, dbenv, envip, strarg);
- result = TCL_OK;
+ ret = tcl_EnvSetMsgfile(interp, dbenv, envip, strarg);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env set_msgfile")) == TCL_OK)
+ res = Tcl_NewIntObj(ret);
+ break;
+ case ENVMSGFILECLOSE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "msgfile_close");
+ return (TCL_ERROR);
+ }
+ ret = tcl_EnvCloseMsgfile(interp, dbenv, envip);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env close msgfile")) == TCL_OK)
+ res = Tcl_NewIntObj(ret);
break;
case ENVSETFLAGS:
/*
@@ -818,6 +910,27 @@ env_Cmd(clientData, interp, objc, objv)
case ENVDBRENAME:
result = env_DbRename(interp, objc, objv, dbenv);
break;
+ case ENVGETBLOBDIR:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_blob_dir(dbenv, &strval);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_blob_dir")) == TCL_OK)
+ res = NewStringObj(strval,
+ strval != NULL ? strlen(strval) : 0);
+ break;
+ case ENVGETBLOBTHRESHOLD:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_blob_threshold(dbenv, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_blob_threshold")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
case ENVGETCACHESIZE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -853,7 +966,8 @@ env_Cmd(clientData, interp, objc, objv)
ret = dbenv->get_create_dir(dbenv, &strval);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_create_dir")) == TCL_OK)
- res = NewStringObj(strval, strlen(strval));
+ res = NewStringObj(strval,
+ strval != NULL ? strlen(strval) : 0);
break;
case ENVGETDATADIRS:
if (objc != 2) {
@@ -866,7 +980,8 @@ env_Cmd(clientData, interp, objc, objv)
res = Tcl_NewListObj(0, NULL);
for (i = 0; result == TCL_OK && dirs[i] != NULL; i++)
result = Tcl_ListObjAppendElement(interp, res,
- NewStringObj(dirs[i], strlen(dirs[i])));
+ NewStringObj(dirs[i],
+ dirs[i] != NULL ? strlen(dirs[i]) : 0));
}
break;
case ENVGETENCRYPTFLAGS:
@@ -966,6 +1081,16 @@ env_Cmd(clientData, interp, objc, objv)
"env get_lk_init_locks")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
+ case ENVGETLKINITLOGID:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_memory_init(dbenv, DB_MEM_LOGID, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_lk_init_logid")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
case ENVGETLKINITOBJECTS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -976,6 +1101,16 @@ env_Cmd(clientData, interp, objc, objv)
"env get_lk_init_objects")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
+ case ENVGETLKINITTHREAD:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_memory_init(dbenv, DB_MEM_THREAD, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_lk_init_thread")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
case ENVGETLKMAXLOCKERS:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -1016,6 +1151,29 @@ env_Cmd(clientData, interp, objc, objv)
"env get_lk_partitions")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
+ case ENVGETLKTABLESIZE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_lk_tablesize(dbenv, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_lk_tablesize")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
+ case ENVGETMEMORYMAX:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_memory_max(dbenv, &gbytes, &bytes);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_memory_max")) == TCL_OK) {
+ myobjv[0] = Tcl_NewLongObj((long)gbytes);
+ myobjv[1] = Tcl_NewLongObj((long)bytes);
+ res = Tcl_NewListObj(2, myobjv);
+ }
+ break;
case ENVGETMETADATADIR:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -1079,6 +1237,16 @@ env_Cmd(clientData, interp, objc, objv)
"env get_mp_pagesize")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
+ case ENVGETMPTABLESIZE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_mp_tablesize(dbenv, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_mp_tablesize")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
case ENVGETOPENFLAG:
result = env_GetOpenFlag(interp, objc, objv, dbenv);
break;
@@ -1102,6 +1270,16 @@ env_Cmd(clientData, interp, objc, objv)
"env get_tas_spins")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
break;
+ case ENVGETTHREADCOUNT:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_thread_count(dbenv, &value);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_thread_count")) == TCL_OK)
+ res = Tcl_NewLongObj((long)value);
+ break;
case ENVGETTIMEOUT:
result = env_GetTimeout(interp, objc, objv, dbenv);
break;
@@ -1174,9 +1352,21 @@ env_Cmd(clientData, interp, objc, objv)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"resize_cache");
break;
+ case ENVSETBLOBTHRESHOLD:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-set_blob_threshold bytes?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[2], &bytes);
+ ret = dbenv->set_blob_threshold(dbenv, bytes, 0);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env set_blob_threshold");
+ break;
case ENVSETDATADIR:
/*
- * One args for this. Error if different.
+ * One arg for this. Error if different.
*/
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "pfx");
@@ -1490,6 +1680,7 @@ _EnvInfoDelete(interp, envip)
case I_AUX:
case I_DB:
case I_DBC:
+ case I_DBSTREAM:
case I_ENV:
case I_LOCK:
case I_LOGC:
@@ -1577,6 +1768,144 @@ tcl_EnvClose(interp, objc, objv, dbenv, envip)
#ifdef CONFIG_TEST
/*
+ * PUBLIC: int tcl_EnvBackup __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
+ * PUBLIC: DB_ENV *));
+ *
+ * tcl_EnvBackup --
+ * Implements the ENV->backup command.
+ */
+int
+tcl_EnvBackup(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* arg count */
+ Tcl_Obj * CONST* objv; /* args */
+ DB_ENV *dbenv; /* Database pointer */
+{
+ static const char *buwhich[] = {
+ "-clean",
+ "-create",
+ "-excl",
+ "-files",
+ "-no_logs",
+ "-single_dir",
+ "-update",
+ "-verbose",
+ NULL
+ };
+ enum buwhich {
+ BKUPCLEAN,
+ BKUPCREATE,
+ BKUPEXCL,
+ BKUPFILES,
+ BKUPNOLOGS,
+ BKUPSINGLEDIR,
+ BKUPUPDATE,
+ BKUPVERBOSE
+ };
+ int i, optindex, result, ret;
+ u_int32_t flags;
+ char *targetdir;
+
+ result = TCL_OK;
+ flags = 0;
+ i = 2;
+ Tcl_SetResult(interp, "0", TCL_STATIC);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?args? target");
+ return (TCL_ERROR);
+ }
+ while (i < (objc - 1)) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], buwhich, "option",
+ TCL_EXACT, &optindex) != TCL_OK)
+ return (IS_HELP(objv[i]));
+ i++;
+ switch ((enum buwhich)optindex) {
+ case BKUPCLEAN:
+ flags |= DB_BACKUP_CLEAN;
+ break;
+ case BKUPCREATE:
+ flags |= DB_CREATE;
+ break;
+ case BKUPEXCL:
+ flags |= DB_EXCL;
+ break;
+ case BKUPFILES:
+ flags |= DB_BACKUP_FILES;
+ break;
+ case BKUPNOLOGS:
+ flags |= DB_BACKUP_NO_LOGS;
+ break;
+ case BKUPSINGLEDIR:
+ flags |= DB_BACKUP_SINGLE_DIR;
+ break;
+ case BKUPUPDATE:
+ flags |= DB_BACKUP_UPDATE;
+ break;
+ case BKUPVERBOSE:
+ flags |= DB_VERB_BACKUP;
+ break;
+ }
+ }
+ targetdir = Tcl_GetStringFromObj(objv[i], NULL);
+ ret = dbenv->backup(dbenv, targetdir, flags);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "backup");
+ return (result);
+}
+
+/*
+ * PUBLIC: int tcl_EnvDbBackup __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
+ * PUBLIC: DB_ENV *));
+ *
+ * tcl_EnvDbBackup --
+ * Implements the ENV->dbbackup command.
+ */
+int
+tcl_EnvDbBackup(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* arg count */
+ Tcl_Obj * CONST* objv; /* args */
+ DB_ENV *dbenv; /* Database pointer */
+{
+ static const char *dbbuwhich[] = {
+ "-excl",
+ NULL
+ };
+ enum dbbuwhich {
+ DBBKUPEXCL
+ };
+ int i, optindex, result, ret;
+ u_int32_t flags;
+ char *srcfile, *targetdir;
+
+ result = TCL_OK;
+ flags = 0;
+ i = 2;
+ Tcl_SetResult(interp, "0", TCL_STATIC);
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?args? file targetdir");
+ return (TCL_ERROR);
+ } else if (objc > 4) {
+ /*
+ * If there is an arg, make sure it is the right one.
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], dbbuwhich, "option",
+ TCL_EXACT, &optindex) != TCL_OK)
+ return (IS_HELP(objv[2]));
+ switch ((enum dbbuwhich)optindex) {
+ case DBBKUPEXCL:
+ flags |= DB_EXCL;
+ break;
+ }
+ i = 4;
+ }
+ srcfile = Tcl_GetStringFromObj(objv[i++], NULL);
+ targetdir = Tcl_GetStringFromObj(objv[i], NULL);
+ ret = dbenv->dbbackup(dbenv, srcfile, targetdir, flags);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "dbbackup");
+ return (result);
+}
+
+/*
* PUBLIC: int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
* PUBLIC: DB_ENV *));
*
@@ -1699,6 +2028,7 @@ tcl_EnvVerbose(interp, dbenv, which, onoff)
"deadlock",
"fileops",
"fileops_all",
+ "mvcc",
"recovery",
"register",
"rep",
@@ -1719,6 +2049,7 @@ tcl_EnvVerbose(interp, dbenv, which, onoff)
ENVVERB_DEADLOCK,
ENVVERB_FILEOPS,
ENVVERB_FILEOPS_ALL,
+ ENVVERB_MVCC,
ENVVERB_RECOVERY,
ENVVERB_REGISTER,
ENVVERB_REPLICATION,
@@ -1762,6 +2093,9 @@ tcl_EnvVerbose(interp, dbenv, which, onoff)
case ENVVERB_FILEOPS_ALL:
wh = DB_VERB_FILEOPS_ALL;
break;
+ case ENVVERB_MVCC:
+ wh = DB_VERB_MVCC;
+ break;
case ENVVERB_RECOVERY:
wh = DB_VERB_RECOVERY;
break;
@@ -1909,6 +2243,36 @@ err:
return (result);
}
+static const struct {
+ u_int32_t flag;
+ char *name;
+} event_names[] = {
+ { DB_EVENT_PANIC, "panic" },
+ { DB_EVENT_REG_ALIVE, "reg_alive" },
+ { DB_EVENT_REG_PANIC, "reg_panic" },
+ { DB_EVENT_REP_AUTOTAKEOVER_FAILED, "autotakeover_failed" },
+ { DB_EVENT_REP_CLIENT, "client" },
+ { DB_EVENT_REP_CONNECT_BROKEN, "connection_broken" },
+ { DB_EVENT_REP_CONNECT_ESTD, "connection_established" },
+ { DB_EVENT_REP_CONNECT_TRY_FAILED, "connection_retry_failed" },
+ { DB_EVENT_REP_DUPMASTER, "dupmaster" },
+ { DB_EVENT_REP_ELECTED, "elected" },
+ { DB_EVENT_REP_ELECTION_FAILED, "election_failed" },
+ { DB_EVENT_REP_INQUEUE_FULL, "incoming_queue_full" },
+ { DB_EVENT_REP_JOIN_FAILURE, "join_failure" },
+ { DB_EVENT_REP_LOCAL_SITE_REMOVED, "local_site_removed" },
+ { DB_EVENT_REP_MASTER, "master" },
+ { DB_EVENT_REP_MASTER_FAILURE, "master_failure" },
+ { DB_EVENT_REP_NEWMASTER, "newmaster" },
+ { DB_EVENT_REP_PERM_FAILED, "perm_failed" },
+ { DB_EVENT_REP_SITE_ADDED, "site_added" },
+ { DB_EVENT_REP_SITE_REMOVED, "site_removed" },
+ { DB_EVENT_REP_STARTUPDONE, "startupdone" },
+ { DB_EVENT_REP_WOULD_ROLLBACK, "would_rollback" },
+ { DB_EVENT_WRITE_FAILED, "write_failed" },
+ { DB_EVENT_NO_SUCH_EVENT, NULL }
+};
+
/*
* env_EventInfo --
* Implements the ENV->event_info command.
@@ -1933,33 +2297,6 @@ env_EventInfo(interp, objc, objv, dbenv, ip)
int clear, enc, i, ret, t_ret;
u_int32_t bit_flag;
- static const struct {
- u_int32_t flag;
- char *name;
- } event_names[] = {
- { DB_EVENT_PANIC, "panic" },
- { DB_EVENT_REG_ALIVE, "reg_alive" },
- { DB_EVENT_REG_PANIC, "reg_panic" },
- { DB_EVENT_REP_CLIENT, "client" },
- { DB_EVENT_REP_CONNECT_BROKEN, "connection_broken" },
- { DB_EVENT_REP_CONNECT_ESTD, "connection_established" },
- { DB_EVENT_REP_CONNECT_TRY_FAILED, "connection_retry_failed" },
- { DB_EVENT_REP_DUPMASTER, "dupmaster" },
- { DB_EVENT_REP_ELECTED, "elected" },
- { DB_EVENT_REP_ELECTION_FAILED, "election_failed" },
- { DB_EVENT_REP_JOIN_FAILURE, "join_failure" },
- { DB_EVENT_REP_LOCAL_SITE_REMOVED, "local_site_removed" },
- { DB_EVENT_REP_MASTER, "master" },
- { DB_EVENT_REP_MASTER_FAILURE, "master_failure" },
- { DB_EVENT_REP_NEWMASTER, "newmaster" },
- { DB_EVENT_REP_PERM_FAILED, "perm_failed" },
- { DB_EVENT_REP_SITE_ADDED, "site_added" },
- { DB_EVENT_REP_SITE_REMOVED, "site_removed" },
- { DB_EVENT_REP_STARTUPDONE, "startupdone" },
- { DB_EVENT_REP_WOULD_ROLLBACK, "would_rollback" },
- { DB_EVENT_WRITE_FAILED, "write_failed" },
- { DB_EVENT_NO_SUCH_EVENT, NULL }
- };
/*
* Note that when this list grows to more than 32 event types, the code
* below (the shift operation) will be broken.
@@ -2078,12 +2415,87 @@ env_EventInfo(interp, objc, objv, dbenv, ip)
"mutex unlock"));
Tcl_SetObjResult(interp, res);
- if (clear)
+ if (clear) {
ip->i_event_info->events = 0;
+ memset(ip->i_event_info->count, 0,
+ sizeof(ip->i_event_info->count));
+ }
return (TCL_OK);
}
/*
+ * env_EventCount --
+ * Implements the 'env event_count' command.
+ */
+static int
+env_EventCount(interp, objc, objv, dbenv, ip)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *dbenv;
+ DBTCL_INFO *ip;
+{
+ int result, ret, unused;
+ size_t count, i, names_cnt;
+ const char *name, **names;
+ Tcl_Obj *res;
+
+ names = NULL;
+ res = NULL;
+ names_cnt = sizeof(event_names) / sizeof(event_names[0]);
+
+ if(ip->i_event_info == NULL) {
+ /* Script needs "-event" in "berkdb env" cmd. */
+ Tcl_SetResult(interp,
+ "event collection not enabled on this env", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "event_name");
+ return (TCL_ERROR);
+ }
+
+ /*
+ * Set up the event names array, then Tcl_GetIndexFromObj will
+ * check the name passed-in to see whether it is valid, and print
+ * hints when it is invalid.
+ */
+ ret = __os_malloc(dbenv->env,
+ names_cnt * sizeof(char *), (void *)&names);
+ if (ret != 0) {
+ Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
+ return (TCL_ERROR);
+ }
+
+ for (i = 0; i < names_cnt; i++)
+ names[i] = event_names[i].name;
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], names, "event_name",
+ TCL_EXACT, &unused) != TCL_OK) {
+ result = (IS_HELP(objv[2]));
+ goto err;
+ }
+
+ name = Tcl_GetStringFromObj(objv[2], NULL);
+ for (i = 0; event_names[i].flag != DB_EVENT_NO_SUCH_EVENT; i++)
+ if (strcmp(event_names[i].name, name) == 0)
+ break;
+ DB_ASSERT(dbenv->env, event_names[i].flag != DB_EVENT_NO_SUCH_EVENT);
+ DB_ASSERT(dbenv->env, i < names_cnt);
+ count = ip->i_event_info->count[event_names[i].flag];
+ res = Tcl_NewLongObj((long)count);
+ Tcl_SetObjResult(interp, res);
+
+ result = TCL_OK;
+err:
+ if (names != NULL)
+ __os_free(dbenv->env, (void *)names);
+
+ return (result);
+}
+
+/*
* PUBLIC: int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
* PUBLIC: Tcl_Obj *));
*
@@ -2260,6 +2672,7 @@ tcl_EnvTest(interp, objc, objv, dbenv)
"postsync",
"repmgr_perm",
"subdb_lock",
+ "repmgr_heartbeat",
NULL
};
enum envtestat {
@@ -2275,7 +2688,8 @@ tcl_EnvTest(interp, objc, objv, dbenv)
ENVTEST_POSTOPEN,
ENVTEST_POSTSYNC,
ENVTEST_REPMGR_PERM,
- ENVTEST_SUBDB_LOCKS
+ ENVTEST_SUBDB_LOCKS,
+ ENVTEST_REPMGR_HEARTBEAT
};
static const char *envtestforce[] = {
"noarchive_timeout",
@@ -2390,6 +2804,10 @@ tcl_EnvTest(interp, objc, objv, dbenv)
DB_ASSERT(env, loc == &env->test_abort);
testval = DB_TEST_SUBDB_LOCKS;
break;
+ case ENVTEST_REPMGR_HEARTBEAT:
+ DB_ASSERT(env, loc == &env->test_abort);
+ testval = DB_TEST_REPMGR_HEARTBEAT;
+ break;
default:
Tcl_SetResult(interp, "Illegal test location", TCL_STATIC);
return (TCL_ERROR);
@@ -2436,8 +2854,9 @@ env_DbRemove(interp, objc, objv, dbenv)
result = TCL_OK;
subdbtmp = NULL;
db = dbr = subdb = subdbr = NULL;
- endarg = nlen = subdblen = 0;
+ endarg = subdblen = 0;
flag = 0;
+ nlen = 0;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args? filename ?database?");
@@ -2538,7 +2957,7 @@ env_DbRemove(interp, objc, objv, dbenv)
* try the dbremove and ignore ENOENT.
*/
if ((db != NULL || subdb != NULL) && ret == 0) {
- /* set up file name for associated recno db for heap*/
+ /* Set up file name for associated recno db for heap. */
if (db != NULL) {
nlen = strlen(db);
if ((ret = __os_malloc(
@@ -2628,8 +3047,9 @@ env_DbRename(interp, objc, objv, dbenv)
result = TCL_OK;
subdbtmp = NULL;
db = dbr = newname = newnamer = subdb = subdbr = NULL;
- endarg = nlen = subdblen = 0;
+ endarg = subdblen = 0;
flag = 0;
+ nlen = 0;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 3, objv,
@@ -2738,7 +3158,7 @@ env_DbRename(interp, objc, objv, dbenv)
* try the dbrename and ignore ENOENT.
*/
if ((db != NULL || subdb != NULL) && ret == 0) {
- /* set up file name for associated recno db for heap*/
+ /* Set up file name for associated recno db for heap. */
if (db != NULL) {
nlen = strlen(db);
if ((ret = __os_malloc(
@@ -2866,7 +3286,7 @@ env_GetFlags(interp, objc, objv, dbenv)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
+ buf, open_flags[i].arg, sizeof(buf) - 1);
}
res = NewStringObj(buf, strlen(buf));
@@ -2932,7 +3352,7 @@ env_GetOpenFlag(interp, objc, objv, dbenv)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, open_flags[i].arg, sizeof(buf));
+ buf, open_flags[i].arg, sizeof(buf) - 1);
}
res = NewStringObj(buf, strlen(buf));
@@ -2984,7 +3404,7 @@ tcl_EnvGetEncryptFlags(interp, objc, objv, dbenv)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, encrypt_flags[i].arg, sizeof(buf));
+ buf, encrypt_flags[i].arg, sizeof(buf) -1);
}
res = NewStringObj(buf, strlen(buf));
@@ -3060,6 +3480,7 @@ env_GetTimeout(interp, objc, objv, dbenv)
char *arg;
} timeout_flags[] = {
{ DB_SET_LOCK_TIMEOUT, "lock" },
+ { DB_SET_MUTEX_FAILCHK_TIMEOUT, "mutex_failchk"},
{ DB_SET_REG_TIMEOUT, "reg" },
{ DB_SET_TXN_TIMEOUT, "txn" },
{ 0, NULL }
@@ -3196,13 +3617,13 @@ tcl_EnvSetErrfile(interp, dbenv, ip, errf)
}
/*
- * PUBLIC: void tcl_EnvSetMsgfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
+ * PUBLIC: int tcl_EnvSetMsgfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *,
* PUBLIC: char *));
*
* tcl_EnvSetMsgfile --
* Implements the ENV->set_msgfile command.
*/
-void
+int
tcl_EnvSetMsgfile(interp, dbenv, ip, msgf)
Tcl_Interp *interp; /* Interpreter */
DB_ENV *dbenv; /* Database pointer */
@@ -3216,14 +3637,52 @@ tcl_EnvSetMsgfile(interp, dbenv, ip, msgf)
if (ip->i_msg != NULL && ip->i_msg != stdout &&
ip->i_msg != stderr)
(void)fclose(ip->i_msg);
- if (strcmp(msgf, "/dev/stdout") == 0)
+ if (strcmp(msgf, "NULL") == 0)
+ ip->i_msg = NULL;
+ else if (strcmp(msgf, "/dev/stdout") == 0)
ip->i_msg = stdout;
else if (strcmp(msgf, "/dev/stderr") == 0)
ip->i_msg = stderr;
else
ip->i_msg = fopen(msgf, "a");
- if (ip->i_msg != NULL)
+ if (strcmp(msgf, "NULL") == 0 || ip->i_msg != NULL) {
dbenv->set_msgfile(dbenv, ip->i_msg);
+ return (TCL_OK);
+ }
+ else
+ return (TCL_ERROR);
+}
+
+/*
+ * PUBLIC: int tcl_EnvCloseMsgfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *));
+ *
+ * tcl_EnvCloseMsgfile --
+ * Implements the ENV->get_msgfile command.
+ */
+int
+tcl_EnvCloseMsgfile(interp, dbenv, ip)
+ Tcl_Interp *interp; /* Interpreter */
+ DB_ENV *dbenv; /* Database pointer */
+ DBTCL_INFO *ip; /* Our internal info */
+{
+ int ret;
+ FILE* msgfile;
+ COMPQUIET(interp, NULL);
+ /*
+ * If the user already set one, free it.
+ */
+ ret = 0;
+ dbenv->get_msgfile(dbenv, &msgfile);
+ if (msgfile != ip->i_msg) {
+ return (TCL_ERROR);
+ }
+ if (msgfile != NULL && msgfile != stdout &&
+ msgfile != stderr) {
+ ret = fclose(msgfile);
+ }
+ ip->i_msg = NULL;
+ dbenv->set_msgfile(dbenv, NULL);
+ return ret;
}
/*
@@ -3281,12 +3740,14 @@ tcl_EnvStatPrint(interp, objc, objv, dbenv)
{
static const char *envstatprtopts[] = {
"-all",
+ "-alloc",
"-clear",
"-subsystem",
NULL
};
enum envstatprtopts {
ENVSTATPRTALL,
+ ENVSTATPRTALLOC,
ENVSTATPRTCLEAR,
ENVSTATPRTSUB
};
@@ -3308,6 +3769,9 @@ tcl_EnvStatPrint(interp, objc, objv, dbenv)
case ENVSTATPRTALL:
flag |= DB_STAT_ALL;
break;
+ case ENVSTATPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case ENVSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
diff --git a/lang/tcl/tcl_internal.c b/lang/tcl/tcl_internal.c
index a358ae99..25f2e48c 100644
--- a/lang/tcl/tcl_internal.c
+++ b/lang/tcl/tcl_internal.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -165,6 +165,9 @@ _DeleteInfo(p)
if (p->i_hashproc != NULL) {
Tcl_DecrRefCount(p->i_hashproc);
}
+ if (p->i_isalive != NULL) {
+ Tcl_DecrRefCount(p->i_isalive);
+ }
if (p->i_part_callback != NULL) {
Tcl_DecrRefCount(p->i_part_callback);
}
@@ -177,6 +180,9 @@ _DeleteInfo(p)
if (p->i_rep_send != NULL) {
Tcl_DecrRefCount(p->i_rep_send);
}
+ if (p->i_rep_view != NULL) {
+ Tcl_DecrRefCount(p->i_rep_view);
+ }
if (p->i_type == I_ENV && p->i_event_info != NULL)
__os_free(NULL, p->i_event_info);
@@ -609,6 +615,7 @@ _EventFunc(dbenv, event, info)
/* Record the fact that this event occurred. */
bit_flag = 1 << event;
ip->i_event_info->events |= bit_flag;
+ ip->i_event_info->count[event]++;
/*
* For events that have associated "info" (currently most don't), save
diff --git a/lang/tcl/tcl_lock.c b/lang/tcl/tcl_lock.c
index 5a06b1a0..847b8aef 100644
--- a/lang/tcl/tcl_lock.c
+++ b/lang/tcl/tcl_lock.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -217,18 +217,31 @@ tcl_LockStat(interp, objc, objv, dbenv)
{
DB_LOCK_STAT *sp;
Tcl_Obj *res;
+ u_int32_t flag;
+ char *arg;
int result, ret;
+ flag = 0;
result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
+
+ if (objc == 3) {
+ arg = Tcl_GetStringFromObj(objv[2], NULL);
+ if (strcmp(arg, "-clear") == 0)
+ flag = DB_STAT_CLEAR;
+ else {
+ Tcl_SetResult(interp,
+ "db stat: unknown arg", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ }
+
_debug_check();
- ret = dbenv->lock_stat(dbenv, &sp, 0);
+ ret = dbenv->lock_stat(dbenv, &sp, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lock stat");
if (result == TCL_ERROR)
return (result);
@@ -237,7 +250,6 @@ tcl_LockStat(interp, objc, objv, dbenv)
* list pairs and free up the memory.
*/
res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
/*
* MAKE_STAT_LIST assumes 'res' and 'error' label.
*/
@@ -266,6 +278,9 @@ tcl_LockStat(interp, objc, objv, dbenv)
sp->st_maxlsteals);
MAKE_STAT_LIST("Current number of lockers", sp->st_nlockers);
MAKE_STAT_LIST("Maximum number of lockers so far", sp->st_maxnlockers);
+ MAKE_STAT_LIST("Number of hits in the thread locker cache",
+ sp->st_nlockers_hit);
+ MAKE_STAT_LIST("Total number of lockers reused", sp->st_nlockers_reused);
MAKE_STAT_LIST("Current number of objects", sp->st_nobjects);
MAKE_STAT_LIST("Maximum number of objects so far", sp->st_maxnobjects);
MAKE_STAT_LIST("Maximum number of objects in any hash bucket",
@@ -304,7 +319,7 @@ tcl_LockStat(interp, objc, objv, dbenv)
sp->st_part_max_wait);
MAKE_STAT_LIST("Maximum number nowaits on any lock partition mutex",
sp->st_part_max_nowait);
-#endif
+
Tcl_SetObjResult(interp, res);
error:
__os_ufree(dbenv->env, sp);
@@ -326,6 +341,7 @@ tcl_LockStatPrint(interp, objc, objv, dbenv)
{
static const char *lkstatprtopts[] = {
"-all",
+ "-alloc",
"-clear",
"-lk_conf",
"-lk_lockers",
@@ -335,6 +351,7 @@ tcl_LockStatPrint(interp, objc, objv, dbenv)
};
enum lkstatprtopts {
LKSTATPRTALL,
+ LKSTATPRTALLOC,
LKSTATPRTCLEAR,
LKSTATPRTCONF,
LKSTATPRTLOCKERS,
@@ -359,6 +376,9 @@ tcl_LockStatPrint(interp, objc, objv, dbenv)
case LKSTATPRTALL:
flag |= DB_STAT_ALL;
break;
+ case LKSTATPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case LKSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
diff --git a/lang/tcl/tcl_log.c b/lang/tcl/tcl_log.c
index 3024f7b1..3331da16 100644
--- a/lang/tcl/tcl_log.c
+++ b/lang/tcl/tcl_log.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -345,18 +345,31 @@ tcl_LogStat(interp, objc, objv, dbenv)
{
DB_LOG_STAT *sp;
Tcl_Obj *res;
+ u_int32_t flag;
+ char *arg;
int result, ret;
+ flag = 0;
result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
+
+ if (objc == 3) {
+ arg = Tcl_GetStringFromObj(objv[2], NULL);
+ if (strcmp(arg, "-clear") == 0)
+ flag = DB_STAT_CLEAR;
+ else {
+ Tcl_SetResult(interp,
+ "db stat: unknown arg", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ }
+
_debug_check();
- ret = dbenv->log_stat(dbenv, &sp, 0);
+ ret = dbenv->log_stat(dbenv, &sp, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log stat");
if (result == TCL_ERROR)
return (result);
@@ -369,7 +382,6 @@ tcl_LogStat(interp, objc, objv, dbenv)
/*
* MAKE_STAT_LIST assumes 'res' and 'error' label.
*/
-#ifdef HAVE_STATISTICS
MAKE_STAT_LIST("Magic", sp->st_magic);
MAKE_STAT_LIST("Log file Version", sp->st_version);
MAKE_STAT_LIST("Region size", sp->st_regsize);
@@ -398,7 +410,7 @@ tcl_LogStat(interp, objc, objv, dbenv)
MAKE_STAT_LIST("Min commits in a log flush", sp->st_mincommitperflush);
MAKE_WSTAT_LIST("Number of region lock waits", sp->st_region_wait);
MAKE_WSTAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
-#endif
+
Tcl_SetObjResult(interp, res);
error:
__os_ufree(dbenv->env, sp);
@@ -417,13 +429,16 @@ tcl_LogStatPrint(interp, objc, objv, dbenv)
int objc; /* How many arguments? */
Tcl_Obj *CONST objv[]; /* The argument objects */
DB_ENV *dbenv; /* Environment pointer */
-{ static const char *logstatprtopts[] = {
+{
+ static const char *logstatprtopts[] = {
"-all",
+ "-alloc",
"-clear",
NULL
};
enum logstatprtopts {
LOGSTATPRTALL,
+ LOGSTATPRTALLOC,
LOGSTATPRTCLEAR
};
u_int32_t flag;
@@ -444,6 +459,9 @@ tcl_LogStatPrint(interp, objc, objv, dbenv)
case LOGSTATPRTALL:
flag |= DB_STAT_ALL;
break;
+ case LOGSTATPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case LOGSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
@@ -464,6 +482,33 @@ error:
}
/*
+ * tcl_LogVerify --
+ *
+ * PUBLIC: int tcl_LogVerify __P((Tcl_Interp *, int,
+ * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
+ */
+int
+tcl_LogVerify(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *dbenv; /* Environment pointer */
+{
+ DB_LOG_VERIFY_CONFIG lvc;
+ int result, ret;
+
+ COMPQUIET(objc, 0);
+ COMPQUIET(objv, NULL);
+ result = TCL_OK;
+ memset(&lvc, 0, sizeof(lvc));
+ _debug_check();
+ ret = dbenv->log_verify(dbenv, &lvc);
+ result = _ReturnSetup(interp,
+ ret, DB_RETOK_STD(ret), "dbenv log_verify");
+ return (result);
+
+}
+/*
* logc_Cmd --
* Implements the log cursor command.
*
@@ -691,17 +736,21 @@ memerr: if (res != NULL) {
static const char *confwhich[] = {
"autoremove",
+ "blob",
"direct",
"dsync",
"inmemory",
+ "nosync",
"zero",
NULL
};
enum logwhich {
LOGCONF_AUTO,
+ LOGCONF_BLOB,
LOGCONF_DIRECT,
LOGCONF_DSYNC,
LOGCONF_INMEMORY,
+ LOGCONF_NOSYNC,
LOGCONF_ZERO
};
@@ -739,6 +788,9 @@ tcl_LogConfig(interp, dbenv, which, onoff)
case LOGCONF_AUTO:
wh = DB_LOG_AUTO_REMOVE;
break;
+ case LOGCONF_BLOB:
+ wh = DB_LOG_BLOB;
+ break;
case LOGCONF_DIRECT:
wh = DB_LOG_DIRECT;
break;
@@ -748,6 +800,9 @@ tcl_LogConfig(interp, dbenv, which, onoff)
case LOGCONF_INMEMORY:
wh = DB_LOG_IN_MEMORY;
break;
+ case LOGCONF_NOSYNC:
+ wh = DB_LOG_NOSYNC;
+ break;
case LOGCONF_ZERO:
wh = DB_LOG_ZERO;
break;
@@ -769,7 +824,7 @@ tcl_LogConfig(interp, dbenv, which, onoff)
}
ret = dbenv->log_set_config(dbenv, wh, on);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env rep_config"));
+ "env log_config"));
}
/*
@@ -798,6 +853,9 @@ tcl_LogGetConfig(interp, dbenv, which)
case LOGCONF_AUTO:
wh = DB_LOG_AUTO_REMOVE;
break;
+ case LOGCONF_BLOB:
+ wh = DB_LOG_BLOB;
+ break;
case LOGCONF_DIRECT:
wh = DB_LOG_DIRECT;
break;
@@ -807,6 +865,9 @@ tcl_LogGetConfig(interp, dbenv, which)
case LOGCONF_INMEMORY:
wh = DB_LOG_IN_MEMORY;
break;
+ case LOGCONF_NOSYNC:
+ wh = DB_LOG_NOSYNC;
+ break;
case LOGCONF_ZERO:
wh = DB_LOG_ZERO;
break;
@@ -821,4 +882,46 @@ tcl_LogGetConfig(interp, dbenv, which)
}
return (result);
}
+
+/*
+ * tcl_LogSetMax --
+ * Call DB_ENV->set_lg_max().
+ * Also delay setting the maximum log if the log buffer size
+ * has already been set, this only applies when setting the
+ * maximum log when opening the environment.
+ *
+ * PUBLIC: int tcl_LogSetMax
+ * PUBLIC: __P((Tcl_Interp *, DB_ENV *,Tcl_Obj *,u_int32_t *,u_int32_t *));
+ */
+int
+tcl_LogSetMax(interp, dbenv, objv, logbufset, logmaxset)
+ Tcl_Interp *interp;
+ DB_ENV *dbenv;
+ Tcl_Obj *objv;
+ u_int32_t *logbufset;
+ u_int32_t *logmaxset;
+{
+ int result, ret;
+ u_int32_t uintarg;
+
+ result = _GetUInt32(interp, objv, &uintarg);
+ /*
+ * If logbufset is NULL it means we're setting it after
+ * the env is opened. If logbufset is not NULL, we're called
+ * from opening the environment and only set if logbufset
+ * has already been set to a value.
+ */
+ if (result == TCL_OK && (logbufset == NULL || (*logbufset) == 0)) {
+ _debug_check();
+ ret = dbenv->set_lg_max(dbenv, uintarg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "log_max");
+ if (logbufset != NULL)
+ *logbufset = 0;
+ } else
+ if (logmaxset != NULL)
+ *logmaxset = uintarg;
+
+ return (result);
+}
#endif
diff --git a/lang/tcl/tcl_mp.c b/lang/tcl/tcl_mp.c
index ba4318da..7e0619dc 100644
--- a/lang/tcl/tcl_mp.c
+++ b/lang/tcl/tcl_mp.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -19,6 +19,8 @@
*/
#ifdef CONFIG_TEST
static int mp_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+static int mp_size_getinput __P((Tcl_Interp *, Tcl_Obj * CONST*, int,
+ u_int32_t *, u_int32_t *));
static int pg_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
static int tcl_MpGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
DB_MPOOLFILE *, DBTCL_INFO *));
@@ -152,35 +154,52 @@ tcl_Mp(interp, objc, objv, dbenv, envip)
DBTCL_INFO *envip; /* Info pointer */
{
static const char *mpopts[] = {
+ "-clear_len",
"-create",
+ "-lsn_offset",
+ "-maxsize",
"-mode",
"-multiversion",
"-nommap",
"-pagesize",
+ "-pgcookie",
"-rdonly",
NULL
};
enum mpopts {
+ MPCLEARLEN,
MPCREATE,
+ MPLSNOFFSET,
+ MPMAXSIZE,
MPMODE,
MPMULTIVERSION,
MPNOMMAP,
MPPAGE,
+ MPPGCOOKIE,
MPRDONLY
};
+ DBT cookie;
DBTCL_INFO *ip;
DB_MPOOLFILE *mpf;
Tcl_Obj *res;
- u_int32_t flag;
- int i, pgsize, mode, optindex, result, ret;
+ u_int32_t bytes, flag, gbytes, len;
+ int32_t offset;
+ int cookiesz, i, mode, optindex, pgsize;
+ int result, ret, setlen, setofs, setsize, value;
char *file, newname[MSG_SIZE];
+ ip = NULL;
+ mpf = NULL;
result = TCL_OK;
i = 2;
flag = 0;
+ bytes = gbytes = len = 0;
+ offset = 0;
mode = 0;
pgsize = 0;
+ ret = setlen = setofs = setsize = value = 0;
memset(newname, 0, MSG_SIZE);
+ memset(&cookie, 0, sizeof(DBT));
while (i < objc) {
if (Tcl_GetIndexFromObj(interp, objv[i],
mpopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
@@ -196,9 +215,41 @@ tcl_Mp(interp, objc, objv, dbenv, envip)
}
i++;
switch ((enum mpopts)optindex) {
+ case MPCLEARLEN:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-clearlen len?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &len);
+ setlen = 1;
+ break;
+ case MPLSNOFFSET:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-lsnoffset offset?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = Tcl_GetIntFromObj(interp, objv[i++], &value);
+ offset = (int32_t)value;
+ setofs = 1;
+ break;
case MPCREATE:
flag |= DB_CREATE;
break;
+ case MPMAXSIZE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-maxsize {gbytes bytes}?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = mp_size_getinput(interp,
+ objv, i++, &gbytes, &bytes);
+ setsize = 1;
+ break;
case MPMODE:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -235,6 +286,16 @@ tcl_Mp(interp, objc, objv, dbenv, envip)
*/
result = Tcl_GetIntFromObj(interp, objv[i++], &pgsize);
break;
+ case MPPGCOOKIE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-pgcookie cookie?");
+ result = TCL_ERROR;
+ break;
+ }
+ cookie.data = Tcl_GetStringFromObj(objv[i++], &cookiesz);
+ cookie.size = (u_int32_t)cookiesz;
+ break;
case MPRDONLY:
flag |= DB_RDONLY;
break;
@@ -265,23 +326,27 @@ tcl_Mp(interp, objc, objv, dbenv, envip)
}
_debug_check();
- if ((ret = dbenv->memp_fcreate(dbenv, &mpf, 0)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mpool");
- _DeleteInfo(ip);
+ if ((ret = dbenv->memp_fcreate(dbenv, &mpf, 0)) != 0)
+ goto error;
+
+ if (setlen != 0 && (ret = mpf->set_clear_len(mpf, len)) != 0)
+ goto error;
+
+ if (setsize != 0 && (ret = mpf->set_maxsize(mpf, gbytes, bytes)) != 0)
+ goto error;
+
+ if (setofs != 0 && (ret = mpf->set_lsn_offset(mpf, offset)) != 0)
+ goto error;
+
+ if (cookie.data != NULL && (ret = mpf->set_pgcookie(mpf, &cookie)) != 0)
goto error;
- }
/*
* XXX
* Interface doesn't currently support DB_MPOOLFILE configuration.
*/
- if ((ret = mpf->open(mpf, file, flag, mode, (size_t)pgsize)) != 0) {
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mpool");
- _DeleteInfo(ip);
-
- (void)mpf->close(mpf, 0);
+ if ((ret = mpf->open(mpf, file, flag, mode, (size_t)pgsize)) != 0)
goto error;
- }
/*
* Success. Set up return. Set up new info and command widget for
@@ -297,6 +362,12 @@ tcl_Mp(interp, objc, objv, dbenv, envip)
Tcl_SetObjResult(interp, res);
error:
+ if (ret != 0) {
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mpool");
+ _DeleteInfo(ip);
+ if (mpf != NULL)
+ (void)mpf->close(mpf, 0);
+ }
return (result);
}
@@ -324,11 +395,9 @@ tcl_MpStat(interp, objc, objv, dbenv)
flag = 0;
result = TCL_OK;
savefsp = NULL;
- /*
- * No args for this. Error if there are some.
- */
+
if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
@@ -354,7 +423,6 @@ tcl_MpStat(interp, objc, objv, dbenv)
* list pairs and free up the memory.
*/
res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
/*
* MAKE_STAT_LIST assumes 'res' and 'error' label.
*/
@@ -378,6 +446,10 @@ tcl_MpStat(interp, objc, objv, dbenv)
MAKE_WSTAT_LIST("Clean page evictions", sp->st_ro_evict);
MAKE_WSTAT_LIST("Dirty page evictions", sp->st_rw_evict);
MAKE_WSTAT_LIST("Dirty pages trickled", sp->st_page_trickle);
+ /* Undocumented field used by tests only. */
+ MAKE_STAT_LIST("Odd file size detected", sp->st_oddfsize_detect);
+ /* Undocumented field used by tests only. */
+ MAKE_STAT_LIST("Odd file size resolved", sp->st_oddfsize_resolve);
MAKE_STAT_LIST("Cached pages", sp->st_pages);
MAKE_WSTAT_LIST("Cached clean pages", sp->st_page_clean);
MAKE_WSTAT_LIST("Cached dirty pages", sp->st_page_dirty);
@@ -398,6 +470,8 @@ tcl_MpStat(interp, objc, objv, dbenv)
MAKE_WSTAT_LIST("Buffers frozen", sp->st_mvcc_frozen);
MAKE_WSTAT_LIST("Buffers thawed", sp->st_mvcc_thawed);
MAKE_WSTAT_LIST("Frozen buffers freed", sp->st_mvcc_freed);
+ MAKE_WSTAT_LIST("The number of outdated intermediate versions reused",
+ sp->st_mvcc_reused);
MAKE_WSTAT_LIST("Page allocations", sp->st_alloc);
MAKE_STAT_LIST("Buckets examined during allocation",
sp->st_alloc_buckets);
@@ -415,6 +489,7 @@ tcl_MpStat(interp, objc, objv, dbenv)
* our per-file sublist.
*/
res1 = res;
+#ifdef HAVE_STATISTICS
for (savefsp = fsp; fsp != NULL && *fsp != NULL; fsp++) {
res = Tcl_NewObj();
MAKE_STAT_STRLIST("File Name", (*fsp)->file_name);
@@ -459,12 +534,14 @@ tcl_MpStatPrint(interp, objc, objv, dbenv)
{
static const char *mpstatprtopts[] = {
"-all",
+ "-alloc",
"-clear",
"-hash",
NULL
};
enum mpstatprtopts {
MPSTATPRTALL,
+ MPSTATPRTALLOC,
MPSTATPRTCLEAR,
MPSTATPRTHASH
};
@@ -486,6 +563,9 @@ tcl_MpStatPrint(interp, objc, objv, dbenv)
case MPSTATPRTALL:
flag |= DB_STAT_ALL;
break;
+ case MPSTATPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case MPSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
@@ -526,8 +606,11 @@ mp_Cmd(clientData, interp, objc, objv)
"get_clear_len",
"get_fileid",
"get_ftype",
+ "get_last_pgno",
"get_lsn_offset",
+ "get_maxsize",
"get_pgcookie",
+ "set_maxsize",
NULL
};
enum mpcmds {
@@ -537,16 +620,20 @@ mp_Cmd(clientData, interp, objc, objv)
MPGETCLEARLEN,
MPGETFILEID,
MPGETFTYPE,
+ MPGETLASTPGNO,
MPGETLSNOFFSET,
- MPGETPGCOOKIE
+ MPGETMAXSIZE,
+ MPGETPGCOOKIE,
+ MPSETMAXSIZE
};
DB_MPOOLFILE *mp;
int cmdindex, ftype, length, result, ret;
DBTCL_INFO *mpip;
- Tcl_Obj *res;
+ Tcl_Obj *res, *myobjv[2];
char *obj_name;
- u_int32_t value;
+ u_int32_t bytes, gbytes, value;
int32_t intval;
+ db_pgno_t pgno;
u_int8_t fileid[DB_FILE_ID_LEN];
DBT cookie;
@@ -608,7 +695,7 @@ mp_Cmd(clientData, interp, objc, objv)
ret = mp->get_clear_len(mp, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"mp get_clear_len")) == TCL_OK)
- res = Tcl_NewIntObj((int)value);
+ res = Tcl_NewLongObj((long)value);
break;
case MPGETFILEID:
if (objc != 2) {
@@ -630,6 +717,16 @@ mp_Cmd(clientData, interp, objc, objv)
"mp get_ftype")) == TCL_OK)
res = Tcl_NewIntObj(ftype);
break;
+ case MPGETLASTPGNO:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = mp->get_last_pgno(mp, &pgno);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "mp get_last_pgno")) == TCL_OK)
+ res = Tcl_NewLongObj((long)pgno);
+ break;
case MPGETLSNOFFSET:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -640,6 +737,19 @@ mp_Cmd(clientData, interp, objc, objv)
"mp get_lsn_offset")) == TCL_OK)
res = Tcl_NewIntObj(intval);
break;
+ case MPGETMAXSIZE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = mp->get_maxsize(mp, &gbytes, &bytes);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "mp get_maxsize")) == TCL_OK) {
+ myobjv[0] = Tcl_NewLongObj((long)gbytes);
+ myobjv[1] = Tcl_NewLongObj((long)bytes);
+ res = Tcl_NewListObj(2, myobjv);
+ }
+ break;
case MPGETPGCOOKIE:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -652,6 +762,21 @@ mp_Cmd(clientData, interp, objc, objv)
res = Tcl_NewByteArrayObj((u_char *)cookie.data,
(int)cookie.size);
break;
+ case MPSETMAXSIZE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?set_maxsize {gbytes bytes}?");
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ if ((result = mp_size_getinput(interp,
+ objv, 2, &gbytes, &bytes)) != TCL_OK)
+ break;
+ ret = mp->set_maxsize(mp, gbytes, bytes);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "set_maxsize")) == TCL_OK)
+ res = Tcl_NewIntObj(ret);
+ break;
}
/*
* Only set result if we have a res. Otherwise, lower
@@ -1018,4 +1143,34 @@ tcl_PgIsset(interp, objc, objv, page, pgip)
Tcl_SetObjResult(interp, res);
return (result);
}
+
+static int
+mp_size_getinput(interp, objv, indx, gbytes, bytes)
+ Tcl_Interp *interp;
+ Tcl_Obj *CONST objv[];
+ int indx;
+ u_int32_t *gbytes, *bytes;
+{
+ Tcl_Obj **myobjv;
+ int myobjc, result;
+
+ if ((result = Tcl_ListObjGetElements(interp, objv[indx],
+ &myobjc, &myobjv)) != TCL_OK)
+ goto error;
+
+ if (myobjc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?set_maxsize {gbytes bytes}?");
+ result = TCL_ERROR;
+ goto error;
+ }
+
+ if ((result = _GetUInt32(interp, myobjv[0], gbytes)) != TCL_OK)
+ goto error;
+
+ result = _GetUInt32(interp, myobjv[1], bytes);
+
+error:
+ return (result);
+}
#endif
diff --git a/lang/tcl/tcl_mutex.c b/lang/tcl/tcl_mutex.c
index 384f91ad..d5e9bc3c 100644
--- a/lang/tcl/tcl_mutex.c
+++ b/lang/tcl/tcl_mutex.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -84,6 +84,40 @@ tcl_Mutex(interp, objc, objv, dbenv)
}
/*
+ * tcl_MutexFailchkTimeout --
+ *
+ * PUBLIC: int tcl_MutexFailchkTimeout __P((Tcl_Interp *, int,
+ * PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
+ */
+int
+tcl_MutexFailchkTimeout(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *dbenv; /* Environment pointer */
+{
+ long timeout;
+ int result, ret;
+
+ /*
+ * One arg, the timeout.
+ */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?timeout?");
+ return (TCL_ERROR);
+ }
+ result = Tcl_GetLongFromObj(interp, objv[2], &timeout);
+ if (result != TCL_OK)
+ return (result);
+ _debug_check();
+ ret = dbenv->set_timeout(dbenv, (u_int32_t)timeout,
+ DB_SET_MUTEX_FAILCHK_TIMEOUT);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "mutex failchk timeout");
+ return (result);
+}
+
+/*
* PUBLIC: int tcl_MutFree __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
* PUBLIC: DB_ENV *));
*
@@ -314,11 +348,13 @@ tcl_MutStatPrint(interp, objc, objv, dbenv)
{
static const char *mutstatprtopts[] = {
"-all",
+ "-alloc",
"-clear",
NULL
};
enum mutstatprtopts {
MUTSTATPRTALL,
+ MUTSTATPRTALLOC,
MUTSTATPRTCLEAR
};
u_int32_t flag;
@@ -339,6 +375,9 @@ tcl_MutStatPrint(interp, objc, objv, dbenv)
case MUTSTATPRTALL:
flag |= DB_STAT_ALL;
break;
+ case MUTSTATPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case MUTSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
diff --git a/lang/tcl/tcl_rep.c b/lang/tcl/tcl_rep.c
index a616cc7c..01710597 100644
--- a/lang/tcl/tcl_rep.c
+++ b/lang/tcl/tcl_rep.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -36,10 +36,13 @@ static const NAMEMAP rep_config_types[] = {
{"autorollback", DB_REP_CONF_AUTOROLLBACK},
{"bulk", DB_REP_CONF_BULK},
{"delayclient", DB_REP_CONF_DELAYCLIENT},
+ {"electloglength", DB_REP_CONF_ELECT_LOGLENGTH},
{"inmem", DB_REP_CONF_INMEM},
{"lease", DB_REP_CONF_LEASE},
{"mgr2sitestrict", DB_REPMGR_CONF_2SITE_STRICT},
{"mgrelections", DB_REPMGR_CONF_ELECTIONS},
+ {"mgrprefmasclient", DB_REPMGR_CONF_PREFMAS_CLIENT},
+ {"mgrprefmasmaster", DB_REPMGR_CONF_PREFMAS_MASTER},
{"nowait", DB_REP_CONF_NOWAIT},
{NULL, 0}
};
@@ -137,6 +140,14 @@ tcl_RepGetTwo(interp, dbenv, op)
case DBTCL_GETCLOCK:
ret = dbenv->rep_get_clockskew(dbenv, &val1, &val2);
break;
+ case DBTCL_GETINQUEUE_MAX:
+ ret = dbenv->repmgr_get_incoming_queue_max(dbenv,
+ &val1, &val2);
+ break;
+ case DBTCL_GETINQUEUE_REDZONE:
+ ret = __repmgr_get_incoming_queue_redzone(dbenv,
+ &val1, &val2);
+ break;
case DBTCL_GETLIMIT:
ret = dbenv->rep_get_limit(dbenv, &val1, &val2);
break;
@@ -456,7 +467,7 @@ tcl_RepLease(interp, objc, objv, dbenv)
if ((result = _GetUInt32(interp, objv[0], &timeout)) != TCL_OK)
return (result);
- if (objc == 4) {
+ if (objc == 3) {
if ((result = _GetUInt32(interp, objv[1], &clock_fast))
!= TCL_OK)
return (result);
@@ -519,14 +530,14 @@ tcl_RepLimit(interp, objc, objv, dbenv)
int result, ret;
u_int32_t bytes, gbytes;
- if (objc != 4) {
+ if (objc != 2) {
Tcl_WrongNumArgs(interp, 2, objv, "gbytes bytes");
return (TCL_ERROR);
}
- if ((result = _GetUInt32(interp, objv[2], &gbytes)) != TCL_OK)
+ if ((result = _GetUInt32(interp, objv[0], &gbytes)) != TCL_OK)
return (result);
- if ((result = _GetUInt32(interp, objv[3], &bytes)) != TCL_OK)
+ if ((result = _GetUInt32(interp, objv[1], &bytes)) != TCL_OK)
return (result);
_debug_check();
@@ -589,14 +600,14 @@ tcl_RepRequest(interp, objc, objv, dbenv)
int result, ret;
long min, max;
- if (objc != 4) {
+ if (objc != 2) {
Tcl_WrongNumArgs(interp, 2, objv, "min max");
return (TCL_ERROR);
}
- if ((result = Tcl_GetLongFromObj(interp, objv[2], &min)) != TCL_OK)
+ if ((result = Tcl_GetLongFromObj(interp, objv[0], &min)) != TCL_OK)
return (result);
- if ((result = Tcl_GetLongFromObj(interp, objv[3], &max)) != TCL_OK)
+ if ((result = Tcl_GetLongFromObj(interp, objv[1], &max)) != TCL_OK)
return (result);
_debug_check();
@@ -944,7 +955,7 @@ tcl_RepStat(interp, objc, objv, dbenv)
result = TCL_OK;
if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
if (objc == 3) {
@@ -970,7 +981,6 @@ tcl_RepStat(interp, objc, objv, dbenv)
* list pairs and free up the memory.
*/
res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
/*
* MAKE_STAT_* assumes 'res' and 'error' label.
*/
@@ -998,6 +1008,7 @@ tcl_RepStat(interp, objc, objv, dbenv)
MAKE_STAT_LIST("Generation number", sp->st_gen);
MAKE_STAT_LIST("Election generation number", sp->st_egen);
MAKE_STAT_LIST("Startup complete", sp->st_startup_complete);
+ MAKE_STAT_LIST("Is view", sp->st_view);
MAKE_WSTAT_LIST("Lease messages sent", sp->st_lease_sends);
MAKE_WSTAT_LIST("Lease checks", sp->st_lease_chk);
MAKE_WSTAT_LIST("Lease check invalid", sp->st_lease_chk_misses);
@@ -1046,8 +1057,10 @@ tcl_RepStat(interp, objc, objv, dbenv)
sp->st_startsync_delayed);
MAKE_STAT_LIST("Maximum lease seconds", sp->st_max_lease_sec);
MAKE_STAT_LIST("Maximum lease usecs", sp->st_max_lease_usec);
+ /* Undocumented field used by tests only. */
MAKE_STAT_LIST("File fail cleanups done", sp->st_filefail_cleanups);
-#endif
+ /* Undocumented field used by tests only. */
+ MAKE_WSTAT_LIST("Future duplicated log records", sp->st_log_futuredup);
Tcl_SetObjResult(interp, res);
error:
@@ -1130,6 +1143,7 @@ tcl_RepMgr(interp, objc, objv, dbenv)
{
static const char *rmgr[] = {
"-ack",
+ "-inqueue",
"-local",
"-msgth",
"-pri",
@@ -1141,6 +1155,7 @@ tcl_RepMgr(interp, objc, objv, dbenv)
};
enum rmgr {
RMGR_ACK,
+ RMGR_INQUEUE,
RMGR_LOCAL,
RMGR_MSGTH,
RMGR_PRI,
@@ -1154,13 +1169,13 @@ tcl_RepMgr(interp, objc, objv, dbenv)
long to;
int ack, creator, i, j, legacy, myobjc, optindex;
int peer, result, ret, totype, t_ret;
- u_int32_t msgth, start_flag, uintarg;
+ u_int32_t call_start, msgth, start_flag, uintarg, uintarg2;
char *arg;
result = TCL_OK;
ack = ret = totype = 0;
msgth = 1;
- start_flag = 0;
+ call_start = start_flag = 0;
if (objc <= 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args?");
@@ -1202,6 +1217,32 @@ tcl_RepMgr(interp, objc, objv, dbenv)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"ack");
break;
+ case RMGR_INQUEUE:
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ if (myobjc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-inqueue {gbytes bytes}?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(myobjv[0], NULL);
+ if ((result = _GetUInt32(interp, myobjv[0], &uintarg))
+ != TCL_OK)
+ break;
+ if ((result = _GetUInt32(interp, myobjv[1], &uintarg2))
+ != TCL_OK)
+ break;
+ _debug_check();
+ ret = dbenv->repmgr_set_incoming_queue_max(dbenv,
+ uintarg, uintarg2);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "repmgr_set_incoming_queue_max");
+ break;
case RMGR_LOCAL:
result = Tcl_ListObjGetElements(interp, objv[i],
&myobjc, &myobjv);
@@ -1370,12 +1411,18 @@ tcl_RepMgr(interp, objc, objv, dbenv)
start_flag = DB_REP_CLIENT;
else if (strcmp(arg, "elect") == 0)
start_flag = DB_REP_ELECTION;
+ else if (strcmp(arg, "none") == 0) {
+ start_flag = 0;
+ call_start = 1;
+ }
else {
Tcl_AddErrorInfo(
interp, "start: illegal state");
result = TCL_ERROR;
break;
}
+ if (start_flag)
+ call_start = 1;
/*
* Some config functions need to be called
* before repmgr_start. So finish parsing all
@@ -1423,7 +1470,7 @@ tcl_RepMgr(interp, objc, objv, dbenv)
* Only call repmgr_start if needed. The user may use this
* call just to reconfigure, change policy, etc.
*/
- if (start_flag != 0 && result == TCL_OK) {
+ if (call_start && result == TCL_OK) {
_debug_check();
ret = dbenv->repmgr_start(dbenv, (int)msgth, start_flag);
result = _ReturnSetup(
@@ -1448,9 +1495,9 @@ tcl_RepMgrSiteList(interp, objc, objv, dbenv)
DB_ENV *dbenv;
{
DB_REPMGR_SITE *sp;
- Tcl_Obj *myobjv[5], *res, *thislist;
+ Tcl_Obj *myobjv[6], *res, *thislist;
u_int count, i;
- char *pr, *st;
+ char *pr, *st, *vw;
int myobjc, result, ret;
result = TCL_OK;
@@ -1483,11 +1530,9 @@ tcl_RepMgrSiteList(interp, objc, objv, dbenv)
st = "disconnected";
else
st = "unknown";
- if (F_ISSET(&sp[i], DB_REPMGR_ISPEER))
- pr = "peer";
- else
- pr = "non-peer";
- MAKE_SITE_LIST(sp[i].eid, sp[i].host, sp[i].port, st, pr);
+ pr = F_ISSET(&sp[i], DB_REPMGR_ISPEER) ? "peer" : "non-peer";
+ vw = F_ISSET(&sp[i], DB_REPMGR_ISVIEW) ? "view" : "participant";
+ MAKE_SITE_LIST(sp[i].eid, sp[i].host, sp[i].port, st, pr, vw);
}
Tcl_SetObjResult(interp, res);
@@ -1520,7 +1565,7 @@ tcl_RepMgrStat(interp, objc, objv, dbenv)
result = TCL_OK;
if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
if (objc == 3) {
@@ -1546,18 +1591,27 @@ tcl_RepMgrStat(interp, objc, objv, dbenv)
* list pairs and free up the memory.
*/
res = Tcl_NewObj();
-#ifdef HAVE_STATISTICS
/*
* MAKE_STAT_* assumes 'res' and 'error' label.
*/
MAKE_WSTAT_LIST("Acknowledgement failures", sp->st_perm_failed);
MAKE_WSTAT_LIST("Messages delayed", sp->st_msgs_queued);
MAKE_WSTAT_LIST("Messages discarded", sp->st_msgs_dropped);
+ MAKE_WSTAT_LIST("Incoming messages size (gbytes)",
+ sp->st_incoming_queue_gbytes);
+ MAKE_WSTAT_LIST("Incoming messages size (bytes)",
+ sp->st_incoming_queue_bytes);
+ MAKE_WSTAT_LIST("Incoming messages discarded",
+ sp->st_incoming_msgs_dropped);
MAKE_WSTAT_LIST("Connections dropped", sp->st_connection_drop);
MAKE_WSTAT_LIST("Failed re-connects", sp->st_connect_fail);
- MAKE_WSTAT_LIST("Election threads", sp->st_elect_threads);
- MAKE_WSTAT_LIST("Max elect threads", sp->st_max_elect_threads);
-#endif
+ MAKE_STAT_LIST("Election threads", sp->st_elect_threads);
+ MAKE_STAT_LIST("Max elect threads", sp->st_max_elect_threads);
+ MAKE_STAT_LIST("Total sites", sp->st_site_total);
+ MAKE_STAT_LIST("View sites", sp->st_site_views);
+ MAKE_STAT_LIST("Participant sites", sp->st_site_participants);
+ MAKE_WSTAT_LIST("Automatic replication process takeovers",
+ sp->st_takeovers);
Tcl_SetObjResult(interp, res);
error:
diff --git a/lang/tcl/tcl_seq.c b/lang/tcl/tcl_seq.c
index 75f59fee..c84123ce 100644
--- a/lang/tcl/tcl_seq.c
+++ b/lang/tcl/tcl_seq.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -77,7 +77,8 @@ seq_Cmd(clientData, interp, objc, objv)
DB_SEQUENCE *seq;
Tcl_Obj *myobjv[2], *res;
db_seq_t min, max;
- int cmdindex, ncache, result, ret;
+ int cmdindex, result, ret;
+ u_int32_t ncache;
Tcl_ResetResult(interp);
seq = (DB_SEQUENCE *)clientData;
@@ -140,7 +141,7 @@ seq_Cmd(clientData, interp, objc, objv)
ret = seq->get_cachesize(seq, &ncache);
if ((result = _ReturnSetup(interp, ret,
DB_RETOK_STD(ret), "sequence get_cachesize")) == TCL_OK)
- res = Tcl_NewIntObj(ncache);
+ res = Tcl_NewIntObj((int)ncache);
break;
case SEQGETDB:
if (objc != 2) {
@@ -203,14 +204,18 @@ tcl_SeqStat(interp, objc, objv, seq)
flag = 0;
if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
+ Tcl_WrongNumArgs(interp, 2, objv, "?-all? ?-clear?");
return (TCL_ERROR);
}
if (objc == 3) {
arg = Tcl_GetStringFromObj(objv[2], NULL);
- if (strcmp(arg, "-clear") == 0)
+ if (strcmp(arg, "-all") == 0) {
+ flag = DB_STAT_ALL;
+ }
+ else if (strcmp(arg, "-clear") == 0) {
flag = DB_STAT_CLEAR;
+ }
else {
Tcl_SetResult(interp,
"db stat: unknown arg", TCL_STATIC);
@@ -266,10 +271,12 @@ tcl_SeqStatPrint(interp, objc, objv, seq)
DB_SEQUENCE *seq; /* Environment pointer */
{
static const char *seqstatprtopts[] = {
+ "-all",
"-clear",
NULL
};
enum seqstatprtopts {
+ SEQSTATPRTALL,
SEQSTATPRTCLEAR
};
u_int32_t flag;
@@ -287,6 +294,9 @@ tcl_SeqStatPrint(interp, objc, objv, seq)
}
i++;
switch ((enum seqstatprtopts)optindex) {
+ case SEQSTATPRTALL:
+ flag |= DB_STAT_ALL;
+ break;
case SEQSTATPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
@@ -422,7 +432,7 @@ tcl_SeqGet(interp, objc, objv, seq)
if ((result = _GetUInt32(interp, objv[objc - 1], &delta)) != TCL_OK)
goto out;
- ret = seq->get(seq, txn, (int32_t)delta, &value, aflag);
+ ret = seq->get(seq, txn, delta, &value, aflag);
result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret), "sequence get");
if (ret == 0) {
res = Tcl_NewWideIntObj((Tcl_WideInt)value);
@@ -459,8 +469,6 @@ tcl_SeqRemove(interp, objc, objv, seq, ip)
txn = NULL;
aflag = 0;
- _DeleteInfo(ip);
-
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
return (TCL_ERROR);
@@ -510,6 +518,7 @@ tcl_SeqRemove(interp, objc, objv, seq, ip)
if (result != TCL_OK)
goto out;
+ _DeleteInfo(ip);
ret = seq->remove(seq, txn, aflag);
result = _ReturnSetup(interp,
ret, DB_RETOK_DBGET(ret), "sequence remove");
@@ -557,7 +566,7 @@ tcl_SeqGetFlags(interp, objc, objv, seq)
if (strlen(buf) > 0)
(void)strncat(buf, " ", sizeof(buf));
(void)strncat(
- buf, seq_flags[i].arg, sizeof(buf));
+ buf, seq_flags[i].arg, sizeof(buf) - 1);
}
res = NewStringObj(buf, strlen(buf));
diff --git a/lang/tcl/tcl_txn.c b/lang/tcl/tcl_txn.c
index e8c69c08..55676da5 100644
--- a/lang/tcl/tcl_txn.c
+++ b/lang/tcl/tcl_txn.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -399,19 +399,31 @@ tcl_TxnStat(interp, objc, objv, dbenv)
DB_TXN_ACTIVE *p;
DB_TXN_STAT *sp;
Tcl_Obj *myobjv[2], *res, *thislist, *lsnlist;
- u_int32_t i;
+ u_int32_t i, flag;
+ char *arg;
int myobjc, result, ret;
+ flag = 0;
result = TCL_OK;
- /*
- * No args for this. Error if there are some.
- */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-clear?");
return (TCL_ERROR);
}
+
+ if (objc == 3) {
+ arg = Tcl_GetStringFromObj(objv[2], NULL);
+ if (strcmp(arg, "-clear") == 0)
+ flag = DB_STAT_CLEAR;
+ else {
+ Tcl_SetResult(interp,
+ "db stat: unknown arg", TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ }
+
_debug_check();
- ret = dbenv->txn_stat(dbenv, &sp, 0);
+ ret = dbenv->txn_stat(dbenv, &sp, flag);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"txn stat");
if (result == TCL_ERROR)
@@ -425,7 +437,6 @@ tcl_TxnStat(interp, objc, objv, dbenv)
/*
* MAKE_STAT_LIST assumes 'res' and 'error' label.
*/
-#ifdef HAVE_STATISTICS
MAKE_STAT_LIST("Region size", sp->st_regsize);
MAKE_STAT_LSN("LSN of last checkpoint", &sp->st_last_ckp);
MAKE_STAT_LIST("Time of last checkpoint", sp->st_time_ckp);
@@ -457,7 +468,7 @@ tcl_TxnStat(interp, objc, objv, dbenv)
break;
}
}
-#endif
+
Tcl_SetObjResult(interp, res);
error:
__os_ufree(dbenv->env, sp);
@@ -479,11 +490,13 @@ tcl_TxnStatPrint(interp, objc, objv, dbenv)
{
static const char *txnprtopts[] = {
"-all",
+ "-alloc",
"-clear",
NULL
};
enum txnprtopts {
TXNPRTALL,
+ TXNPRTALLOC,
TXNPRTCLEAR
};
u_int32_t flag;
@@ -504,6 +517,9 @@ tcl_TxnStatPrint(interp, objc, objv, dbenv)
case TXNPRTALL:
flag |= DB_STAT_ALL;
break;
+ case TXNPRTALLOC:
+ flag |= DB_STAT_ALLOC;
+ break;
case TXNPRTCLEAR:
flag |= DB_STAT_CLEAR;
break;
diff --git a/lang/tcl/tcl_util.c b/lang/tcl/tcl_util.c
index 0e83826f..81f3b7da 100644
--- a/lang/tcl/tcl_util.c
+++ b/lang/tcl/tcl_util.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/