mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 09:17:52 +03: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;
|
continue;
|
||||||
if (!keepfd || !virCommandFDIsSet(i, keepfd, keepfd_size)) {
|
if (!keepfd || !virCommandFDIsSet(i, keepfd, keepfd_size)) {
|
||||||
tmpfd = i;
|
tmpfd = i;
|
||||||
VIR_FORCE_CLOSE(tmpfd);
|
VIR_MASS_CLOSE(tmpfd);
|
||||||
} else if (virSetInherit(i, true) < 0) {
|
} else if (virSetInherit(i, true) < 0) {
|
||||||
virReportSystemError(errno, _("failed to preserve fd %d"), i);
|
virReportSystemError(errno, _("failed to preserve fd %d"), i);
|
||||||
goto fork_error;
|
goto fork_error;
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "configmake.h"
|
#include "configmake.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
#define virFileError(code, ...) \
|
#define virFileError(code, ...) \
|
||||||
@ -42,19 +43,33 @@
|
|||||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
__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 saved_errno = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (*fdptr >= 0) {
|
if (*fdptr < 0)
|
||||||
if (preserve_errno)
|
return 0;
|
||||||
saved_errno = errno;
|
|
||||||
rc = close(*fdptr);
|
if (preserve_errno)
|
||||||
*fdptr = -1;
|
saved_errno = errno;
|
||||||
if (preserve_errno)
|
|
||||||
errno = saved_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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,14 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Don't call these directly - use the macros below */
|
/* 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;
|
int virFileFclose(FILE **file, bool preserve_errno) ATTRIBUTE_RETURN_CHECK;
|
||||||
FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK;
|
FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
/* For use on normal paths; caller must check return value,
|
/* For use on normal paths; caller must check return value,
|
||||||
and failure sets errno per close. */
|
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)
|
# define VIR_FCLOSE(FILE) virFileFclose(&(FILE), false)
|
||||||
|
|
||||||
/* Wrapper around fdopen that consumes fd on success. */
|
/* 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,
|
/* For use on cleanup paths; errno is unaffected by close,
|
||||||
and no return value to worry about. */
|
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))
|
# 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. */
|
/* Opaque type for managing a wrapper around a fd. */
|
||||||
struct _virFileWrapperFd;
|
struct _virFileWrapperFd;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user