Package: libgdbm6
Version: 1.18.1-5
Severity: normal

I think this is a kernel issue, but I'll report against libgdbm6 first to 
have my reasoning checked.

Given this program:

    #include <errno.h>
    #include <gdbm.h>
    int main (int argc, char *args[])
    {
        GDBM_FILE g;
        (void) argc;
        (void) args;

        g = gdbm_open("/tmp/db", 0, GDBM_NEWDB, 0777, NULL);

        gdbm_reorganize(g);
        gdbm_close(g);

        g = gdbm_open("/tmp/db", 0, GDBM_WRCREAT, 0777, 
                NULL);
        printf("opened as %p, %d\n", g, errno);
        if (g)
            gdbm_close(g);
        return 0;
    }

Building via "gcc a.c -lgdbm" and then stracing shows that the second 
gdbm_open() call returns NULL because flock() says EAGAIN (see attachment).

What happens is this:

DB created and locked
    698118 14:52:47.633361 openat(AT_FDCWD, "/tmp/db", O_RDWR|O_CREAT, 0777) = 3
    698118 14:52:47.633570 flock(3, LOCK_EX|LOCK_NB) = 0
Tmp file created and locked
    698118 14:52:47.634086 openat(AT_FDCWD, "/tmp/db.pRQDFD", 
O_RDWR|O_CREAT|O_EXCL, 0600) = 4
    698118 14:52:47.634176 flock(4, LOCK_EX|LOCK_NB) = 0
Tmp file renamed
    698118 14:52:47.635073 rename("/tmp/db.pRQDFD", "/tmp/db") = 0
but OLD file gets unlocked
    698118 14:52:47.635124 flock(3, LOCK_UN) = 0
both files get close()d
    698118 14:52:47.635157 close(3)         = 0
    698118 14:52:47.635736 close(4)         = 0
new file gets opened and fails
    698118 14:52:47.635867 openat(AT_FDCWD, "/tmp/db", O_RDWR|O_CREAT, 0777) = 3
    698118 14:52:47.635949 flock(3, LOCK_EX|LOCK_NB) = -1 EAGAIN (Die Ressource 
ist zur Zeit nicht verfügbar)


IMO the close(4) should drop the lock on the temporary (now renamed to 
target name) file, so the next flock() should work.
(That's why I believe it's a kernel issue.)

Is my reasoning sound, or should libgdbm unlock the new file as well?


I've got a tmpfs here, but that shouldn't matter:

    none on /tmp type tmpfs (rw,relatime,size=4194304k)


Thanks for your patience and help!


-- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable-debug'), (500, 
'testing-debug'), (500, 'unstable'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 5.6.0-2-amd64 (SMP w/8 CPU threads)
Kernel taint flags: TAINT_WARN
Locale: LANG=de_AT.UTF-8, LC_CTYPE=de_AT.UTF-8 (charmap=UTF-8), 
LANGUAGE=de_AT:de
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libgdbm6 depends on:
ii  libc6  2.30-8

libgdbm6 recommends no packages.

Versions of packages libgdbm6 suggests:
ii  gdbm-l10n  1.18.1-5

-- no debconf information

-- 
698118 14:52:47.631034 execve("./a.out", ["./a.out"], 0x7ffe96712530 /* 68 vars 
*/) = 0
698118 14:52:47.631420 brk(NULL)        = 0x5593b18d6000
698118 14:52:47.631493 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Datei 
oder Verzeichnis nicht gefunden)
698118 14:52:47.631758 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) 
= 3
698118 14:52:47.631856 fstat(3, {st_mode=S_IFREG|0644, st_size=215581, ...}) = 0
698118 14:52:47.631910 mmap(NULL, 215581, PROT_READ, MAP_PRIVATE, 3, 0) = 
0x7f0467e75000
698118 14:52:47.631957 close(3)         = 0
698118 14:52:47.632017 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgdbm.so.6", 
O_RDONLY|O_CLOEXEC) = 3
698118 14:52:47.632078 read(3, 
"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\208\0\0\0\0\0\0"..., 832) = 832
698118 14:52:47.632119 fstat(3, {st_mode=S_IFREG|0644, st_size=59416, ...}) = 0
698118 14:52:47.632173 mmap(NULL, 8192, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0467e73000
698118 14:52:47.632242 mmap(NULL, 61496, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 
3, 0) = 0x7f0467e63000
698118 14:52:47.632301 mmap(0x7f0467e66000, 32768, PROT_READ|PROT_EXEC, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f0467e66000
698118 14:52:47.632360 mmap(0x7f0467e6e000, 12288, PROT_READ, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xb000) = 0x7f0467e6e000
698118 14:52:47.632403 mmap(0x7f0467e71000, 8192, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd000) = 0x7f0467e71000
698118 14:52:47.632466 close(3)         = 0
698118 14:52:47.632505 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", 
O_RDONLY|O_CLOEXEC) = 3
698118 14:52:47.632558 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 
o\2\0\0\0\0\0"..., 832) = 832
698118 14:52:47.632607 fstat(3, {st_mode=S_IFREG|0755, st_size=1831600, ...}) = 0
698118 14:52:47.632651 mmap(NULL, 1844568, PROT_READ, 
MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0467ca0000
698118 14:52:47.632724 mmap(0x7f0467cc5000, 1351680, PROT_READ|PROT_EXEC, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f0467cc5000
698118 14:52:47.632769 mmap(0x7f0467e0f000, 303104, PROT_READ, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16f000) = 0x7f0467e0f000
698118 14:52:47.632810 mmap(0x7f0467e59000, 24576, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b8000) = 0x7f0467e59000
698118 14:52:47.632855 mmap(0x7f0467e5f000, 13656, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0467e5f000
698118 14:52:47.632902 close(3)         = 0
698118 14:52:47.632951 mmap(NULL, 12288, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0467c9d000
698118 14:52:47.632992 arch_prctl(ARCH_SET_FS, 0x7f0467c9d740) = 0
698118 14:52:47.633090 mprotect(0x7f0467e59000, 12288, PROT_READ) = 0
698118 14:52:47.633158 mprotect(0x7f0467e71000, 4096, PROT_READ) = 0
698118 14:52:47.633196 mprotect(0x5593b1751000, 4096, PROT_READ) = 0
698118 14:52:47.633235 mprotect(0x7f0467ed2000, 4096, PROT_READ) = 0
698118 14:52:47.633272 munmap(0x7f0467e75000, 215581) = 0
698118 14:52:47.633361 openat(AT_FDCWD, "/tmp/db", O_RDWR|O_CREAT, 0777) = 3
698118 14:52:47.633410 fstat(3, {st_mode=S_IFREG|0755, st_size=16384, ...}) = 0
698118 14:52:47.633493 brk(NULL)        = 0x5593b18d6000
698118 14:52:47.633527 brk(0x5593b18f7000) = 0x5593b18f7000
698118 14:52:47.633570 flock(3, LOCK_EX|LOCK_NB) = 0
698118 14:52:47.633607 ftruncate(3, 0)  = 0
698118 14:52:47.633655 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0
698118 14:52:47.633703 write(3, 
"\317\232W\23\0\20\0\0\0\20\0\0\0\0\0\0\0\20\0\0\t\0\0\0\0\20\0\0\246\0\0\0"...,
 4096) = 4096
698118 14:52:47.633751 write(3, "\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 
\0\0\0\0\0\0\0 \0\0\0\0\0\0"..., 4096) = 4096
698118 14:52:47.633796 write(3, 
"\1\0\0\0\0\0\0\0\0\20\0\0\0\0\0\0\0000\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) 
= 4096
698118 14:52:47.633843 lseek(3, 0, SEEK_END) = 12288
698118 14:52:47.633879 write(3, 
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 
4096
698118 14:52:47.633921 fsync(3)         = 0
698118 14:52:47.633953 fstat(3, {st_mode=S_IFREG|0755, st_size=16384, ...}) = 0
698118 14:52:47.633996 mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 
0) = 0x7f0467ea6000
698118 14:52:47.634050 getpid()         = 698118
698118 14:52:47.634086 openat(AT_FDCWD, "/tmp/db.pRQDFD", 
O_RDWR|O_CREAT|O_EXCL, 0600) = 4
698118 14:52:47.634138 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
698118 14:52:47.634176 flock(4, LOCK_EX|LOCK_NB) = 0
698118 14:52:47.634215 write(4, 
"\317\232W\23\0\20\0\0\0\20\0\0\0\0\0\0\0\20\0\0\t\0\0\0\0\20\0\0\246\0\0\0"...,
 4096) = 4096
698118 14:52:47.634259 write(4, "\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 
\0\0\0\0\0\0\0 \0\0\0\0\0\0"..., 4096) = 4096
698118 14:52:47.634302 write(4, 
"\1\0\0\0\0\0\0\0\0\20\0\0\0\0\0\0\0000\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) 
= 4096
698118 14:52:47.634344 lseek(4, 0, SEEK_END) = 12288
698118 14:52:47.634379 write(4, 
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 
4096
698118 14:52:47.634420 fsync(4)         = 0
698118 14:52:47.634452 fstat(4, {st_mode=S_IFREG|0600, st_size=16384, ...}) = 0
698118 14:52:47.634488 mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 
0) = 0x7f0467ea2000
698118 14:52:47.634589 brk(0x5593b1918000) = 0x5593b1918000
698118 14:52:47.634700 brk(0x5593b1939000) = 0x5593b1939000
698118 14:52:47.634818 brk(0x5593b195a000) = 0x5593b195a000
698118 14:52:47.634880 msync(0x7f0467ea2000, 16384, MS_SYNC|MS_INVALIDATE) = 0
698118 14:52:47.634915 fstat(3, {st_mode=S_IFREG|0755, st_size=16384, ...}) = 0
698118 14:52:47.634955 fchown(4, 1000, 1000) = 0
698118 14:52:47.634996 fchmod(4, 0755)  = 0
698118 14:52:47.635034 munmap(0x7f0467ea6000, 16384) = 0
698118 14:52:47.635073 rename("/tmp/db.pRQDFD", "/tmp/db") = 0
698118 14:52:47.635124 flock(3, LOCK_UN) = 0
698118 14:52:47.635157 close(3)         = 0
698118 14:52:47.635205 brk(0x5593b18fc000) = 0x5593b18fc000
698118 14:52:47.635257 brk(0x5593b18fb000) = 0x5593b18fb000
698118 14:52:47.635293 fstat(4, {st_mode=S_IFREG|0755, st_size=16384, ...}) = 0
698118 14:52:47.635331 mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 
0) = 0x7f0467ea6000
698118 14:52:47.635372 msync(0x7f0467ea6000, 16384, MS_SYNC|MS_INVALIDATE) = 0
698118 14:52:47.635409 brk(0x5593b191c000) = 0x5593b191c000
698118 14:52:47.635515 brk(0x5593b193d000) = 0x5593b193d000
698118 14:52:47.635620 brk(0x5593b195e000) = 0x5593b195e000
698118 14:52:47.635664 msync(0x7f0467ea6000, 16384, MS_SYNC|MS_INVALIDATE) = 0
698118 14:52:47.635697 munmap(0x7f0467ea6000, 16384) = 0
698118 14:52:47.635736 close(4)         = 0
698118 14:52:47.635780 brk(0x5593b18fa000) = 0x5593b18fa000
698118 14:52:47.635832 brk(0x5593b18f9000) = 0x5593b18f9000
698118 14:52:47.635867 openat(AT_FDCWD, "/tmp/db", O_RDWR|O_CREAT, 0777) = 3
698118 14:52:47.635910 fstat(3, {st_mode=S_IFREG|0755, st_size=16384, ...}) = 0
698118 14:52:47.635949 flock(3, LOCK_EX|LOCK_NB) = -1 EAGAIN (Die Ressource ist 
zur Zeit nicht verfügbar)
698118 14:52:47.635992 close(3)         = 0
698118 14:52:47.636042 fstat(1, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
698118 14:52:47.636086 write(1, "opened as (nil), 11\n", 20) = 20
698118 14:52:47.636134 exit_group(0)    = ?
698118 14:52:47.636281 +++ exited with 0 +++

Reply via email to