/*
# 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 << "[REMOTE 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;
}