[MDEV-26601] Incorrect use of O_TMPFILE Created: 2021-09-14  Updated: 2021-09-14  Resolved: 2021-09-14

Status: Closed
Project: MariaDB Server
Component/s: Server
Affects Version/s: 10.5.10, 10.4.21
Fix Version/s: 10.4.22, 10.5.13, 10.6.5

Type: Bug Priority: Major
Reporter: Fabian Vogt Assignee: Daniel Black
Resolution: Fixed Votes: 0
Labels: not-10.3
Environment:

openSUSE Tumbleweed


Issue Links:
Problem/Incident
is caused by MDEV-15584 Linux - use O_TMPFILE for create_temp... Closed

 Description   

I noticed this line in mysql.err:

2021-09-13 16:11:44 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)

However, /tmp is a tmpfs which does support O_TMPFILE. The issue is that mysqld calls open incorrectly:

[pid 11696] openat(AT_FDCWD, "/tmp", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC|O_TMPFILE, 0660) = -1 EINVAL
[pid 11696] openat(AT_FDCWD, "/tmp/ibMbcqxC", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600) = 8
[pid 11696] unlink("/tmp/ibMbcqxC")     = 0

Either O_CREAT or O_TMPFILE can be specified, but not both at the same time. This effectively makes the O_TMPFILE support dead code.



 Comments   
Comment by Daniel Black [ 2021-09-14 ]

Thanks Fabian. I never noticed because of the description in https://man7.org/linux/man-pages/man2/open.2.html

Local test:

diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 51a3efa05ad..0f1c6d6b1bc 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -121,7 +121,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
       /* explictly don't use O_EXCL here has it has a different
          meaning with O_TMPFILE
       */
-      if ((file= open(dir, mode | O_TMPFILE | O_CLOEXEC,
+      if ((file= open(dir, (mode & ~O_CREAT) | O_TMPFILE | O_CLOEXEC,
                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) >= 0)
       {
         my_snprintf(to, FN_REFLEN, "%s/#sql/fd=%d", dir, file);

strace: Process 2240978 attached
2021-09-14 19:01:15 0 [Note] InnoDB: Using Linux native AIO
2021-09-14 19:01:15 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2021-09-14 19:01:15 0 [Note] InnoDB: Uses event mutexes
2021-09-14 19:01:15 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2021-09-14 19:01:15 0 [Note] InnoDB: Number of pools: 1
2021-09-14 19:01:15 0 [Note] InnoDB: Using SSE2 crc32 instructions
[pid 2240976] openat(AT_FDCWD, "/tmp", O_RDWR|O_TRUNC|O_CLOEXEC|O_TMPFILE, 0660) = 6
[pid 2240976] openat(AT_FDCWD, "/tmp", O_RDWR|O_TRUNC|O_CLOEXEC|O_TMPFILE, 0660) = 6
[pid 2240976] openat(AT_FDCWD, "/tmp", O_RDWR|O_TRUNC|O_CLOEXEC|O_TMPFILE, 0660) = 6

where /tmp/ is a tmpfs.

Comment by Fabian Vogt [ 2021-09-14 ]

Great!

Thanks Fabian. I never noticed because of the description in https://man7.org/linux/man-pages/man2/open.2.html

Yes, it's really not clear on that topic. I actually did the same error while writing a test program for this, which in some way made it easier for me to spot the bug with strace

Generated at Thu Feb 08 09:46:32 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.