virFDStream: Add option for delete file after it's opening

This is needed if we want to transfer a temporary file. If the
transfer is done with iohelper, we might run into a race condition,
where we unlink() file before iohelper is executed.

* src/fdstream.c, src/fdstream.h,
  src/util/iohelper.c: Add new option
* src/lxc/lxc_driver.c, src/qemu/qemu_driver.c,
  src/storage/storage_driver.c, src/uml/uml_driver.c,
  src/xen/xen_driver.c: Expand existing function calls
This commit is contained in:
Michal Privoznik 2011-04-05 12:27:35 +02:00
parent 2c6efac985
commit 6a1f5f568f
8 changed files with 46 additions and 17 deletions

View File

@ -493,7 +493,8 @@ virFDStreamOpenFileInternal(virStreamPtr st,
unsigned long long offset, unsigned long long offset,
unsigned long long length, unsigned long long length,
int flags, int flags,
int mode) int mode,
bool delete)
{ {
int fd = -1; int fd = -1;
int fds[2] = { -1, -1 }; int fds[2] = { -1, -1 };
@ -502,8 +503,8 @@ virFDStreamOpenFileInternal(virStreamPtr st,
int errfd = -1; int errfd = -1;
pid_t pid = 0; pid_t pid = 0;
VIR_DEBUG("st=%p path=%s flags=%d offset=%llu length=%llu mode=%d", VIR_DEBUG("st=%p path=%s flags=%d offset=%llu length=%llu mode=%d delete=%d",
st, path, flags, offset, length, mode); st, path, flags, offset, length, mode, delete);
if (flags & O_CREAT) if (flags & O_CREAT)
fd = open(path, flags, mode); fd = open(path, flags, mode);
@ -554,6 +555,14 @@ virFDStreamOpenFileInternal(virStreamPtr st,
virCommandAddArgFormat(cmd, "%d", mode); virCommandAddArgFormat(cmd, "%d", mode);
virCommandAddArgFormat(cmd, "%llu", offset); virCommandAddArgFormat(cmd, "%llu", offset);
virCommandAddArgFormat(cmd, "%llu", length); virCommandAddArgFormat(cmd, "%llu", length);
virCommandAddArgFormat(cmd, "%u", delete);
/* when running iohelper we don't want to delete file now,
* because a race condition may occur in which we delete it
* before iohelper even opens it. We want iohelper to remove
* the file instead.
*/
delete = false;
if (flags == O_RDONLY) { if (flags == O_RDONLY) {
childfd = fds[1]; childfd = fds[1];
@ -583,6 +592,9 @@ virFDStreamOpenFileInternal(virStreamPtr st,
if (virFDStreamOpenInternal(st, fd, cmd, errfd, length) < 0) if (virFDStreamOpenInternal(st, fd, cmd, errfd, length) < 0)
goto error; goto error;
if (delete)
unlink(path);
return 0; return 0;
error: error:
@ -601,7 +613,8 @@ int virFDStreamOpenFile(virStreamPtr st,
const char *path, const char *path,
unsigned long long offset, unsigned long long offset,
unsigned long long length, unsigned long long length,
int flags) int flags,
bool delete)
{ {
if (flags & O_CREAT) { if (flags & O_CREAT) {
streamsReportError(VIR_ERR_INTERNAL_ERROR, streamsReportError(VIR_ERR_INTERNAL_ERROR,
@ -611,7 +624,7 @@ int virFDStreamOpenFile(virStreamPtr st,
} }
return virFDStreamOpenFileInternal(st, path, return virFDStreamOpenFileInternal(st, path,
offset, length, offset, length,
flags, 0); flags, 0, delete);
} }
int virFDStreamCreateFile(virStreamPtr st, int virFDStreamCreateFile(virStreamPtr st,
@ -619,9 +632,11 @@ int virFDStreamCreateFile(virStreamPtr st,
unsigned long long offset, unsigned long long offset,
unsigned long long length, unsigned long long length,
int flags, int flags,
mode_t mode) mode_t mode,
bool delete)
{ {
return virFDStreamOpenFileInternal(st, path, return virFDStreamOpenFileInternal(st, path,
offset, length, offset, length,
flags | O_CREAT, mode); flags | O_CREAT,
mode, delete);
} }

View File

@ -37,12 +37,14 @@ int virFDStreamOpenFile(virStreamPtr st,
const char *path, const char *path,
unsigned long long offset, unsigned long long offset,
unsigned long long length, unsigned long long length,
int flags); int flags,
bool delete);
int virFDStreamCreateFile(virStreamPtr st, int virFDStreamCreateFile(virStreamPtr st,
const char *path, const char *path,
unsigned long long offset, unsigned long long offset,
unsigned long long length, unsigned long long length,
int flags, int flags,
mode_t mode); mode_t mode,
bool delete);
#endif /* __VIR_FDSTREAM_H_ */ #endif /* __VIR_FDSTREAM_H_ */

View File

@ -2691,7 +2691,8 @@ lxcDomainOpenConsole(virDomainPtr dom,
goto cleanup; goto cleanup;
} }
if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) if (virFDStreamOpenFile(st, chr->source.data.file.path,
0, 0, O_RDWR, false) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;

View File

@ -7120,7 +7120,8 @@ qemuDomainOpenConsole(virDomainPtr dom,
goto cleanup; goto cleanup;
} }
if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) if (virFDStreamOpenFile(st, chr->source.data.file.path,
0, 0, O_RDWR, false) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;

View File

@ -1592,7 +1592,7 @@ storageVolumeDownload(virStorageVolPtr obj,
if (virFDStreamOpenFile(stream, if (virFDStreamOpenFile(stream,
vol->target.path, vol->target.path,
offset, length, offset, length,
O_RDONLY) < 0) O_RDONLY, false) < 0)
goto out; goto out;
ret = 0; ret = 0;
@ -1656,7 +1656,7 @@ storageVolumeUpload(virStorageVolPtr obj,
if (virFDStreamOpenFile(stream, if (virFDStreamOpenFile(stream,
vol->target.path, vol->target.path,
offset, length, offset, length,
O_WRONLY) < 0) O_WRONLY, false) < 0)
goto out; goto out;
ret = 0; ret = 0;

View File

@ -2130,7 +2130,8 @@ umlDomainOpenConsole(virDomainPtr dom,
goto cleanup; goto cleanup;
} }
if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) if (virFDStreamOpenFile(st, chr->source.data.file.path,
0, 0, O_RDWR, false) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;

View File

@ -146,6 +146,7 @@ int main(int argc, char **argv)
unsigned long long length; unsigned long long length;
int flags; int flags;
int mode; int mode;
unsigned int delete;
if (setlocale(LC_ALL, "") == NULL || if (setlocale(LC_ALL, "") == NULL ||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL || bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
@ -161,8 +162,8 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (argc != 6) { if (argc != 7) {
fprintf(stderr, _("%s: syntax FILENAME FLAGS MODE OFFSET LENGTH\n"), argv[0]); fprintf(stderr, _("%s: syntax FILENAME FLAGS MODE OFFSET LENGTH DELETE\n"), argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -186,10 +187,17 @@ int main(int argc, char **argv)
fprintf(stderr, _("%s: malformed file length %s"), argv[0], argv[5]); fprintf(stderr, _("%s: malformed file length %s"), argv[0], argv[5]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (virStrToLong_ui(argv[6], NULL, 10, &delete) < 0) {
fprintf(stderr, _("%s: malformed delete flag %s"), argv[0],argv[6]);
exit(EXIT_FAILURE);
}
if (runIO(path, flags, mode, offset, length) < 0) if (runIO(path, flags, mode, offset, length) < 0)
goto error; goto error;
if (delete)
unlink(path);
return 0; return 0;
error: error:

View File

@ -2086,7 +2086,8 @@ xenUnifiedDomainOpenConsole(virDomainPtr dom,
goto cleanup; goto cleanup;
} }
if (virFDStreamOpenFile(st, chr->source.data.file.path, 0, 0, O_RDWR) < 0) if (virFDStreamOpenFile(st, chr->source.data.file.path,
0, 0, O_RDWR, false) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;