diff options
author | Sebastian Schmelzer | 2011-07-14 15:23:41 +0200 |
---|---|---|
committer | Sebastian Schmelzer | 2011-07-14 15:23:41 +0200 |
commit | d3cb5ed54623b42c15384fa80a622bef043f529c (patch) | |
tree | b0df2aecbcd9e9d7a6effeefd7784dd7c6fb283c | |
download | nbd-broker-d3cb5ed54623b42c15384fa80a622bef043f529c.tar.gz nbd-broker-d3cb5ed54623b42c15384fa80a622bef043f529c.tar.xz nbd-broker-d3cb5ed54623b42c15384fa80a622bef043f529c.zip |
initial import
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | AUTHORS | 7 | ||||
-rw-r--r-- | CMakeLists.txt | 46 | ||||
-rw-r--r-- | README | 36 | ||||
-rw-r--r-- | cmake/FindGearman.cmake | 17 | ||||
-rw-r--r-- | src/client/main.cpp | 139 | ||||
-rw-r--r-- | src/version.h | 2 | ||||
-rw-r--r-- | src/worker/main.cpp | 166 |
8 files changed, 417 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d94cf1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +bin +build +~* @@ -0,0 +1,7 @@ +Initial design and first versions: +Johann Latocha <johann@latocha.de> + +Project management, supervision: +Dirk von Suchodoletz <dvs@openslx.com> +Sebastian Schmelzer <sebastian@schmelzer.ws> +Johann Latocha <johann@latocha.de>
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..04a2be4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +################################################################################ +# General +################################################################################ + +# set project's name +PROJECT( nbd-broker ) + +# cmake min version +CMAKE_MINIMUM_REQUIRED( VERSION 2.8.0 ) + +# set compiler optimizations for debug and release +SET(CMAKE_BUILD_TYPE Debug) +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -march=native") + +# local cmake modules +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +# this command finds libraries and sets all required variables +FIND_PACKAGE(Gearman REQUIRED) + +# some includes +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ) + +################################################################################ +# Variables +################################################################################ + +FILE( GLOB_RECURSE NBDBROKERWORKER_SRCS "src/worker/*.cpp" ) +FILE( GLOB_RECURSE NBDBROKERCLIENT_SRCS "src/client/*.cpp" ) + + +################################################################################ +# Build +################################################################################ + +# build +ADD_EXECUTABLE( nbd-broker-worker ${NBDBROKERWORKER_SRCS} ) +ADD_EXECUTABLE( nbd-broker-client ${NBDBROKERCLIENT_SRCS} ) + +# link +TARGET_LINK_LIBRARIES( nbd-broker-worker ${GEARMAN_LIBRARIES} ) +TARGET_LINK_LIBRARIES( nbd-broker-client ${GEARMAN_LIBRARIES} ) + +# install +INSTALL(TARGETS nbd-broker-worker nbd-broker-client RUNTIME DESTINATION bin) @@ -0,0 +1,36 @@ +**** Installation Guide (Debian/Ubuntu/Suse) **** + +*** Prerequisites *** + +The following packages are required: + +Client: + gearman-tools + libgearman4 + libgearman-dev + nbd-client + cmake + +Server additionally: + gearman-job-server + nbd-server + + +*** Installation *** + +Change to the root folder nbd-broker and enter: + mkdir -p build + cd build/ + cmake .. + make + +If you succeed, all binaries are located at build/ +So change the current directory with: + cd build/ + +As superuser (root) you can install the application on your system: + make install + + +If you have any feedback please consult http://feedback.openslx.org/ and +send your suggestions, praise, or complaints to feedback@openslx.org
\ No newline at end of file diff --git a/cmake/FindGearman.cmake b/cmake/FindGearman.cmake new file mode 100644 index 0000000..757d5b7 --- /dev/null +++ b/cmake/FindGearman.cmake @@ -0,0 +1,17 @@ +FIND_PATH(GEARMAN_INCLUDES gearman.h /usr/include/libgearman /usr/local/include/libgearman) + +FIND_LIBRARY(GEARMAN_LIBRARIES NAMES libgearman.so PATH /usr/lib /usr/local/lib) + +IF (GEARMAN_INCLUDES AND GEARMAN_LIBRARIES) + SET(GEARMAN_FOUND TRUE) +ENDIF (GEARMAN_INCLUDES AND GEARMAN_LIBRARIES) + +IF (GEARMAN_FOUND) + IF (NOT GEARMAN_FIND_QUIETLY) + MESSAGE(STATUS "Found Gearman: ${GEARMAN_LIBRARIES}") + ENDIF (NOT GEARMAN_FIND_QUIETLY) +ELSE (GEARMAN_FOUND) + IF (GEARMAN_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Gearman") + ENDIF (GEARMAN_FIND_REQUIRED) +ENDIF (GEARMAN_FOUND)
\ No newline at end of file diff --git a/src/client/main.cpp b/src/client/main.cpp new file mode 100644 index 0000000..dfec059 --- /dev/null +++ b/src/client/main.cpp @@ -0,0 +1,139 @@ +/* + # Copyright (c) 2011 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://gpl.openslx.org/ + # + # If you have any feedback please consult http://feedback.openslx.org/ and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + */ + +#include <sstream> +#include <iostream> +#include <stdio.h> +#include <libgearman/gearman.h> + +#include "../version.h" + +using namespace std; + +static void usage(char *name) +{ + printf("usage: %s -h <host> [-p <port>] -i <image> -d <device>\n", name); + printf("\t-h <host>\t gearman job server host\n"); + printf("\t-p <port>\t gearman job server port\n"); + printf("\t-i <image>\t remote image file to load\n"); + printf("\t-d <device>\t local nbd-device to use\n"); + printf("\t-v\t\t print version and exit\n"); +} + +int main(int argc, char* argv[]) +{ + string host(""); + in_port_t port = 0; + string image(""); + string device(""); + + gearman_return_t ret; + gearman_client_st client; + + // parse command line arguments + int c; + while ((c = getopt(argc, argv, "h:p:i:d:v")) != -1) + { + switch (c) + { + case 'h': + host = optarg; + break; + case 'p': + port = (in_port_t) atoi(optarg); + break; + case 'i': + image = optarg; + break; + case 'd': + device = optarg; + break; + case 'v': + printf("Version: %s\n", VERSION_STRING); + exit(0); + default: + usage(argv[0]); + exit(1); + } + } + + if (host == "" || image == "" || device == "") + { + usage(argv[0]); + exit(1); + } + + // initialize gearman client + if (gearman_client_create(&client) == NULL) + { + cerr << "[ERROR] Memory allocation failure on client creation" << endl; + exit(1); + } + ret = gearman_client_add_server(&client, host.c_str(), port); + if (ret != GEARMAN_SUCCESS) + { + cerr << "[ERROR] " << gearman_client_error(&client) << endl; + exit(1); + } + + // main loop + char *result; + size_t result_size; + string msg; + while (1) + { + // send request to gearman job server + result = (char *) gearman_client_do(&client, "start_nbd_server", NULL, + (void*) image.c_str(), (size_t) image.length(), &result_size, + &ret); + + if (ret == GEARMAN_WORK_DATA) + { + msg = result; + free(result); + continue; + } + else if (ret == GEARMAN_WORK_STATUS) + { + uint32_t m, n; + gearman_client_do_status(&client, &n, &m); + printf("[INFO] Status: %u/%u\n", n, m); + continue; + } + else if (ret == GEARMAN_SUCCESS) + { + // start nbd-client + stringstream command; + command << "nbd-client " << host << " " << msg << " " << device; + cout << "[DEBUG] " << "Running command: " << command.str() << endl; + system(command.str().c_str()); + free(result); + } + else if (ret == GEARMAN_WORK_FAIL) + { + cerr << "[ERROR] " << msg << endl; + cerr << "[ERROR] Work failed" << endl; + free(result); + } + else + { + cerr << "[ERROR] " << gearman_client_error(&client) << endl; + free(result); + } + + break; + } + + // cleanup + gearman_client_free(&client); + return 0; +} diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..43331a7 --- /dev/null +++ b/src/version.h @@ -0,0 +1,2 @@ +#define VERSION_STRING "0.1.0" +#define VERSION_NUMBER 010 diff --git a/src/worker/main.cpp b/src/worker/main.cpp new file mode 100644 index 0000000..ff97041 --- /dev/null +++ b/src/worker/main.cpp @@ -0,0 +1,166 @@ +/* + # Copyright (c) 2011 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://gpl.openslx.org/ + # + # If you have any feedback please consult http://feedback.openslx.org/ and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + */ + +#include <map> +#include <unistd.h> +#include <iostream> +#include <sstream> +#include <stdio.h> +#include <string.h> +#include <libgearman/gearman.h> + +#include "../version.h" + +using namespace std; + +int _nbd_server_port; +map<string, int> _map; // map running nbd-servers: <exported image, port number> + +static void *start_nbd_server(gearman_job_st *job, void *context, + size_t *result_size, gearman_return_t *ret_ptr) +{ + cout << "[DEBUG] Received request from " << gearman_job_handle(job) << endl; + + if (gearman_job_workload_size(job) <= 0) + { + cerr << "[ERROR] No image given, aborting!" << endl; + return NULL; + } + + // prepare data + char* req = (char*) gearman_job_workload(job); + size_t req_size = gearman_job_workload_size(job); + string *image = new string(req, req_size); + int current_port = 0; + cout << "[DEBUG] Requested image: " << *image << endl; + + // test if requested image exists + int test = access(image->c_str(), 0); + if (test != 0) + { + cerr << "[ERROR] Requested image not found, aborting!" << endl; + char msg[] = "Requested image not found"; + gearman_job_send_data(job, msg, sizeof(msg)); + *ret_ptr = GEARMAN_WORK_FAIL; + return NULL; + } + + if (_map[*image] != 0) + { + // nbd-server already running + cout << "[DEBUG] Requested nbd-server is already running on port " + << _map[*image] << endl; + current_port = _map[*image]; + } + else + { + // start new nbd-server + cout << "[DEBUG] Starting new nbd-server on port " << _nbd_server_port + << endl; + + stringstream command; + command << "nbd-server " << _nbd_server_port << " " << *image; + cout << "[DEBUG] " << "Running command: " << command.str() << endl; + system(command.str().c_str()); + + current_port = _nbd_server_port; + _map[*image] = _nbd_server_port; + _nbd_server_port++; + } + + // send port number to client + cout << "[DEBUG] " << "Response with port number " << current_port << endl; + char buf[32]; + snprintf(buf, sizeof(buf), "%d", current_port); + gearman_job_send_data(job, buf, strlen(buf)); + + *ret_ptr = GEARMAN_SUCCESS; + return NULL; +} + +static void usage(char *name) +{ + printf("usage: %s [-p] [-d] [-v]\n", name); + printf("\t-p\t first port number for nbd-servers (default: 5001)\n"); + printf("\t-d\t start as daemon\n"); + printf("\t-v\t print version and exit\n"); +} + +int main(int argc, char* argv[]) +{ + gearman_return_t result; + gearman_worker_st worker; + _nbd_server_port = 5001; + bool as_daemon = false; + + // parse command line arguments + int c; + while ((c = getopt(argc, argv, "p:dv")) != -1) + { + switch (c) + { + case 'p': + _nbd_server_port = atoi(optarg); + break; + case 'd': + as_daemon = true; + break; + case 'v': + printf("Version: %s\n", VERSION_STRING); + exit(0); + default: + usage(argv[0]); + exit(1); + } + } + + // initialize gearman worker + if (gearman_worker_create(&worker) == NULL) + { + cerr << "[ERROR] Memory allocation failure on worker creation" << endl; + exit(1); + } + result = gearman_worker_add_server(&worker, "127.0.0.1", 0); + if (result != GEARMAN_SUCCESS) + { + cerr << "[ERROR] " << gearman_worker_error(&worker) << endl; + exit(1); + } + result = gearman_worker_add_function(&worker, "start_nbd_server", 0, + start_nbd_server, NULL); + if (result != GEARMAN_SUCCESS) + { + cerr << "[ERROR] " << gearman_worker_error(&worker) << endl; + exit(1); + } + cout << "[DEBUG] Worker is ready." << endl; + if (as_daemon) + { + cout << "[DEBUG] Daemonize..." << endl; + daemon(0, 0); + } + + // main loop + while (1) + { + result = gearman_worker_work(&worker); + if (result != GEARMAN_SUCCESS) + { + cerr << "[ERROR] " << gearman_worker_error(&worker) << endl; + break; + } + } + + // cleanup + gearman_worker_free(&worker); + cout << "[DEBUG] Worker has been freed." << endl; +} |