Hide Forgot
Description of problem: gdbm-1.8.0 is 11 years old. 1.8.3 has numerous improvements and is only 9 years old, and using anything newer than 1.8.0 would avoid at least one failure in ruby's test suite: See http://bugzilla.redhat.com/602435#c50 Version-Release number of selected component (if applicable): gdbm-1.8.0-36.el6.x86_64 How reproducible: always Steps to Reproduce: 1. Here's a quick test to demonstrate the problem: ruby -e 'require "gdbm"; gdbm = GDBM.open("x", nil); print gdbm' 2. 3. Actual results: prints a non-nil value and creates a file named "x" Expected results: prints "nil" and does *not* create any file Additional info:
Yes, with gdbm 1.8.3 it works as expected, and with gdmb 1.8.0 it does not. Most flaws fixed in 1.8.3 are also fixed in our 1.8.0, and the diff between our 1.8.0 and 1.8.3 is surprisingly small. Unfortunately this particular bug remains unfixed.
This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unfortunately unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux. If you would like it considered as an exception in the current release, please ask your support representative.
Created attachment 591139 [details] proposed patch used in gdbm-1.8.3 This fix is used in gdbm-1.8.3 and works on the reproducer above. Related changelog comment: * gdbmopen.c: Fix typo; s/GDBM_OPENMASK/GDBM_WRITER/.
Updating Bug summary, since we will rather fix the particular bug instead of rebasing.
Steps to Reproduce: 1. Here's a quick test to demonstrate the problem: ruby -e 'require "gdbm"; gdbm = GDBM.open("x", nil); print gdbm' Actual results: prints a non-nil value and creates a file named "x" Expected results: prints "nil" and does *not* create any file
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2015-0005.html
This change breaks perl test suite.
(In reply to Petr Pisar from comment #25) > This change breaks perl test suite. Can you be more specific?
(In reply to Honza Horak from comment #26) > (In reply to Petr Pisar from comment #25) > > This change breaks perl test suite. > > Can you be more specific? I have not yet investigated it. Rebuilding perl fails with gdbm-1.8.0-37.el6 on x86_64 only. It passes with gdbm-1.8.0-36.el6.
(In reply to Petr Pisar from comment #27) > I have not yet investigated it. Rebuilding perl fails with gdbm-1.8.0-37.el6 > on x86_64 only. It passes with gdbm-1.8.0-36.el6. Please, give us know as soon as you find out more. Thanks.
This Perl code changed behaviour: $ cat gdbmfix #!/usr/bin/perl use strict; use warnings; use GDBM_File; unlink <Op.dbmx*>; my %h; tie(%h, 'GDBM_File', 'Op.dbmx', &GDBM_WRCREAT, 0640) or die "Initialization failed"; $h{'goner1'} = 'snork'; untie(%h); $ ./gdbmfix gdbm store returned -1, errno 0, key "goner1" at ./gdbmfix line 10. The failed line 10 is the "$h{'goner1'} = 'snork';" line. I debugged the gdbm library and the -1 comes from this check at the very beginning of gdbm_store(): /* First check to make sure this guy is a writer. */ if (dbf->read_write != GDBM_WRITER) { gdbm_errno = GDBM_READER_CANT_STORE; return -1; } Debugger show that the dbf->read_write holds value 2 while GDBM_WRITER macro is declared as 1. It looks like the gdbm_open() does not set the database handle is opened for writing: When calling gdbm_open(): Breakpoint 1, gdbm_open (file=0x63f1f0 "Op.dbmx", block_size=0, flags=2, mode=416, fatal_func=0x7ffff7d25420 <Perl_croak_nocontext>) at gdbmopen.c:76 When leaving the gdbm_open(): Breakpoint 2, gdbm_open (file=0x63f1f0 "Op.dbmx", block_size=0, flags=2, mode=416, fatal_func=0x7ffff7d25420 <Perl_croak_nocontext>) at gdbmopen.c:398 398 return dbf; (gdb) p *dbf $6 = {name = 0x62d090 "Op.dbmx", read_write = 2, fast_write = 1, central_free = 0, coalesce_blocks = 0, file_locking = 1, fatal_err = 0x7ffff7d25420 <Perl_croak_nocontext>, desc = 7, header = 0x62a8f0, dir = 0x69b720, bucket_cache = 0x0, cache_size = 0, last_read = -1, bucket = 0x0, bucket_dir = 0, cache_entry = 0x0, header_changed = 0 '\000', directory_changed = 0 '\000', bucket_changed = 0 '\000', second_changed = 0 '\000'} The flags=2 is GDBM_WRCREAT which corresponds to the Perl code.
This is caused by the last hunk of the gdbm patch: diff -up gdbm-1.8.0/gdbmopen.c.gdbmopen gdbm-1.8.0/gdbmopen.c --- gdbm-1.8.0/gdbmopen.c.gdbmopen 2012-06-12 10:08:02.853499099 +0200 +++ gdbm-1.8.0/gdbmopen.c 2012-06-12 10:08:13.620769745 +0200 @@ -129,19 +129,17 @@ gdbm_open (file, block_size, flags, mode dbf->desc = open (dbf->name, O_RDONLY, 0); break; - case GDBM_OPENMASK: + case GDBM_WRITER: dbf->desc = open (dbf->name, O_RDWR, 0); break; case GDBM_NEWDB: dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode); - flags = GDBM_WRITER; need_trunc = TRUE; break; default: dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode); - flags = GDBM_WRITER; ← THIS IS MISSING break;
This update breaks NIS: [root@ladd00 LADD-NIS]# rpm -q gdbm gdbm-1.8.0-37.el6.x86_64 [root@ladd00 LADD-NIS]# make -C /var/yp make: Entering directory `/var/yp' ... gmake[1]: Entering directory `/var/yp/LADD-NIS' Updating auto.daq... makedbm: dbm_store: Success gmake[1]: [auto.daq] Error 1 (ignored) ... [root@ladd00 LADD-NIS]# ls -l /var/yp/LADD-NIS total 268 -rw------- 1 root root 12481 Jan 7 14:11 auto.daq -rw------- 1 root root 12288 Jan 7 14:18 auto.daq~ ... (observe how file auto.daq is not updated, auto.daq~ is left behind instead) K.O.
I reported the regression as bug #1180392.
I concur. I opened up bug 1183180 prior to finding this... and yes since reverting back to gdbm-devel-1.8.0-36.el6.x86_64.rpm ypserv (specifically tools like ypinit and makedbm) works again. With this update, ypserv breaks because it can no longer update it's data in /var/yp/{domain}. This is serious breakage for anyone using ypserv.