mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 06:35:24 +00:00
file: Log closing filedescriptors
EBADF errors are logged as warnings as they normally indicate a double close bug. This patch also provides VIR_MASS_CLOSE helper to be user in the only case of mass close after fork when EBADF should rather be ignored.
This commit is contained in:
parent
461ed4210f
commit
dfd4584317
@ -529,7 +529,7 @@ virExecWithHook(const char *const*argv,
|
||||
continue;
|
||||
if (!keepfd || !virCommandFDIsSet(i, keepfd, keepfd_size)) {
|
||||
tmpfd = i;
|
||||
VIR_FORCE_CLOSE(tmpfd);
|
||||
VIR_MASS_CLOSE(tmpfd);
|
||||
} else if (virSetInherit(i, true) < 0) {
|
||||
virReportSystemError(errno, _("failed to preserve fd %d"), i);
|
||||
goto fork_error;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "configmake.h"
|
||||
#include "memory.h"
|
||||
#include "virterror_internal.h"
|
||||
#include "logging.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||
#define virFileError(code, ...) \
|
||||
@ -42,19 +43,33 @@
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
|
||||
|
||||
int virFileClose(int *fdptr, bool preserve_errno)
|
||||
int virFileClose(int *fdptr, bool preserve_errno, bool ignore_EBADF)
|
||||
{
|
||||
int saved_errno = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (*fdptr >= 0) {
|
||||
if (preserve_errno)
|
||||
saved_errno = errno;
|
||||
rc = close(*fdptr);
|
||||
*fdptr = -1;
|
||||
if (preserve_errno)
|
||||
errno = saved_errno;
|
||||
if (*fdptr < 0)
|
||||
return 0;
|
||||
|
||||
if (preserve_errno)
|
||||
saved_errno = errno;
|
||||
|
||||
rc = close(*fdptr);
|
||||
if (rc < 0) {
|
||||
if (errno == EBADF) {
|
||||
if (!ignore_EBADF)
|
||||
VIR_WARN("Tried to close invalid fd %d", *fdptr);
|
||||
} else {
|
||||
char ebuf[1024] ATTRIBUTE_UNUSED;
|
||||
VIR_DEBUG("Failed to close fd %d: %s",
|
||||
*fdptr, virStrerror(errno, ebuf, sizeof(ebuf)));
|
||||
}
|
||||
} else {
|
||||
VIR_DEBUG("Closed fd %d", *fdptr);
|
||||
}
|
||||
*fdptr = -1;
|
||||
if (preserve_errno)
|
||||
errno = saved_errno;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -33,13 +33,14 @@
|
||||
|
||||
|
||||
/* Don't call these directly - use the macros below */
|
||||
int virFileClose(int *fdptr, bool preserve_errno) ATTRIBUTE_RETURN_CHECK;
|
||||
int virFileClose(int *fdptr, bool preserve_errno, bool ignore_EBADF)
|
||||
ATTRIBUTE_RETURN_CHECK;
|
||||
int virFileFclose(FILE **file, bool preserve_errno) ATTRIBUTE_RETURN_CHECK;
|
||||
FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK;
|
||||
|
||||
/* For use on normal paths; caller must check return value,
|
||||
and failure sets errno per close. */
|
||||
# define VIR_CLOSE(FD) virFileClose(&(FD), false)
|
||||
# define VIR_CLOSE(FD) virFileClose(&(FD), false, false)
|
||||
# define VIR_FCLOSE(FILE) virFileFclose(&(FILE), false)
|
||||
|
||||
/* Wrapper around fdopen that consumes fd on success. */
|
||||
@ -47,9 +48,13 @@ FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK;
|
||||
|
||||
/* For use on cleanup paths; errno is unaffected by close,
|
||||
and no return value to worry about. */
|
||||
# define VIR_FORCE_CLOSE(FD) ignore_value(virFileClose(&(FD), true))
|
||||
# define VIR_FORCE_CLOSE(FD) ignore_value(virFileClose(&(FD), true, false))
|
||||
# define VIR_FORCE_FCLOSE(FILE) ignore_value(virFileFclose(&(FILE), true))
|
||||
|
||||
/* Similar VIR_FORCE_CLOSE() but ignores EBADF errors since they are expected
|
||||
* during mass close after fork(). */
|
||||
# define VIR_MASS_CLOSE(FD) ignore_value(virFileClose(&(FD), true, true))
|
||||
|
||||
/* Opaque type for managing a wrapper around a fd. */
|
||||
struct _virFileWrapperFd;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user