flexnbd: Add --bind to flexnbd read and flexnbd write

This commit is contained in:
nick
2012-06-06 09:55:08 +01:00
parent b985e97098
commit 8a2fd06c31
6 changed files with 64 additions and 30 deletions

View File

@@ -217,7 +217,7 @@ int control_mirror(struct control_params* client, int linesc, char** lines)
return -1; return -1;
} }
fd = socket_connect(&connect_to.generic); fd = socket_connect(&connect_to.generic, NULL);
remote_size = socket_nbd_read_hello(fd); remote_size = socket_nbd_read_hello(fd);
remote_size = remote_size; // shush compiler remote_size = remote_size; // shush compiler

View File

@@ -111,6 +111,7 @@ void params_readwrite(
struct mode_readwrite_params* out, struct mode_readwrite_params* out,
char* s_ip_address, char* s_ip_address,
char* s_port, char* s_port,
char* s_bind_address,
char* s_from, char* s_from,
char* s_length_or_filename char* s_length_or_filename
) )
@@ -128,6 +129,9 @@ void params_readwrite(
SERVER_ERROR("Couldn't parse connection address '%s'", SERVER_ERROR("Couldn't parse connection address '%s'",
s_ip_address); s_ip_address);
if (s_bind_address != NULL && parse_ip_to_sockaddr(&out->connect_from.generic, s_bind_address) == 0)
SERVER_ERROR("Couldn't parse bind address '%s'", s_bind_address);
/* FIXME: duplicated from above */ /* FIXME: duplicated from above */
out->connect_to.v4.sin_port = atoi(s_port); out->connect_to.v4.sin_port = atoi(s_port);
if (out->connect_to.v4.sin_port < 0 || out->connect_to.v4.sin_port > 65535) if (out->connect_to.v4.sin_port < 0 || out->connect_to.v4.sin_port > 65535)
@@ -198,7 +202,7 @@ void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char
} }
void read_readwrite_param( int c, char **ip_addr, char **ip_port, char **from, char **size) void read_readwrite_param( int c, char **ip_addr, char **ip_port, char **bind_addr, char **from, char **size)
{ {
switch(c){ switch(c){
case 'h': case 'h':
@@ -217,6 +221,9 @@ void read_readwrite_param( int c, char **ip_addr, char **ip_port, char **from, c
case 'S': case 'S':
*size = optarg; *size = optarg;
break; break;
case 'b':
*bind_addr = optarg;
break;
case 'd': case 'd':
set_debug(1); set_debug(1);
break; break;
@@ -320,8 +327,9 @@ int mode_serve( int argc, char *argv[] )
int mode_read( int argc, char *argv[] ) int mode_read( int argc, char *argv[] )
{ {
int c; int c;
char *ip_addr = NULL; char *ip_addr = NULL;
char *ip_port = NULL; char *ip_port = NULL;
char *bind_addr = NULL;
char *from = NULL; char *from = NULL;
char *size = NULL; char *size = NULL;
int err = 0; int err = 0;
@@ -330,8 +338,11 @@ int mode_read( int argc, char *argv[] )
while (1){ while (1){
c = getopt_long(argc, argv, read_short_options, read_options, NULL); c = getopt_long(argc, argv, read_short_options, read_options, NULL);
if ( c == -1 ) break;
read_readwrite_param( c, &ip_addr, &ip_port, &from, &size ); if ( c == -1 )
break;
read_readwrite_param( c, &ip_addr, &ip_port, &bind_addr, &from, &size );
} }
if ( NULL == ip_addr || NULL == ip_port ) { if ( NULL == ip_addr || NULL == ip_port ) {
@@ -345,7 +356,7 @@ int mode_read( int argc, char *argv[] )
if ( err ) { exit_err( read_help_text ); } if ( err ) { exit_err( read_help_text ); }
memset( &readwrite, 0, sizeof( readwrite ) ); memset( &readwrite, 0, sizeof( readwrite ) );
params_readwrite( 0, &readwrite, ip_addr, ip_port, from, size ); params_readwrite( 0, &readwrite, ip_addr, ip_port, bind_addr, from, size );
do_read( &readwrite ); do_read( &readwrite );
return 0; return 0;
} }
@@ -353,8 +364,9 @@ int mode_read( int argc, char *argv[] )
int mode_write( int argc, char *argv[] ) int mode_write( int argc, char *argv[] )
{ {
int c; int c;
char *ip_addr = NULL; char *ip_addr = NULL;
char *ip_port = NULL; char *ip_port = NULL;
char *bind_addr = NULL;
char *from = NULL; char *from = NULL;
char *size = NULL; char *size = NULL;
int err = 0; int err = 0;
@@ -363,8 +375,10 @@ int mode_write( int argc, char *argv[] )
while (1){ while (1){
c = getopt_long(argc, argv, write_short_options, write_options, NULL); c = getopt_long(argc, argv, write_short_options, write_options, NULL);
if ( c == -1 ) break; if ( c == -1 )
read_readwrite_param( c, &ip_addr, &ip_port, &from, &size ); break;
read_readwrite_param( c, &ip_addr, &ip_port, &bind_addr, &from, &size );
} }
if ( NULL == ip_addr || NULL == ip_port ) { if ( NULL == ip_addr || NULL == ip_port ) {
@@ -378,7 +392,7 @@ int mode_write( int argc, char *argv[] )
if ( err ) { exit_err( write_help_text ); } if ( err ) { exit_err( write_help_text ); }
memset( &readwrite, 0, sizeof( readwrite ) ); memset( &readwrite, 0, sizeof( readwrite ) );
params_readwrite( 1, &readwrite, ip_addr, ip_port, from, size ); params_readwrite( 1, &readwrite, ip_addr, ip_port, bind_addr, from, size );
do_write( &readwrite ); do_write( &readwrite );
return 0; return 0;
} }

View File

@@ -3,6 +3,7 @@
#define OPT_HELP "help" #define OPT_HELP "help"
#define OPT_ADDR "addr" #define OPT_ADDR "addr"
#define OPT_BIND "bind"
#define OPT_PORT "port" #define OPT_PORT "port"
#define OPT_FILE "file" #define OPT_FILE "file"
#define OPT_SOCK "sock" #define OPT_SOCK "sock"
@@ -34,6 +35,7 @@
#define GETOPT_SOCK GETOPT_ARG( OPT_SOCK, 's' ) #define GETOPT_SOCK GETOPT_ARG( OPT_SOCK, 's' )
#define GETOPT_FROM GETOPT_ARG( OPT_FROM, 'F' ) #define GETOPT_FROM GETOPT_ARG( OPT_FROM, 'F' )
#define GETOPT_SIZE GETOPT_ARG( OPT_SIZE, 'S' ) #define GETOPT_SIZE GETOPT_ARG( OPT_SIZE, 'S' )
#define GETOPT_BIND GETOPT_ARG( OPT_BIND, 'b' )
#ifdef DEBUG #ifdef DEBUG
# define OPT_DEBUG "debug" # define OPT_DEBUG "debug"
@@ -45,6 +47,12 @@
# define DEBUG_LINE "" # define DEBUG_LINE ""
#endif #endif
#define HELP_LINE \
"\t--" OPT_HELP ",-h \tThis text.\n"
#define SOCK_LINE \
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n"
#define BIND_LINE \
"\t--" OPT_BIND ",-b <ADDR>\tBind the local socket to a particular IP address.\n"
static struct option serve_options[] = { static struct option serve_options[] = {
GETOPT_HELP, GETOPT_HELP,
@@ -60,12 +68,12 @@ static char serve_short_options[] = "Dhl:p:f:s:";
static char serve_help_text[] = static char serve_help_text[] =
"Usage: flexnbd " CMD_SERVE " <options> [<acl address>*]\n\n" "Usage: flexnbd " CMD_SERVE " <options> [<acl address>*]\n\n"
"Serve FILE from ADDR:PORT, with an optional control socket at SOCK.\n\n" "Serve FILE from ADDR:PORT, with an optional control socket at SOCK.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_ADDR ",-l <ADDR>\tThe address to serve on.\n" "\t--" OPT_ADDR ",-l <ADDR>\tThe address to serve on.\n"
"\t--" OPT_PORT ",-p <PORT>\tThe port to serve on.\n" "\t--" OPT_PORT ",-p <PORT>\tThe port to serve on.\n"
"\t--" OPT_FILE ",-f <FILE>\tThe file to serve.\n" "\t--" OPT_FILE ",-f <FILE>\tThe file to serve.\n"
"\t--" OPT_DENY ",-D\tDeny connections by default unless in ACL\n" "\t--" OPT_DENY ",-D\tDeny connections by default unless in ACL.\n"
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket to open.\n" SOCK_LINE
DEBUG_LINE; DEBUG_LINE;
static struct option read_options[] = { static struct option read_options[] = {
@@ -74,18 +82,20 @@ static struct option read_options[] = {
GETOPT_PORT, GETOPT_PORT,
GETOPT_FROM, GETOPT_FROM,
GETOPT_SIZE, GETOPT_SIZE,
GETOPT_BIND,
GETOPT_DEBUG, GETOPT_DEBUG,
{0} {0}
}; };
static char read_short_options[] = "hl:p:F:S:"; static char read_short_options[] = "hl:p:F:S:b:";
static char read_help_text[] = static char read_help_text[] =
"Usage: flexnbd " CMD_READ " <options>\n\n" "Usage: flexnbd " CMD_READ " <options>\n\n"
"Read SIZE bytes from a server at ADDR:PORT to stdout, starting at OFFSET.\n\n" "Read SIZE bytes from a server at ADDR:PORT to stdout, starting at OFFSET.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_ADDR ",-l <ADDR>\tThe address to read from.\n" "\t--" OPT_ADDR ",-l <ADDR>\tThe address to read from.\n"
"\t--" OPT_PORT ",-p <PORT>\tThe port to read from.\n" "\t--" OPT_PORT ",-p <PORT>\tThe port to read from.\n"
"\t--" OPT_FROM ",-F <OFFSET>\tByte offset to read from.\n" "\t--" OPT_FROM ",-F <OFFSET>\tByte offset to read from.\n"
"\t--" OPT_SIZE ",-S <SIZE>\tBytes to read.\n" "\t--" OPT_SIZE ",-S <SIZE>\tBytes to read.\n"
BIND_LINE
DEBUG_LINE; DEBUG_LINE;
@@ -94,11 +104,12 @@ static char *write_short_options = read_short_options;
static char write_help_text[] = static char write_help_text[] =
"Usage: flexnbd " CMD_WRITE" <options>\n\n" "Usage: flexnbd " CMD_WRITE" <options>\n\n"
"Write SIZE bytes from stdin to a server at ADDR:PORT, starting at OFFSET.\n\n" "Write SIZE bytes from stdin to a server at ADDR:PORT, starting at OFFSET.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_ADDR ",-l <ADDR>\tThe address to write to.\n" "\t--" OPT_ADDR ",-l <ADDR>\tThe address to write to.\n"
"\t--" OPT_PORT ",-p <PORT>\tThe port to write to.\n" "\t--" OPT_PORT ",-p <PORT>\tThe port to write to.\n"
"\t--" OPT_FROM ",-F <OFFSET>\tByte offset to write from.\n" "\t--" OPT_FROM ",-F <OFFSET>\tByte offset to write from.\n"
"\t--" OPT_SIZE ",-S <SIZE>\tBytes to write.\n" "\t--" OPT_SIZE ",-S <SIZE>\tBytes to write.\n"
BIND_LINE
DEBUG_LINE; DEBUG_LINE;
struct option acl_options[] = { struct option acl_options[] = {
@@ -111,8 +122,8 @@ static char acl_short_options[] = "hs:";
static char acl_help_text[] = static char acl_help_text[] =
"Usage: flexnbd " CMD_ACL " <options> [<acl address>+]\n\n" "Usage: flexnbd " CMD_ACL " <options> [<acl address>+]\n\n"
"Set the access control list for a server with control socket SOCK.\n\n" "Set the access control list for a server with control socket SOCK.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n" SOCK_LINE
DEBUG_LINE; DEBUG_LINE;
struct option mirror_options[] = { struct option mirror_options[] = {
@@ -127,8 +138,7 @@ static char mirror_short_options[] = "hs:l:p:";
static char mirror_help_text[] = static char mirror_help_text[] =
"Usage: flexnbd " CMD_MIRROR " <options>\n\n" "Usage: flexnbd " CMD_MIRROR " <options>\n\n"
"Start mirroring from the server with control socket SOCK to one at ADDR:PORT.\n\n" "Start mirroring from the server with control socket SOCK to one at ADDR:PORT.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n"
"\t--" OPT_ADDR ",-l <ADDR>\tThe address to mirror to.\n" "\t--" OPT_ADDR ",-l <ADDR>\tThe address to mirror to.\n"
"\t--" OPT_PORT ",-p <PORT>\tThe port to mirror to.\n" "\t--" OPT_PORT ",-p <PORT>\tThe port to mirror to.\n"
DEBUG_LINE; DEBUG_LINE;
@@ -144,8 +154,8 @@ static char status_short_options[] = "hs:";
static char status_help_text[] = static char status_help_text[] =
"Usage: flexnbd " CMD_STATUS " <options>\n\n" "Usage: flexnbd " CMD_STATUS " <options>\n\n"
"Get the status for a server with control socket SOCK.\n\n" "Get the status for a server with control socket SOCK.\n\n"
"\t--" OPT_HELP ",-h\tThis text.\n" HELP_LINE
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket.\n" SOCK_LINE
DEBUG_LINE; DEBUG_LINE;
static char help_help_text[] = static char help_help_text[] =
@@ -159,3 +169,4 @@ static char help_help_text[] =
"\tflexnbd status\n" "\tflexnbd status\n"
"\tflexnbd help\n\n" "\tflexnbd help\n\n"
"See flexnbd help <cmd> for further info\n"; "See flexnbd help <cmd> for further info\n";

View File

@@ -82,6 +82,7 @@ struct mode_serve_params {
struct mode_readwrite_params { struct mode_readwrite_params {
union mysockaddr connect_to; union mysockaddr connect_to;
union mysockaddr connect_from;
off64_t from; off64_t from;
off64_t len; off64_t len;
int data_fd; int data_fd;

View File

@@ -7,12 +7,20 @@
#include <string.h> #include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
int socket_connect(struct sockaddr* to) int socket_connect(struct sockaddr* to, struct sockaddr* from)
{ {
int fd = socket(to->sa_family == AF_INET ? PF_INET : PF_INET6, SOCK_STREAM, 0); int fd = socket(to->sa_family == AF_INET ? PF_INET : PF_INET6, SOCK_STREAM, 0);
SERVER_ERROR_ON_FAILURE(fd, "Couldn't create client socket"); SERVER_ERROR_ON_FAILURE(fd, "Couldn't create client socket");
SERVER_ERROR_ON_FAILURE(connect(fd, to, sizeof(struct sockaddr_in6)),
"connect failed"); if (NULL != from)
SERVER_ERROR_ON_FAILURE(
bind(fd, from, sizeof(struct sockaddr_in6)),
"bind() failed"
);
SERVER_ERROR_ON_FAILURE(
connect(fd, to, sizeof(struct sockaddr_in6)),"connect failed"
);
return fd; return fd;
} }
@@ -106,7 +114,7 @@ void socket_nbd_write(int fd, off64_t from, int len, int in_fd, void* in_buf)
void do_read(struct mode_readwrite_params* params) void do_read(struct mode_readwrite_params* params)
{ {
params->client = socket_connect(&params->connect_to.generic); params->client = socket_connect(&params->connect_to.generic, &params->connect_from.generic);
CHECK_RANGE("read"); CHECK_RANGE("read");
socket_nbd_read(params->client, params->from, params->len, socket_nbd_read(params->client, params->from, params->len,
params->data_fd, NULL); params->data_fd, NULL);
@@ -115,7 +123,7 @@ void do_read(struct mode_readwrite_params* params)
void do_write(struct mode_readwrite_params* params) void do_write(struct mode_readwrite_params* params)
{ {
params->client = socket_connect(&params->connect_to.generic); params->client = socket_connect(&params->connect_to.generic, &params->connect_from.generic);
CHECK_RANGE("write"); CHECK_RANGE("write");
socket_nbd_write(params->client, params->from, params->len, socket_nbd_write(params->client, params->from, params->len,
params->data_fd, NULL); params->data_fd, NULL);

View File

@@ -2,7 +2,7 @@
#define __READWRITE_H #define __READWRITE_H
int socket_connect(struct sockaddr* to); int socket_connect(struct sockaddr* to, struct sockaddr* from);
off64_t socket_nbd_read_hello(int fd); off64_t socket_nbd_read_hello(int fd);
void socket_nbd_read(int fd, off64_t from, int len, int out_fd, void* out_buf); void socket_nbd_read(int fd, off64_t from, int len, int out_fd, void* out_buf);
void socket_nbd_write(int fd, off64_t from, int len, int out_fd, void* out_buf); void socket_nbd_write(int fd, off64_t from, int len, int out_fd, void* out_buf);