mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 01:43:23 +00:00
use posix_fallocate() to allocate diskspace faster
* src/libvirt_private.syms src/storage_backend_fs.c src/util.c src/util.h: use posix_fallocate() on supported systems to allocate diskspace faster, patches by Amit Shah Daniel
This commit is contained in:
parent
92d313ebe6
commit
c29d092905
1
AUTHORS
1
AUTHORS
@ -65,6 +65,7 @@ Patches have also been contributed by:
|
|||||||
Maximilian Wilhelm <max@rfc2324.org>
|
Maximilian Wilhelm <max@rfc2324.org>
|
||||||
Ryota Ozaki <ozaki.ryota@gmail.com>
|
Ryota Ozaki <ozaki.ryota@gmail.com>
|
||||||
Pritesh Kothari <Pritesh.Kothari@Sun.COM>
|
Pritesh Kothari <Pritesh.Kothari@Sun.COM>
|
||||||
|
Amit Shah <amit.shah@redhat.com>
|
||||||
|
|
||||||
[....send patches to get your name here....]
|
[....send patches to get your name here....]
|
||||||
|
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
Fri Mar 20 13:16:01 CET 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/libvirt_private.syms src/storage_backend_fs.c src/util.c
|
||||||
|
src/util.h: use posix_fallocate() on supported systems to
|
||||||
|
allocate diskspace faster, patches by Amit Shah
|
||||||
|
|
||||||
Fri Mar 20 11:41:40 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
Fri Mar 20 11:41:40 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
Fix test breakage on x86_64 from previous change
|
Fix test breakage on x86_64 from previous change
|
||||||
|
@ -72,7 +72,7 @@ dnl Use --disable-largefile if you don't want this.
|
|||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
dnl Availability of various common functions (non-fatal if missing).
|
dnl Availability of various common functions (non-fatal if missing).
|
||||||
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid])
|
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid posix_fallocate mmap])
|
||||||
|
|
||||||
dnl Availability of various not common threadsafe functions
|
dnl Availability of various not common threadsafe functions
|
||||||
AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r])
|
AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r])
|
||||||
|
@ -308,6 +308,7 @@ virStrToLong_ui;
|
|||||||
virFileLinkPointsTo;
|
virFileLinkPointsTo;
|
||||||
saferead;
|
saferead;
|
||||||
safewrite;
|
safewrite;
|
||||||
|
safezero;
|
||||||
virMacAddrCompare;
|
virMacAddrCompare;
|
||||||
virEnumFromString;
|
virEnumFromString;
|
||||||
virEnumToString;
|
virEnumToString;
|
||||||
|
@ -62,6 +62,8 @@ static int qcowXGetBackingStore(virConnectPtr, char **,
|
|||||||
static int vmdk4GetBackingStore(virConnectPtr, char **,
|
static int vmdk4GetBackingStore(virConnectPtr, char **,
|
||||||
const unsigned char *, size_t);
|
const unsigned char *, size_t);
|
||||||
|
|
||||||
|
static int track_allocation_progress = 0;
|
||||||
|
|
||||||
/* Either 'magic' or 'extension' *must* be provided */
|
/* Either 'magic' or 'extension' *must* be provided */
|
||||||
struct FileTypeInfo {
|
struct FileTypeInfo {
|
||||||
int type; /* One of the constants above */
|
int type; /* One of the constants above */
|
||||||
@ -1016,17 +1018,25 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Pre-allocate any data if requested */
|
/* Pre-allocate any data if requested */
|
||||||
/* XXX slooooooooooooooooow.
|
/* XXX slooooooooooooooooow on non-extents-based file systems */
|
||||||
* Need to add in progress bars & bg thread somehow */
|
/* FIXME: Add in progress bars & bg thread if progress bar requested */
|
||||||
if (vol->allocation) {
|
if (vol->allocation) {
|
||||||
|
if (track_allocation_progress) {
|
||||||
unsigned long long remain = vol->allocation;
|
unsigned long long remain = vol->allocation;
|
||||||
static char const zeros[4096];
|
|
||||||
while (remain) {
|
while (remain) {
|
||||||
int bytes = sizeof(zeros);
|
/* Allocate in chunks of 512MiB: big-enough chunk
|
||||||
|
* size and takes approx. 9s on ext3. A progress
|
||||||
|
* update every 9s is a fair-enough trade-off
|
||||||
|
*/
|
||||||
|
unsigned long long bytes = 512 * 1024 * 1024;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (bytes > remain)
|
if (bytes > remain)
|
||||||
bytes = remain;
|
bytes = remain;
|
||||||
if ((bytes = safewrite(fd, zeros, bytes)) < 0) {
|
if ((r = safezero(fd, 0, vol->allocation - remain,
|
||||||
virReportSystemError(conn, errno,
|
bytes)) != 0) {
|
||||||
|
virReportSystemError(conn, r,
|
||||||
_("cannot fill file '%s'"),
|
_("cannot fill file '%s'"),
|
||||||
vol->target.path);
|
vol->target.path);
|
||||||
unlink(vol->target.path);
|
unlink(vol->target.path);
|
||||||
@ -1035,6 +1045,18 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
remain -= bytes;
|
remain -= bytes;
|
||||||
}
|
}
|
||||||
|
} else { /* No progress bars to be shown */
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = safezero(fd, 0, 0, vol->allocation)) != 0) {
|
||||||
|
virReportSystemError(conn, r,
|
||||||
|
_("cannot fill file '%s'"),
|
||||||
|
vol->target.path);
|
||||||
|
unlink(vol->target.path);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now seek to final size, possibly making the file sparse */
|
/* Now seek to final size, possibly making the file sparse */
|
||||||
|
68
src/util.c
68
src/util.c
@ -39,6 +39,9 @@
|
|||||||
#if HAVE_SYS_WAIT_H
|
#if HAVE_SYS_WAIT_H
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_MMAP
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#if HAVE_TERMIOS_H
|
#if HAVE_TERMIOS_H
|
||||||
@ -117,6 +120,71 @@ ssize_t safewrite(int fd, const void *buf, size_t count)
|
|||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_POSIX_FALLOCATE
|
||||||
|
int safezero(int fd, int flags, off_t offset, off_t len)
|
||||||
|
{
|
||||||
|
return posix_fallocate(fd, offset, len);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
int safezero(int fd, int flags, off_t offset, off_t len)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
/* memset wants the mmap'ed file to be present on disk so create a
|
||||||
|
* sparse file
|
||||||
|
*/
|
||||||
|
r = ftruncate(fd, len);
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
|
||||||
|
if (buf == MAP_FAILED)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
memset(buf, 0, len);
|
||||||
|
munmap(buf, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_MMAP */
|
||||||
|
|
||||||
|
int safezero(int fd, int flags, off_t offset, off_t len)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char *buf;
|
||||||
|
unsigned long long remain, bytes;
|
||||||
|
|
||||||
|
/* Split up the write in small chunks so as not to allocate lots of RAM */
|
||||||
|
remain = len;
|
||||||
|
bytes = 1024 * 1024;
|
||||||
|
|
||||||
|
r = VIR_ALLOC_N(buf, bytes);
|
||||||
|
if (r < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
while (remain) {
|
||||||
|
if (bytes > remain)
|
||||||
|
bytes = remain;
|
||||||
|
|
||||||
|
r = safewrite(fd, buf, len);
|
||||||
|
if (r < 0) {
|
||||||
|
VIR_FREE(buf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* safewrite() guarantees all data will be written */
|
||||||
|
remain -= bytes;
|
||||||
|
}
|
||||||
|
VIR_FREE(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MMAP */
|
||||||
|
#endif /* HAVE_POSIX_FALLOCATE */
|
||||||
|
|
||||||
#ifndef PROXY
|
#ifndef PROXY
|
||||||
|
|
||||||
int virFileStripSuffix(char *str,
|
int virFileStripSuffix(char *str,
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
int saferead(int fd, void *buf, size_t count);
|
int saferead(int fd, void *buf, size_t count);
|
||||||
ssize_t safewrite(int fd, const void *buf, size_t count);
|
ssize_t safewrite(int fd, const void *buf, size_t count);
|
||||||
|
int safezero(int fd, int flags, off_t offset, off_t len);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VIR_EXEC_NONE = 0,
|
VIR_EXEC_NONE = 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user