mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 17:53:07 +00:00
87b7292aa5
drgn is currently licensed as GPLv3+. Part of the long term vision for drgn is that other projects can use it as a library providing programmatic interfaces for debugger functionality. A more permissive license is better suited to this goal. We decided on LGPLv2.1+ as a good balance between software freedom and permissiveness. All contributors not employed by Meta were contacted via email and consented to the license change. The only exception was the author of commitc4fbf7e589
("libdrgn: fix for compilation error"), who did not respond. That commit reverted a single line of code to one originally written by me in commit640b1c011d
("libdrgn: embed DWARF index in DWARF info cache"). Signed-off-by: Omar Sandoval <osandov@osandov.com>
109 lines
2.5 KiB
C
109 lines
2.5 KiB
C
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
/*
|
|
* QEMU's 9pfs server passes through O_NOATIME from the client. If the server
|
|
* process doesn't have permission to use O_NOATIME (e.g., because it's being
|
|
* run without privileges and it doesn't own the file), then the open will fail.
|
|
* Overlayfs uses O_NOATIME, so overlayfs on top of 9pfs doesn't work. We work
|
|
* around this with this LD_PRELOAD hack to remove O_NOATIME from open() and
|
|
* fcntl() calls.
|
|
*
|
|
* As of QEMU 5.1.0, the 9pfs server falls back to removing O_NOATIME, so this
|
|
* isn't necessary on newer versions.
|
|
*/
|
|
|
|
#include <dlfcn.h>
|
|
#include <fcntl.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#define ORIG(name) ({ \
|
|
static typeof(&name) orig; \
|
|
\
|
|
if (!orig) { \
|
|
void *tmp; \
|
|
\
|
|
tmp = dlsym(RTLD_NEXT, #name); \
|
|
if (!tmp) { \
|
|
fprintf(stderr, "%s\n", dlerror()); \
|
|
abort(); \
|
|
} \
|
|
orig = tmp; \
|
|
} \
|
|
orig; \
|
|
})
|
|
|
|
#ifndef __OPEN_NEEDS_MODE
|
|
/* From glibc fnctl.h. */
|
|
#ifdef __O_TMPFILE
|
|
# define __OPEN_NEEDS_MODE(oflag) \
|
|
(((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
|
|
#else
|
|
# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
|
|
#endif
|
|
#endif
|
|
|
|
#define OPEN_MODE(flags) ({ \
|
|
mode_t mode = 0; \
|
|
\
|
|
if (__OPEN_NEEDS_MODE(flags)) { \
|
|
va_list ap; \
|
|
\
|
|
va_start(ap, flags); \
|
|
mode = va_arg(ap, mode_t); \
|
|
va_end(ap); \
|
|
} \
|
|
mode; \
|
|
})
|
|
|
|
int open(const char *pathname, int flags, ...)
|
|
{
|
|
flags &= ~O_NOATIME;
|
|
return ORIG(open)(pathname, flags, OPEN_MODE(flags));
|
|
}
|
|
|
|
int open64(const char *pathname, int flags, ...)
|
|
{
|
|
flags &= ~O_NOATIME;
|
|
return ORIG(open64)(pathname, flags, OPEN_MODE(flags));
|
|
}
|
|
|
|
int openat(int dirfd, const char *pathname, int flags, ...)
|
|
{
|
|
flags &= ~O_NOATIME;
|
|
return ORIG(openat)(dirfd, pathname, flags, OPEN_MODE(flags));
|
|
}
|
|
|
|
int openat64(int dirfd, const char *pathname, int flags, ...)
|
|
{
|
|
flags &= ~O_NOATIME;
|
|
return ORIG(openat64)(dirfd, pathname, flags, OPEN_MODE(flags));
|
|
}
|
|
|
|
#define FCNTL_ARG(cmd) ({ \
|
|
va_list ap; \
|
|
void *arg; \
|
|
\
|
|
va_start(ap, cmd); \
|
|
arg = va_arg(ap, void *); \
|
|
va_end(ap); \
|
|
if (cmd == F_SETFL) \
|
|
arg = (void *)((uintptr_t)arg & ~O_NOATIME); \
|
|
arg; \
|
|
})
|
|
|
|
int fcntl(int fd, int cmd, ...)
|
|
{
|
|
return ORIG(fcntl)(fd, cmd, FCNTL_ARG(cmd));
|
|
}
|
|
|
|
int fcntl64(int fd, int cmd, ...)
|
|
{
|
|
return ORIG(fcntl64)(fd, cmd, FCNTL_ARG(cmd));
|
|
}
|