Subject: | please expose set_lg_filemode |
set_lg_filemode makes it possible to explicitly set the permissions of the log.* files generated by the logging subsystem. It turns out that this feature is useful if you have multiple (POSIX) users accessing the same environment, especially if you can't trust their respective umasks.
Here is a patch:
Subject: | set_lg_filemode.diff |
diff -r 7db4dc8e429c BerkeleyDB.pm
--- a/BerkeleyDB.pm Fri Mar 30 09:13:20 2018 -0700
+++ b/BerkeleyDB.pm Fri Mar 30 13:21:49 2018 -0700
@@ -931,6 +931,7 @@
LockDetect => 0,
TxMax => 0,
LogConfig => 0,
+ LogFileMode => undef,
MaxLockers => 0,
MaxLocks => 0,
MaxObjects => 0,
diff -r 7db4dc8e429c BerkeleyDB.pod
--- a/BerkeleyDB.pod Fri Mar 30 09:13:20 2018 -0700
+++ b/BerkeleyDB.pod Fri Mar 30 13:21:49 2018 -0700
@@ -102,6 +102,7 @@
$status = $env->set_lg_dir();
$status = $env->set_lg_bsize();
$status = $env->set_lg_max();
+ $status = $env->set_lg_filemode($octal_mode);
$status = $env->set_data_dir() ;
$status = $env->set_tmp_dir() ;
@@ -177,6 +178,7 @@
[ -LockDetect => number, ]
[ -TxMax => number, ]
[ -LogConfig => number, ]
+ [ -LogFileMode => number, ]
[ -MaxLockers => number, ]
[ -MaxLocks => number, ]
[ -MaxObjects => number, ]
@@ -249,6 +251,11 @@
If present, this parameter is used to configure log options.
+=item -LogFileMode
+
+Overrides the file permissions on C<log.*> files with an explicit
+permission (DB 4.4 and up).
+
=item -MaxLockers
If present, this parameter is used to configure the maximum number of
diff -r 7db4dc8e429c BerkeleyDB.xs
--- a/BerkeleyDB.xs Fri Mar 30 09:13:20 2018 -0700
+++ b/BerkeleyDB.xs Fri Mar 30 13:21:49 2018 -0700
@@ -2615,6 +2615,7 @@
int lk_detect = 0 ;
int tx_max = 0 ;
int log_config = 0 ;
+ int log_filemode = 0 ;
int max_lockers = 0 ;
int max_locks = 0 ;
int max_objects = 0 ;
@@ -2644,6 +2645,7 @@
SetValue_iv(lk_detect, "LockDetect") ;
SetValue_iv(tx_max, "TxMax") ;
SetValue_iv(log_config,"LogConfig") ;
+ SetValue_iv(log_filemode,"LogFileMode") ;
SetValue_iv(max_lockers,"MaxLockers") ;
SetValue_iv(max_locks, "MaxLocks") ;
SetValue_iv(max_objects,"MaxObjects") ;
@@ -2690,6 +2692,8 @@
#ifndef AT_LEAST_DB_4_4
if (thread_count)
softCrash("-ThreadCount needs Berkeley DB 4.4 or better") ;
+ if (log_filemode)
+ softCrash("-LogFileMode needs Berkeley DB 4.4 or better") ;
#endif /* ! AT_LEAST_DB_4_4 */
#ifndef AT_LEAST_DB_4_7
if (log_config)
@@ -2804,6 +2808,13 @@
my_db_strerror(status)));
}
#endif
+#ifdef AT_LEAST_DB_4_4
+ if (status == 0 && log_filemode) {
+ status = env->set_lg_filemode(env, log_filemode) ;
+ Trace(("set_lg_filemode [%04o] returned %s\n", log_filemode,
+ my_db_strerror(status)));
+ }
+#endif
if (status == 0 && cachesize) {
status = env->set_cachesize(env, 0, cachesize, 0) ;
Trace(("set_cachesize [%d] returned %s\n",
@@ -3373,6 +3384,23 @@
RETVAL
int
+set_lg_filemode(env, filemode)
+ BerkeleyDB::Env env
+ u_int32_t filemode
+ PREINIT:
+ dMY_CXT;
+ INIT:
+ ckActive_Database(env->active) ;
+ CODE:
+#ifndef AT_LEAST_DB_4_4
+ softCrash("$env->set_lg_filemode needs Berkeley DB 4.4 or better") ;
+#else
+ RETVAL = env->Status = env->Env->set_lg_filemode(env->Env, filemode);
+#endif
+ OUTPUT:
+ RETVAL
+
+int
set_lg_max(env, lg_max)
BerkeleyDB::Env env
u_int32_t lg_max
diff -r 7db4dc8e429c t/db-4.4.t
--- a/t/db-4.4.t Fri Mar 30 09:13:20 2018 -0700
+++ b/t/db-4.4.t Fri Mar 30 13:21:49 2018 -0700
@@ -10,7 +10,7 @@
plan(skip_all => "this needs Berkeley DB 4.4.x or better\n" )
if $BerkeleyDB::db_version < 4.4;
-plan tests => 5;
+plan tests => 12;
{
title "Testing compact";
@@ -55,3 +55,70 @@
ok $db->compact() == 0, " Compacted ok";
}
+{
+ title "Testing lg_filemode";
+
+ # switch umask
+ my $omask = umask 077;
+
+ use Cwd ;
+ my $cwd = cwd() ;
+ my $home = "$cwd/test-log-perms" ;
+ my $data_file = "data.db" ;
+ ok my $lexD = new LexDir($home) ;
+ my $env = new BerkeleyDB::Env
+ -Home => $home,
+ -LogFileMode => 0641, # something weird
+ -Flags => DB_CREATE|DB_INIT_TXN|DB_INIT_LOG|
+ DB_INIT_MPOOL|DB_INIT_LOCK ;
+ ok $env ;
+
+ # something crazy small
+ #is($env->set_lg_max(1024), 0);
+
+ ok my $txn = $env->txn_begin() ;
+
+ my %hash ;
+ ok tie %hash, 'BerkeleyDB::Hash', -Filename => $data_file,
+ -Flags => DB_CREATE ,
+ -Env => $env,
+ -Txn => $txn ;
+
+
+ $hash{"abc"} = 123 ;
+ $hash{"def"} = 456 ;
+
+ $txn->txn_commit() ;
+
+ ok(my ($log) = glob("$home/log.*"), "log.* file is present");
+
+ SKIP: {
+ skip "POSIX only", 1 if $^O eq 'MSWin32';
+
+ my (undef, undef, $perms) = stat $log;
+
+ is($perms, 0100641, "log perms match");
+ };
+
+ # meh this one is gonna be harder to test because it would entail
+ # spurring the database into generating a second log file
+
+ # $env->set_lg_filemode(0777);
+ # $env->txn_checkpoint(0, 0);
+ # $txn = $env->txn_begin;
+ # $txn->Txn(tied %hash);
+ # for my $i (0..10_000) {
+ # $hash{$i} = $i x 10;
+ # }
+
+ # $txn->txn_commit;
+ # $env->txn_checkpoint(0, 0);
+
+ #diag(`ls -l $home`);
+
+ untie %hash ;
+
+ undef $txn ;
+ undef $env ;
+ umask $omask;
+}