/* # 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 #include #include #include #include #include #include #include "../version.h" using namespace std; int _nbd_server_port; map _map; // map running nbd-servers: 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; }