mirror of https://gitee.com/openkylin/libvirt.git
util: Generalize virFileDirectFd
virFileDirectFd was used for accessing files opened with O_DIRECT using libvirt_iohelper. We will want to use the helper for accessing files regardless on O_DIRECT and thus virFileDirectFd was generalized and renamed to virFileWrapperFd.
This commit is contained in:
parent
faad9648cf
commit
afe6e58aed
|
@ -2521,7 +2521,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom,
|
||||||
unsigned long long pad;
|
unsigned long long pad;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int directFlag = 0;
|
int directFlag = 0;
|
||||||
virFileDirectFdPtr directFd = NULL;
|
virFileWrapperFdPtr wrapperFd = NULL;
|
||||||
bool bypass_cache = flags & VIR_DOMAIN_SAVE_BYPASS_CACHE;
|
bool bypass_cache = flags & VIR_DOMAIN_SAVE_BYPASS_CACHE;
|
||||||
|
|
||||||
if (qemuProcessAutoDestroyActive(driver, vm)) {
|
if (qemuProcessAutoDestroyActive(driver, vm)) {
|
||||||
|
@ -2625,7 +2625,9 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom,
|
||||||
&needUnlink, &bypassSecurityDriver);
|
&needUnlink, &bypassSecurityDriver);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
if (bypass_cache && (directFd = virFileDirectFdNew(&fd, path)) == NULL)
|
if (bypass_cache &&
|
||||||
|
!(wrapperFd = virFileWrapperFdNew(&fd, path,
|
||||||
|
VIR_FILE_WRAPPER_BYPASS_CACHE)))
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
/* Write header to file, followed by XML */
|
/* Write header to file, followed by XML */
|
||||||
|
@ -2644,14 +2646,14 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom,
|
||||||
/* Touch up file header to mark image complete. */
|
/* Touch up file header to mark image complete. */
|
||||||
if (bypass_cache) {
|
if (bypass_cache) {
|
||||||
/* Reopen the file to touch up the header, since we aren't set
|
/* Reopen the file to touch up the header, since we aren't set
|
||||||
* up to seek backwards on directFd. The reopened fd will
|
* up to seek backwards on wrapperFd. The reopened fd will
|
||||||
* trigger a single page of file system cache pollution, but
|
* trigger a single page of file system cache pollution, but
|
||||||
* that's acceptable. */
|
* that's acceptable. */
|
||||||
if (VIR_CLOSE(fd) < 0) {
|
if (VIR_CLOSE(fd) < 0) {
|
||||||
virReportSystemError(errno, _("unable to close %s"), path);
|
virReportSystemError(errno, _("unable to close %s"), path);
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
if (virFileDirectFdClose(directFd) < 0)
|
if (virFileWrapperFdClose(wrapperFd) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
fd = qemuOpenFile(driver, path, O_WRONLY, NULL, NULL);
|
fd = qemuOpenFile(driver, path, O_WRONLY, NULL, NULL);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
@ -2703,7 +2705,7 @@ endjob:
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
virFileDirectFdFree(directFd);
|
virFileWrapperFdFree(wrapperFd);
|
||||||
VIR_FREE(xml);
|
VIR_FREE(xml);
|
||||||
if (ret != 0 && needUnlink)
|
if (ret != 0 && needUnlink)
|
||||||
unlink(path);
|
unlink(path);
|
||||||
|
@ -2939,7 +2941,7 @@ doCoreDump(struct qemud_driver *driver,
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virFileDirectFdPtr directFd = NULL;
|
virFileWrapperFdPtr wrapperFd = NULL;
|
||||||
int directFlag = 0;
|
int directFlag = 0;
|
||||||
|
|
||||||
/* Create an empty file with appropriate ownership. */
|
/* Create an empty file with appropriate ownership. */
|
||||||
|
@ -2959,7 +2961,9 @@ doCoreDump(struct qemud_driver *driver,
|
||||||
NULL, NULL)) < 0)
|
NULL, NULL)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (bypass_cache && (directFd = virFileDirectFdNew(&fd, path)) == NULL)
|
if (bypass_cache &&
|
||||||
|
!(wrapperFd = virFileWrapperFdNew(&fd, path,
|
||||||
|
VIR_FILE_WRAPPER_BYPASS_CACHE)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuMigrationToFile(driver, vm, fd, 0, path,
|
if (qemuMigrationToFile(driver, vm, fd, 0, path,
|
||||||
|
@ -2973,14 +2977,14 @@ doCoreDump(struct qemud_driver *driver,
|
||||||
path);
|
path);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (virFileDirectFdClose(directFd) < 0)
|
if (virFileWrapperFdClose(wrapperFd) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
virFileDirectFdFree(directFd);
|
virFileWrapperFdFree(wrapperFd);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
unlink(path);
|
unlink(path);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3926,7 +3930,8 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver,
|
||||||
const char *path,
|
const char *path,
|
||||||
virDomainDefPtr *ret_def,
|
virDomainDefPtr *ret_def,
|
||||||
struct qemud_save_header *ret_header,
|
struct qemud_save_header *ret_header,
|
||||||
bool bypass_cache, virFileDirectFdPtr *directFd,
|
bool bypass_cache,
|
||||||
|
virFileWrapperFdPtr *wrapperFd,
|
||||||
const char *xmlin, int state, bool edit,
|
const char *xmlin, int state, bool edit,
|
||||||
bool unlink_corrupt)
|
bool unlink_corrupt)
|
||||||
{
|
{
|
||||||
|
@ -3948,7 +3953,9 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver,
|
||||||
|
|
||||||
if ((fd = qemuOpenFile(driver, path, oflags, NULL, NULL)) < 0)
|
if ((fd = qemuOpenFile(driver, path, oflags, NULL, NULL)) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
if (bypass_cache && (*directFd = virFileDirectFdNew(&fd, path)) == NULL)
|
if (bypass_cache &&
|
||||||
|
!(*wrapperFd = virFileWrapperFdNew(&fd, path,
|
||||||
|
VIR_FILE_WRAPPER_BYPASS_CACHE)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
|
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
|
||||||
|
@ -4187,7 +4194,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct qemud_save_header header;
|
struct qemud_save_header header;
|
||||||
virFileDirectFdPtr directFd = NULL;
|
virFileWrapperFdPtr wrapperFd = NULL;
|
||||||
int state = -1;
|
int state = -1;
|
||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
||||||
|
@ -4203,7 +4210,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
|
|
||||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
|
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
|
||||||
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
|
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
|
||||||
&directFd, dxml, state, false, false);
|
&wrapperFd, dxml, state, false, false);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -4223,7 +4230,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
|
|
||||||
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
|
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
|
||||||
false);
|
false);
|
||||||
if (virFileDirectFdClose(directFd) < 0)
|
if (virFileWrapperFdClose(wrapperFd) < 0)
|
||||||
VIR_WARN("Failed to close %s", path);
|
VIR_WARN("Failed to close %s", path);
|
||||||
|
|
||||||
if (qemuDomainObjEndJob(driver, vm) == 0)
|
if (qemuDomainObjEndJob(driver, vm) == 0)
|
||||||
|
@ -4236,7 +4243,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||||
cleanup:
|
cleanup:
|
||||||
virDomainDefFree(def);
|
virDomainDefFree(def);
|
||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
virFileDirectFdFree(directFd);
|
virFileWrapperFdFree(wrapperFd);
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
qemuDriverUnlock(driver);
|
qemuDriverUnlock(driver);
|
||||||
|
@ -4364,10 +4371,10 @@ qemuDomainObjRestore(virConnectPtr conn,
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct qemud_save_header header;
|
struct qemud_save_header header;
|
||||||
virFileDirectFdPtr directFd = NULL;
|
virFileWrapperFdPtr wrapperFd = NULL;
|
||||||
|
|
||||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
|
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
|
||||||
bypass_cache, &directFd, NULL, -1, false,
|
bypass_cache, &wrapperFd, NULL, -1, false,
|
||||||
true);
|
true);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (fd == -3)
|
if (fd == -3)
|
||||||
|
@ -4394,13 +4401,13 @@ qemuDomainObjRestore(virConnectPtr conn,
|
||||||
|
|
||||||
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
|
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
|
||||||
start_paused);
|
start_paused);
|
||||||
if (virFileDirectFdClose(directFd) < 0)
|
if (virFileWrapperFdClose(wrapperFd) < 0)
|
||||||
VIR_WARN("Failed to close %s", path);
|
VIR_WARN("Failed to close %s", path);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virDomainDefFree(def);
|
virDomainDefFree(def);
|
||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
virFileDirectFdFree(directFd);
|
virFileWrapperFdFree(wrapperFd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,12 +94,6 @@ FILE *virFileFdopen(int *fdptr, const char *mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opaque type for managing a wrapper around an O_DIRECT fd. For now,
|
|
||||||
* read-write is not supported, just a single direction. */
|
|
||||||
struct _virFileDirectFd {
|
|
||||||
virCommandPtr cmd; /* Child iohelper process to do the I/O. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virFileDirectFdFlag:
|
* virFileDirectFdFlag:
|
||||||
*
|
*
|
||||||
|
@ -116,36 +110,62 @@ virFileDirectFdFlag(void)
|
||||||
return O_DIRECT ? O_DIRECT : -1;
|
return O_DIRECT ? O_DIRECT : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opaque type for managing a wrapper around a fd. For now,
|
||||||
|
* read-write is not supported, just a single direction. */
|
||||||
|
struct _virFileWrapperFd {
|
||||||
|
virCommandPtr cmd; /* Child iohelper process to do the I/O. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
/**
|
/**
|
||||||
* virFileDirectFdNew:
|
* virFileWrapperFdNew:
|
||||||
* @fd: pointer to fd to wrap
|
* @fd: pointer to fd to wrap
|
||||||
* @name: name of fd, for diagnostics
|
* @name: name of fd, for diagnostics
|
||||||
|
* @flags: bitwise-OR of virFileWrapperFdFlags
|
||||||
*
|
*
|
||||||
* Update *FD (created with virFileDirectFdFlag() among the flags to
|
* Update @fd so that it meets parameters requested by @flags.
|
||||||
* open()) to ensure that all I/O to that file will bypass the system
|
*
|
||||||
* cache. This must be called after open() and optional fchown() or
|
* If VIR_FILE_WRAPPER_BYPASS_CACHE bit is set in @flags, @fd will be updated
|
||||||
* fchmod(), but before any seek or I/O, and only on seekable fd. The
|
* in a way that all I/O to that file will bypass the system cache. The
|
||||||
* file must be O_RDONLY (to read the entire existing file) or
|
* original fd must have been created with virFileDirectFdFlag() among the
|
||||||
* O_WRONLY (to write to an empty file). In some cases, *FD is
|
* flags to open().
|
||||||
* changed to a non-seekable pipe; in this case, the caller must not
|
*
|
||||||
* do anything further with the original fd.
|
* If VIR_FILE_WRAPPER_NON_BLOCKING bit is set in @flags, @fd will be updated
|
||||||
|
* to ensure it properly supports non-blocking I/O, i.e., it will report
|
||||||
|
* EAGAIN.
|
||||||
|
*
|
||||||
|
* This must be called after open() and optional fchown() or fchmod(), but
|
||||||
|
* before any seek or I/O, and only on seekable fd. The file must be O_RDONLY
|
||||||
|
* (to read the entire existing file) or O_WRONLY (to write to an empty file).
|
||||||
|
* In some cases, @fd is changed to a non-seekable pipe; in this case, the
|
||||||
|
* caller must not do anything further with the original fd.
|
||||||
*
|
*
|
||||||
* On success, the new wrapper object is returned, which must be later
|
* On success, the new wrapper object is returned, which must be later
|
||||||
* freed with virFileDirectFdFree(). On failure, *FD is unchanged, an
|
* freed with virFileWrapperFdFree(). On failure, @fd is unchanged, an
|
||||||
* error message is output, and NULL is returned.
|
* error message is output, and NULL is returned.
|
||||||
*/
|
*/
|
||||||
virFileDirectFdPtr
|
virFileWrapperFdPtr
|
||||||
virFileDirectFdNew(int *fd, const char *name)
|
virFileWrapperFdNew(int *fd, const char *name, unsigned int flags)
|
||||||
{
|
{
|
||||||
virFileDirectFdPtr ret = NULL;
|
virFileWrapperFdPtr ret = NULL;
|
||||||
bool output = false;
|
bool output = false;
|
||||||
int pipefd[2] = { -1, -1 };
|
int pipefd[2] = { -1, -1 };
|
||||||
int mode = -1;
|
int mode = -1;
|
||||||
|
|
||||||
/* XXX support posix_fadvise rather than spawning a child, if the
|
if (!flags) {
|
||||||
* kernel support for that is decent enough. */
|
virFileError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("invalid use with no flags"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!O_DIRECT) {
|
/* XXX support posix_fadvise rather than O_DIRECT, if the kernel support
|
||||||
|
* for that is decent enough. In that case, we will also need to
|
||||||
|
* explicitly support VIR_FILE_WRAPPER_NON_BLOCKING since
|
||||||
|
* VIR_FILE_WRAPPER_BYPASS_CACHE alone will no longer require spawning
|
||||||
|
* iohelper.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((flags & VIR_FILE_WRAPPER_BYPASS_CACHE) && !O_DIRECT) {
|
||||||
virFileError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virFileError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("O_DIRECT unsupported on this platform"));
|
_("O_DIRECT unsupported on this platform"));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -156,12 +176,7 @@ virFileDirectFdNew(int *fd, const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef F_GETFL
|
|
||||||
/* Mingw lacks F_GETFL, but it also lacks O_DIRECT so didn't get
|
|
||||||
* here in the first place. All other platforms reach this
|
|
||||||
* line. */
|
|
||||||
mode = fcntl(*fd, F_GETFL);
|
mode = fcntl(*fd, F_GETFL);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mode < 0) {
|
if (mode < 0) {
|
||||||
virFileError(VIR_ERR_INTERNAL_ERROR, _("invalid fd %d for %s"),
|
virFileError(VIR_ERR_INTERNAL_ERROR, _("invalid fd %d for %s"),
|
||||||
|
@ -208,48 +223,59 @@ virFileDirectFdNew(int *fd, const char *name)
|
||||||
error:
|
error:
|
||||||
VIR_FORCE_CLOSE(pipefd[0]);
|
VIR_FORCE_CLOSE(pipefd[0]);
|
||||||
VIR_FORCE_CLOSE(pipefd[1]);
|
VIR_FORCE_CLOSE(pipefd[1]);
|
||||||
virFileDirectFdFree(ret);
|
virFileWrapperFdFree(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
virFileWrapperFdPtr
|
||||||
|
virFileWrapperFdNew(int *fd ATTRIBUTE_UNUSED,
|
||||||
|
const char *name ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int fdflags ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virFileError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("virFileWrapperFd unsupported on this platform"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virFileDirectFdClose:
|
* virFileWrapperFdClose:
|
||||||
* @dfd: direct fd wrapper, or NULL
|
* @wfd: fd wrapper, or NULL
|
||||||
*
|
*
|
||||||
* If DFD is valid, then ensure that I/O has completed, which may
|
* If @wfd is valid, then ensure that I/O has completed, which may
|
||||||
* include reaping a child process. Return 0 if all data for the
|
* include reaping a child process. Return 0 if all data for the
|
||||||
* wrapped fd is complete, or -1 on failure with an error emitted.
|
* wrapped fd is complete, or -1 on failure with an error emitted.
|
||||||
* This function intentionally returns 0 when DFD is NULL, so that
|
* This function intentionally returns 0 when @wfd is NULL, so that
|
||||||
* callers can conditionally create a virFileDirectFd wrapper but
|
* callers can conditionally create a virFileWrapperFd wrapper but
|
||||||
* unconditionally call the cleanup code. To avoid deadlock, only
|
* unconditionally call the cleanup code. To avoid deadlock, only
|
||||||
* call this after closing the fd resulting from virFileDirectFdNew().
|
* call this after closing the fd resulting from virFileWrapperFdNew().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virFileDirectFdClose(virFileDirectFdPtr dfd)
|
virFileWrapperFdClose(virFileWrapperFdPtr wfd)
|
||||||
{
|
{
|
||||||
if (!dfd)
|
if (!wfd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return virCommandWait(dfd->cmd, NULL);
|
return virCommandWait(wfd->cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virFileDirectFdFree:
|
* virFileWrapperFdFree:
|
||||||
* @dfd: direct fd wrapper, or NULL
|
* @wfd: fd wrapper, or NULL
|
||||||
*
|
*
|
||||||
* Free all remaining resources associated with DFD. If
|
* Free all remaining resources associated with @wfd. If
|
||||||
* virFileDirectFdClose() was not previously called, then this may
|
* virFileWrapperFdClose() was not previously called, then this may
|
||||||
* discard some previous I/O. To avoid deadlock, only call this after
|
* discard some previous I/O. To avoid deadlock, only call this after
|
||||||
* closing the fd resulting from virFileDirectFdNew().
|
* closing the fd resulting from virFileWrapperFdNew().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
virFileDirectFdFree(virFileDirectFdPtr dfd)
|
virFileWrapperFdFree(virFileWrapperFdPtr wfd)
|
||||||
{
|
{
|
||||||
if (!dfd)
|
if (!wfd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
virCommandFree(dfd->cmd);
|
virCommandFree(wfd->cmd);
|
||||||
VIR_FREE(dfd);
|
VIR_FREE(wfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,20 +50,27 @@ FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK;
|
||||||
# define VIR_FORCE_CLOSE(FD) ignore_value(virFileClose(&(FD), true))
|
# define VIR_FORCE_CLOSE(FD) ignore_value(virFileClose(&(FD), true))
|
||||||
# define VIR_FORCE_FCLOSE(FILE) ignore_value(virFileFclose(&(FILE), true))
|
# define VIR_FORCE_FCLOSE(FILE) ignore_value(virFileFclose(&(FILE), true))
|
||||||
|
|
||||||
/* Opaque type for managing a wrapper around an O_DIRECT fd. */
|
/* Opaque type for managing a wrapper around a fd. */
|
||||||
struct _virFileDirectFd;
|
struct _virFileWrapperFd;
|
||||||
|
|
||||||
typedef struct _virFileDirectFd virFileDirectFd;
|
typedef struct _virFileWrapperFd virFileWrapperFd;
|
||||||
typedef virFileDirectFd *virFileDirectFdPtr;
|
typedef virFileWrapperFd *virFileWrapperFdPtr;
|
||||||
|
|
||||||
int virFileDirectFdFlag(void);
|
int virFileDirectFdFlag(void);
|
||||||
|
|
||||||
virFileDirectFdPtr virFileDirectFdNew(int *fd, const char *name)
|
enum {
|
||||||
|
VIR_FILE_WRAPPER_BYPASS_CACHE = (1 << 0),
|
||||||
|
VIR_FILE_WRAPPER_NON_BLOCKING = (1 << 1),
|
||||||
|
} virFileWrapperFdFlags;
|
||||||
|
|
||||||
|
virFileWrapperFdPtr virFileWrapperFdNew(int *fd,
|
||||||
|
const char *name,
|
||||||
|
unsigned int flags)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
int virFileDirectFdClose(virFileDirectFdPtr dfd);
|
int virFileWrapperFdClose(virFileWrapperFdPtr dfd);
|
||||||
|
|
||||||
void virFileDirectFdFree(virFileDirectFdPtr dfd);
|
void virFileWrapperFdFree(virFileWrapperFdPtr dfd);
|
||||||
|
|
||||||
int virFileLock(int fd, bool shared, off_t start, off_t len);
|
int virFileLock(int fd, bool shared, off_t start, off_t len);
|
||||||
int virFileUnlock(int fd, off_t start, off_t len);
|
int virFileUnlock(int fd, off_t start, off_t len);
|
||||||
|
|
Loading…
Reference in New Issue