summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2013-08-01 19:35:48 +0200
committerSimon Rettberg2013-08-01 19:35:48 +0200
commite7ad62c1b1627f7bab2524a4c30f1833f6b6767d (patch)
tree090473456331c3fa25eafc2db60e4c2808d808a9
parent[SERVER] Add command line options to create empty image of certain size with ... (diff)
downloaddnbd3-e7ad62c1b1627f7bab2524a4c30f1833f6b6767d.tar.gz
dnbd3-e7ad62c1b1627f7bab2524a4c30f1833f6b6767d.tar.xz
dnbd3-e7ad62c1b1627f7bab2524a4c30f1833f6b6767d.zip
[SERVER] Fix create_image() by adding fallback solutions for fallocate()
-rw-r--r--src/server/globals.c9
-rw-r--r--src/server/globals.h1
-rw-r--r--src/server/helper.c9
-rw-r--r--src/server/helper.h1
-rw-r--r--src/server/image.c21
-rw-r--r--src/server/memlog.c1
-rw-r--r--src/server/server.c19
7 files changed, 41 insertions, 20 deletions
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 <dirent.h>
#include <zlib.h>
#include <inttypes.h>
-#include <fcntl.h>
// ##########################################
@@ -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 );