From e7ad62c1b1627f7bab2524a4c30f1833f6b6767d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 1 Aug 2013 19:35:48 +0200 Subject: [SERVER] Fix create_image() by adding fallback solutions for fallocate() --- src/server/globals.c | 9 ++++++++- src/server/globals.h | 1 + src/server/helper.c | 9 +++++++++ src/server/helper.h | 1 + src/server/image.c | 21 ++++++++++----------- src/server/memlog.c | 1 + src/server/server.c | 19 +++++++++++-------- 7 files changed, 41 insertions(+), 20 deletions(-) (limited to 'src/server') diff --git a/src/server/globals.c b/src/server/globals.c index d84e3f7..182b2cc 100644 --- a/src/server/globals.c +++ b/src/server/globals.c @@ -29,8 +29,15 @@ void globals_loadConfig() if ( name == NULL ) return; ini_parse( name, &ini_handler, NULL ); free( name ); - if ( _basePath != NULL && _basePath[0] != '/' ) { + if ( _basePath == NULL || _basePath[0] == '\0' ) { + memlogf( "[ERROR] Need to specify basePath in " CONFIG_FILENAME ); + exit( EXIT_FAILURE ); + } + if ( _basePath[0] != '/' ) { memlogf( "[ERROR] _basePath must be absolute!" ); exit( EXIT_FAILURE ); } + char *end = _basePath + strlen( _basePath ) - 1; + while ( end >= _basePath && *end == '/' ) + *end-- = '\0'; } diff --git a/src/server/globals.h b/src/server/globals.h index 2dd6e13..b063fc3 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -117,6 +117,7 @@ struct _dnbd3_client // ####################################################### #define CONFIG_FILENAME "server.conf" + /** * Base directory where the configuration files reside. Will never have a trailing slash. */ diff --git a/src/server/helper.c b/src/server/helper.c index b028ad1..65239ea 100644 --- a/src/server/helper.c +++ b/src/server/helper.c @@ -162,3 +162,12 @@ int mkdir_p(const char* path) if ( mkdir( buffer, 0750 ) != 0 && errno != EEXIST ) return FALSE; return TRUE; } + +int file_alloc(int fd, uint64_t offset, uint64_t size) +{ + if ( fallocate( fd, 0, offset, size ) == 0 ) return TRUE; // fast way + if ( posix_fallocate( fd, offset, size ) == 0 ) return TRUE; // slow way + if ( lseek( fd, offset + size - 1, SEEK_SET ) != offset ) return FALSE; // dumb way + if ( write( fd, "", 1 ) != 1 ) return FALSE; + return TRUE; +} diff --git a/src/server/helper.h b/src/server/helper.h index c212720..6c116ef 100644 --- a/src/server/helper.h +++ b/src/server/helper.h @@ -19,6 +19,7 @@ void trim_right(char * const string); int file_exists(char *file); int file_writable(char *file); int mkdir_p(const char* path); +int file_alloc(int fd, uint64_t offset, uint64_t size); static inline int is_same_server(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { diff --git a/src/server/image.c b/src/server/image.c index 556e83b..6b6fb99 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -14,7 +14,6 @@ #include #include #include -#include // ########################################## @@ -555,7 +554,7 @@ int image_create(char *image, int revision, uint64_t size) assert( image != NULL ); assert( size >= DNBD3_BLOCK_SIZE ); if ( revision <= 0 ) { - printf( "[ERROR] revision id invalid: %d\n", revision ); + memlogf( "[ERROR] revision id invalid: %d", revision ); return FALSE; } const int PATHLEN = 2000; @@ -571,7 +570,7 @@ int image_create(char *image, int revision, uint64_t size) snprintf( path, PATHLEN, "%s/%s.r%d", _basePath, image, revision ); } if ( file_exists( path ) ) { - printf( "[ERROR] Image %s with rid %d already exists!\n", image, revision ); + memlogf( "[ERROR] Image %s with rid %d already exists!", image, revision ); return FALSE; } snprintf( cache, PATHLEN, "%s.map", path ); @@ -579,26 +578,26 @@ int image_create(char *image, int revision, uint64_t size) const int mapsize = IMGSIZE_TO_MAPBYTES(size); // Write files int fdImage = -1, fdCache = -1; - fdImage = open( path, O_WRONLY | O_TRUNC, 0640 ); - fdCache = open( cache, O_WRONLY | O_TRUNC, 0640 ); + fdImage = open( path, O_RDWR | O_TRUNC | O_CREAT, 0640 ); + fdCache = open( cache, O_RDWR | O_TRUNC | O_CREAT, 0640 ); if ( fdImage < 0 ) { - printf( "[ERROR] Could not open %s for writing.\n", path ); + memlogf( "[ERROR] Could not open %s for writing.", path ); goto failure_cleanup; } if ( fdCache < 0 ) { - printf( "[ERROR] Could not open %s for writing.\n", cache ); + memlogf( "[ERROR] Could not open %s for writing.", cache ); goto failure_cleanup; } // Try cache map first - if ( fallocate( fdCache, 0, 0, mapsize ) != 0 ) { + if ( !file_alloc( fdCache, 0, mapsize ) ) { const int err = errno; - printf( "[ERROR] Could not allocate %d bytes for %s (errno=%d)", mapsize, cache, err ); + memlogf( "[ERROR] Could not allocate %d bytes for %s (errno=%d)", mapsize, cache, err ); goto failure_cleanup; } // Now write image - if ( fallocate( fdImage, 0, 0, size ) != 0 ) { + if ( !file_alloc( fdImage, 0, size ) ) { const int err = errno; - printf( "[ERROR] Could not allocate %" PRIu64 " bytes for %s (errno=%d)", size, path, err ); + memlogf( "[ERROR] Could not allocate %" PRIu64 " bytes for %s (errno=%d)", size, path, err ); goto failure_cleanup; } close( fdImage ); diff --git a/src/server/memlog.c b/src/server/memlog.c index 447d232..12de858 100644 --- a/src/server/memlog.c +++ b/src/server/memlog.c @@ -60,6 +60,7 @@ void memlogf(const char *fmt, ...) va_start( ap, fmt ); vprintf( fmt, ap ); va_end( ap ); + printf( "\n" ); return; // Not initialized yet } va_list ap; diff --git a/src/server/server.c b/src/server/server.c index 9b6ff30..12b437b 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -82,7 +82,8 @@ void dnbd3_print_help(char *argv_0) printf( "Management functions:\n" ); printf( "--crc [image-file] Generate crc block list for given image\n" ); printf( "--create [image-name] --revision [rid] --size [filesize]\n" - "\tCreate a local empty image file with a zeroed cache-map for the specified image" ); + "\tCreate a local empty image file with a zeroed cache-map for the specified image\n" ); + printf( "\n" ); exit( 0 ); } @@ -215,13 +216,7 @@ int main(int argc, char *argv[]) opt = getopt_long( argc, argv, optString, longOpts, &longIndex ); } - // One-shots first: - - if ( paramCreate != NULL ) { - return image_create( paramCreate, paramRevision, paramSize ) ? 0 : EXIT_FAILURE; - } - - // No one-shot detected, normal server operation + // Load general config if ( _configDir == NULL ) _configDir = strdup( "/etc/dnbd3-server" ); globals_loadConfig(); @@ -230,6 +225,14 @@ int main(int argc, char *argv[]) exit( EXIT_FAILURE ); } + // One-shots first: + + if ( paramCreate != NULL ) { + return image_create( paramCreate, paramRevision, paramSize ) ? 0 : EXIT_FAILURE; + } + + // No one-shot detected, normal server operation + if ( demonize ) daemon( 1, 0 ); initmemlog(); spin_init( &_clients_lock, PTHREAD_PROCESS_PRIVATE ); -- cgit v1.2.3-55-g7522