mirror of https://github.com/containers/podman.git
rootless: add fallback for renameat2 at runtime
the renameat2 syscall might be defined in the C library but lacking support in the kernel. In such case, let it fallback to open(O_CREAT)+rename as it does on systems lacking the definition for renameat2. Closes: https://github.com/containers/libpod/issues/4570 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
5c3af009c6
commit
a94e625868
|
@ -19,24 +19,31 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int rename_noreplace (int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
# ifdef SYS_renameat2
|
||||||
# ifndef RENAME_NOREPLACE
|
# ifndef RENAME_NOREPLACE
|
||||||
# define RENAME_NOREPLACE (1 << 0)
|
# define RENAME_NOREPLACE (1 << 0)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
ret = (int) syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
|
||||||
|
if (ret == 0 || errno != EINVAL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Fallback in case of errno==EINVAL. */
|
||||||
|
# endif
|
||||||
|
|
||||||
int renameat2 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags)
|
|
||||||
{
|
|
||||||
# ifdef SYS_renameat2
|
|
||||||
return (int) syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
|
|
||||||
# else
|
|
||||||
/* This might be an issue if another process is trying to read the file while it is empty. */
|
/* This might be an issue if another process is trying to read the file while it is empty. */
|
||||||
int fd = open (newpath, O_EXCL|O_CREAT, 0700);
|
ret = open (newpath, O_EXCL|O_CREAT, 0700);
|
||||||
if (fd < 0)
|
if (ret < 0)
|
||||||
return fd;
|
return ret;
|
||||||
close (fd);
|
close (ret);
|
||||||
|
|
||||||
/* We are sure we created the file, let's overwrite it. */
|
/* We are sure we created the file, let's overwrite it. */
|
||||||
return rename (oldpath, newpath);
|
return rename (oldpath, newpath);
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TEMP_FAILURE_RETRY
|
#ifndef TEMP_FAILURE_RETRY
|
||||||
#define TEMP_FAILURE_RETRY(expression) \
|
#define TEMP_FAILURE_RETRY(expression) \
|
||||||
|
@ -453,7 +460,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
|
||||||
|
|
||||||
/* There can be another process at this point trying to configure the user namespace and the pause
|
/* There can be another process at this point trying to configure the user namespace and the pause
|
||||||
process, do not override the pid file if it already exists. */
|
process, do not override the pid file if it already exists. */
|
||||||
if (renameat2 (AT_FDCWD, tmp_file_path, AT_FDCWD, pause_pid_file_path, RENAME_NOREPLACE) < 0)
|
if (rename_noreplace (AT_FDCWD, tmp_file_path, AT_FDCWD, pause_pid_file_path) < 0)
|
||||||
{
|
{
|
||||||
unlink (tmp_file_path);
|
unlink (tmp_file_path);
|
||||||
kill (pid, SIGKILL);
|
kill (pid, SIGKILL);
|
||||||
|
|
Loading…
Reference in New Issue