mirror of https://github.com/xemu-project/xemu.git
linux-user/elfload: Fix pr_pid values in core files
util: Add qemu_close_all_open_fd net/tap: Use qemu_close_all_open_fd -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmawHSsdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8mhQgAlNjO1eeeQmgJvKpk BwXx7NnXi9d8UZCA5EASK9SQVJC3eYIlMayX9byPmZZ6XJaOBRzgIzm612HkKLYn yIqmLb0UhUTT+VKW7Kob/wGslB/PJWSKQ3dvZFaaLMfB6L3BtpwUAFFU5hwkODU/ TS4qici1W+eW7hInNSH5dgA68UGPcfDBEo4ITW91DbTSZRNz9RP4b2Ak+Wgv30Ux 2yEVsP6rBqBSxglbafcywWbYs5sX3EvSUJo4mVm8Ku4zriAf87Y9Da3irpZ4WYgi 02f+/GGAv9kiGbf9jPrQTD0O8tmp4Z6JMWxEOfMsCj+KCT2fHSSqcBHTU3RN0guB uaxx6w== =U5cs -----END PGP SIGNATURE----- Merge tag 'pull-misc-20240805' of https://gitlab.com/rth7680/qemu into staging linux-user/elfload: Fix pr_pid values in core files util: Add qemu_close_all_open_fd net/tap: Use qemu_close_all_open_fd # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmawHSsdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8mhQgAlNjO1eeeQmgJvKpk # BwXx7NnXi9d8UZCA5EASK9SQVJC3eYIlMayX9byPmZZ6XJaOBRzgIzm612HkKLYn # yIqmLb0UhUTT+VKW7Kob/wGslB/PJWSKQ3dvZFaaLMfB6L3BtpwUAFFU5hwkODU/ # TS4qici1W+eW7hInNSH5dgA68UGPcfDBEo4ITW91DbTSZRNz9RP4b2Ak+Wgv30Ux # 2yEVsP6rBqBSxglbafcywWbYs5sX3EvSUJo4mVm8Ku4zriAf87Y9Da3irpZ4WYgi # 02f+/GGAv9kiGbf9jPrQTD0O8tmp4Z6JMWxEOfMsCj+KCT2fHSSqcBHTU3RN0guB # uaxx6w== # =U5cs # -----END PGP SIGNATURE----- # gpg: Signature made Mon 05 Aug 2024 10:30:35 AM AEST # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * tag 'pull-misc-20240805' of https://gitlab.com/rth7680/qemu: net/tap: Use qemu_close_all_open_fd() qemu/osdep: Add excluded fd parameter to qemu_close_all_open_fd() net/tap: Factorize fd closing after forking qemu/osdep: Split qemu_close_all_open_fd() and add fallback qemu/osdep: Move close_all_open_fds() to oslib-posix linux-user/elfload: Fix pr_pid values in core files Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
8db6e33d9b
|
@ -757,6 +757,17 @@ static inline void qemu_reset_optind(void)
|
||||||
|
|
||||||
int qemu_fdatasync(int fd);
|
int qemu_fdatasync(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_close_all_open_fd:
|
||||||
|
*
|
||||||
|
* Close all open file descriptors except the ones supplied in the @skip array
|
||||||
|
*
|
||||||
|
* @skip: ordered array of distinct file descriptors that should not be closed
|
||||||
|
* if any, or NULL.
|
||||||
|
* @nskip: number of entries in the @skip array or 0 if @skip is NULL.
|
||||||
|
*/
|
||||||
|
void qemu_close_all_open_fd(const int *skip, unsigned int nskip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync changes made to the memory mapped file back to the backing
|
* Sync changes made to the memory mapped file back to the backing
|
||||||
* storage. For POSIX compliant systems this will fallback
|
* storage. For POSIX compliant systems this will fallback
|
||||||
|
|
|
@ -4102,8 +4102,7 @@ static void fill_elf_note_phdr(struct elf_phdr *phdr, size_t sz, off_t offset)
|
||||||
bswap_phdr(phdr, 1);
|
bswap_phdr(phdr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_prstatus_note(void *data, const TaskState *ts,
|
static void fill_prstatus_note(void *data, CPUState *cpu, int signr)
|
||||||
CPUState *cpu, int signr)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Because note memory is only aligned to 4, and target_elf_prstatus
|
* Because note memory is only aligned to 4, and target_elf_prstatus
|
||||||
|
@ -4113,7 +4112,7 @@ static void fill_prstatus_note(void *data, const TaskState *ts,
|
||||||
struct target_elf_prstatus prstatus = {
|
struct target_elf_prstatus prstatus = {
|
||||||
.pr_info.si_signo = signr,
|
.pr_info.si_signo = signr,
|
||||||
.pr_cursig = signr,
|
.pr_cursig = signr,
|
||||||
.pr_pid = ts->ts_tid,
|
.pr_pid = get_task_state(cpu)->ts_tid,
|
||||||
.pr_ppid = getppid(),
|
.pr_ppid = getppid(),
|
||||||
.pr_pgrp = getpgrp(),
|
.pr_pgrp = getpgrp(),
|
||||||
.pr_sid = getsid(0),
|
.pr_sid = getsid(0),
|
||||||
|
@ -4428,8 +4427,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
|
||||||
CPU_FOREACH(cpu_iter) {
|
CPU_FOREACH(cpu_iter) {
|
||||||
dptr = fill_note(&hptr, NT_PRSTATUS, "CORE",
|
dptr = fill_note(&hptr, NT_PRSTATUS, "CORE",
|
||||||
sizeof(struct target_elf_prstatus));
|
sizeof(struct target_elf_prstatus));
|
||||||
fill_prstatus_note(dptr, ts, cpu_iter,
|
fill_prstatus_note(dptr, cpu_iter, cpu_iter == cpu ? signr : 0);
|
||||||
cpu_iter == cpu ? signr : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_write(fd, header, data_offset) < 0) {
|
if (dump_write(fd, header, data_offset) < 0) {
|
||||||
|
|
34
net/tap.c
34
net/tap.c
|
@ -385,6 +385,24 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void close_all_fds_after_fork(int excluded_fd)
|
||||||
|
{
|
||||||
|
const int skip_fd[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
|
||||||
|
excluded_fd};
|
||||||
|
unsigned int nskip = ARRAY_SIZE(skip_fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skip_fd must be an ordered array of distinct fds, exclude
|
||||||
|
* excluded_fd if already included in the [STDIN_FILENO - STDERR_FILENO]
|
||||||
|
* range
|
||||||
|
*/
|
||||||
|
if (excluded_fd <= STDERR_FILENO) {
|
||||||
|
nskip--;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_close_all_open_fd(skip_fd, nskip);
|
||||||
|
}
|
||||||
|
|
||||||
static void launch_script(const char *setup_script, const char *ifname,
|
static void launch_script(const char *setup_script, const char *ifname,
|
||||||
int fd, Error **errp)
|
int fd, Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -400,13 +418,7 @@ static void launch_script(const char *setup_script, const char *ifname,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int open_max = sysconf(_SC_OPEN_MAX), i;
|
close_all_fds_after_fork(fd);
|
||||||
|
|
||||||
for (i = 3; i < open_max; i++) {
|
|
||||||
if (i != fd) {
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parg = args;
|
parg = args;
|
||||||
*parg++ = (char *)setup_script;
|
*parg++ = (char *)setup_script;
|
||||||
*parg++ = (char *)ifname;
|
*parg++ = (char *)ifname;
|
||||||
|
@ -490,17 +502,11 @@ static int net_bridge_run_helper(const char *helper, const char *bridge,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int open_max = sysconf(_SC_OPEN_MAX), i;
|
|
||||||
char *fd_buf = NULL;
|
char *fd_buf = NULL;
|
||||||
char *br_buf = NULL;
|
char *br_buf = NULL;
|
||||||
char *helper_cmd = NULL;
|
char *helper_cmd = NULL;
|
||||||
|
|
||||||
for (i = 3; i < open_max; i++) {
|
close_all_fds_after_fork(sv[1]);
|
||||||
if (i != sv[1]) {
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
|
fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
|
||||||
|
|
||||||
if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
|
if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
|
||||||
|
|
|
@ -26,40 +26,6 @@
|
||||||
|
|
||||||
static pid_t the_ppid;
|
static pid_t the_ppid;
|
||||||
|
|
||||||
/*
|
|
||||||
* Close all open file descriptors.
|
|
||||||
*/
|
|
||||||
static void close_all_open_fd(void)
|
|
||||||
{
|
|
||||||
struct dirent *de;
|
|
||||||
int fd, dfd;
|
|
||||||
DIR *dir;
|
|
||||||
|
|
||||||
#ifdef CONFIG_CLOSE_RANGE
|
|
||||||
int r = close_range(0, ~0U, 0);
|
|
||||||
if (!r) {
|
|
||||||
/* Success, no need to try other ways. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dir = opendir("/proc/self/fd");
|
|
||||||
if (!dir) {
|
|
||||||
/* If /proc is not mounted, there is nothing that can be done. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Avoid closing the directory. */
|
|
||||||
dfd = dirfd(dir);
|
|
||||||
|
|
||||||
for (de = readdir(dir); de; de = readdir(dir)) {
|
|
||||||
fd = atoi(de->d_name);
|
|
||||||
if (fd != dfd) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hup_handler(int signal)
|
static void hup_handler(int signal)
|
||||||
{
|
{
|
||||||
/* Check every second if this process has been reparented. */
|
/* Check every second if this process has been reparented. */
|
||||||
|
@ -85,9 +51,8 @@ static int async_teardown_fn(void *arg)
|
||||||
/*
|
/*
|
||||||
* Close all file descriptors that might have been inherited from the
|
* Close all file descriptors that might have been inherited from the
|
||||||
* main qemu process when doing clone, needed to make libvirt happy.
|
* main qemu process when doing clone, needed to make libvirt happy.
|
||||||
* Not using close_range for increased compatibility with older kernels.
|
|
||||||
*/
|
*/
|
||||||
close_all_open_fd();
|
qemu_close_all_open_fd(NULL, 0);
|
||||||
|
|
||||||
/* Set up a handler for SIGHUP and unblock SIGHUP. */
|
/* Set up a handler for SIGHUP and unblock SIGHUP. */
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
|
|
|
@ -807,3 +807,127 @@ int qemu_msync(void *addr, size_t length, int fd)
|
||||||
|
|
||||||
return msync(addr, length, MS_SYNC);
|
return msync(addr, length, MS_SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool qemu_close_all_open_fd_proc(const int *skip, unsigned int nskip)
|
||||||
|
{
|
||||||
|
struct dirent *de;
|
||||||
|
int fd, dfd;
|
||||||
|
DIR *dir;
|
||||||
|
unsigned int skip_start = 0, skip_end = nskip;
|
||||||
|
|
||||||
|
dir = opendir("/proc/self/fd");
|
||||||
|
if (!dir) {
|
||||||
|
/* If /proc is not mounted, there is nothing that can be done. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Avoid closing the directory. */
|
||||||
|
dfd = dirfd(dir);
|
||||||
|
|
||||||
|
for (de = readdir(dir); de; de = readdir(dir)) {
|
||||||
|
bool close_fd = true;
|
||||||
|
|
||||||
|
if (de->d_name[0] == '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fd = atoi(de->d_name);
|
||||||
|
if (fd == dfd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = skip_start; i < skip_end; i++) {
|
||||||
|
if (fd < skip[i]) {
|
||||||
|
/* We are below the next skipped fd, break */
|
||||||
|
break;
|
||||||
|
} else if (fd == skip[i]) {
|
||||||
|
close_fd = false;
|
||||||
|
/* Restrict the range as we found fds matching start/end */
|
||||||
|
if (i == skip_start) {
|
||||||
|
skip_start++;
|
||||||
|
} else if (i == skip_end) {
|
||||||
|
skip_end--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close_fd) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool qemu_close_all_open_fd_close_range(const int *skip,
|
||||||
|
unsigned int nskip,
|
||||||
|
int open_max)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_CLOSE_RANGE
|
||||||
|
int max_fd = open_max - 1;
|
||||||
|
int first = 0, last;
|
||||||
|
unsigned int cur_skip = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Find the start boundary of the range to close */
|
||||||
|
while (cur_skip < nskip && first == skip[cur_skip]) {
|
||||||
|
cur_skip++;
|
||||||
|
first++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the upper boundary of the range to close */
|
||||||
|
last = max_fd;
|
||||||
|
if (cur_skip < nskip) {
|
||||||
|
last = skip[cur_skip] - 1;
|
||||||
|
last = MIN(last, max_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* With the adjustments to the range, we might be done. */
|
||||||
|
if (first > last) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = close_range(first, last, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
first = last + 1;
|
||||||
|
} while (last < max_fd);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qemu_close_all_open_fd_fallback(const int *skip, unsigned int nskip,
|
||||||
|
int open_max)
|
||||||
|
{
|
||||||
|
unsigned int cur_skip = 0;
|
||||||
|
|
||||||
|
/* Fallback */
|
||||||
|
for (int i = 0; i < open_max; i++) {
|
||||||
|
if (cur_skip < nskip && i == skip[cur_skip]) {
|
||||||
|
cur_skip++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
close(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close all open file descriptors.
|
||||||
|
*/
|
||||||
|
void qemu_close_all_open_fd(const int *skip, unsigned int nskip)
|
||||||
|
{
|
||||||
|
int open_max = sysconf(_SC_OPEN_MAX);
|
||||||
|
|
||||||
|
assert(skip != NULL || nskip == 0);
|
||||||
|
|
||||||
|
if (!qemu_close_all_open_fd_close_range(skip, nskip, open_max) &&
|
||||||
|
!qemu_close_all_open_fd_proc(skip, nskip)) {
|
||||||
|
qemu_close_all_open_fd_fallback(skip, nskip, open_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue