diff --git a/mars.h b/mars.h index d950b7a9..7c90c6fd 100644 --- a/mars.h +++ b/mars.h @@ -265,7 +265,7 @@ extern int mars_power_button_recursive(struct mars_brick *brick, bool val, int #ifdef _STRATEGY // call this only in strategy bricks, never in ordinary bricks #define MARS_ARGV_MAX 4 -#define MARS_PATH_MAX 64 +#define MARS_PATH_MAX 128 extern char *my_id(void); diff --git a/mars_client.c b/mars_client.c index b7a56fce..e882a209 100644 --- a/mars_client.c +++ b/mars_client.c @@ -46,8 +46,10 @@ static int _connect(struct client_output *output, const char *str) if (!output->path) { output->path = kstrdup(str, GFP_MARS); status = -ENOMEM; - if (!output->path) + if (!output->path) { + MARS_DBG("no mem\n"); goto done; + } status = -EINVAL; output->host = strchr(output->path, '@'); if (!output->host) { @@ -60,12 +62,18 @@ static int _connect(struct client_output *output, const char *str) } status = mars_create_sockaddr(&sockaddr, output->host); - if (unlikely(status < 0)) + if (unlikely(status < 0)) { + MARS_DBG("no sockaddr, status = %d\n", status); goto done; + } status = mars_create_socket(&output->socket, &sockaddr, false); if (unlikely(status < 0)) { - output->socket = NULL; + if (status == -EINPROGRESS) { + MARS_DBG("operation is in progress....\n"); + goto really_done; // give it a chance next time + } + MARS_DBG("no socket, status = %d\n", status); goto done; } @@ -76,8 +84,10 @@ static int _connect(struct client_output *output, const char *str) }; status = mars_send_struct(&output->socket, &cmd, mars_cmd_meta); - if (unlikely(status < 0)) + if (unlikely(status < 0)) { + MARS_DBG("send of connect failed, status = %d\n", status); goto done; + } } if (status >= 0) { struct mars_cmd cmd = { @@ -85,6 +95,10 @@ static int _connect(struct client_output *output, const char *str) }; status = mars_send_struct(&output->socket, &cmd, mars_cmd_meta); + if (unlikely(status < 0)) { + MARS_DBG("send of getinfo failed, status = %d\n", status); + goto done; + } } done: @@ -92,6 +106,7 @@ done: MARS_INF("cannot connect to remote host '%s' (status = %d) -- retrying\n", output->host ? output->host : "NULL", status); _kill_socket(output); } +really_done: return status; } diff --git a/mars_net.c b/mars_net.c index fdfab1bd..7bc67730 100644 --- a/mars_net.c +++ b/mars_net.c @@ -123,56 +123,59 @@ EXPORT_SYMBOL_GPL(mars_create_sockaddr); int mars_create_socket(struct socket **sock, struct sockaddr_storage *addr, bool is_server) { - struct sockaddr null_bind = {}; struct sockaddr *sockaddr = (void*)addr; int x_true = 1; - int status; + int status = 0; - if (!is_server) { - sockaddr = &null_bind; + if (!*sock) { + status = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, sock); + if (unlikely(status < 0)) { + *sock = NULL; + MARS_ERR("cannot create socket, status = %d\n", status); + goto done; + } + + /* TODO: improve this by a table-driven approach + */ + (*sock)->sk->sk_rcvtimeo = (*sock)->sk->sk_sndtimeo = default_tcp_params.tcp_timeout * HZ; + status = kernel_setsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); + _check(status); + status = kernel_setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); + _check(status); + status = kernel_setsockopt(*sock, SOL_IP, SO_PRIORITY, (char*)&default_tcp_params.tos, sizeof(default_tcp_params.tos)); + _check(status); + status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, (char*)&x_true, sizeof(x_true)); + _check(status); + status = kernel_setsockopt(*sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&x_true, sizeof(x_true)); + _check(status); + status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&default_tcp_params.tcp_keepcnt, sizeof(default_tcp_params.tcp_keepcnt)); + _check(status); + status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&default_tcp_params.tcp_keepintvl, sizeof(default_tcp_params.tcp_keepintvl)); + _check(status); + status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&default_tcp_params.tcp_keepidle, sizeof(default_tcp_params.tcp_keepidle)); + _check(status); } - status = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, sock); - if (status < 0) { - *sock = NULL; - MARS_ERR("cannot create socket, status = %d\n", status); - return status; - } - - /* TODO: improve this by a table-driven approach - */ - (*sock)->sk->sk_rcvtimeo = (*sock)->sk->sk_sndtimeo = default_tcp_params.tcp_timeout * HZ; - status = kernel_setsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); - _check(status); - status = kernel_setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); - _check(status); - status = kernel_setsockopt(*sock, SOL_IP, SO_PRIORITY, (char*)&default_tcp_params.tos, sizeof(default_tcp_params.tos)); - _check(status); - status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, (char*)&x_true, sizeof(x_true)); - _check(status); - status = kernel_setsockopt(*sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&x_true, sizeof(x_true)); - _check(status); - status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&default_tcp_params.tcp_keepcnt, sizeof(default_tcp_params.tcp_keepcnt)); - _check(status); - status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&default_tcp_params.tcp_keepintvl, sizeof(default_tcp_params.tcp_keepintvl)); - _check(status); - status = kernel_setsockopt(*sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&default_tcp_params.tcp_keepidle, sizeof(default_tcp_params.tcp_keepidle)); - _check(status); - - status = kernel_bind(*sock, sockaddr, sizeof(*sockaddr)); - if (status < 0) { - MARS_ERR("bind failed, status = %d\n", status); - return status; - } - - if (!is_server) { - sockaddr = (void*)addr; + if (is_server) { + status = kernel_bind(*sock, sockaddr, sizeof(*sockaddr)); + if (unlikely(status < 0)) { + MARS_ERR("bind failed, status = %d\n", status); + sock_release(*sock); + *sock = NULL; + goto done; + } + status = kernel_listen(*sock, 16); + if (status < 0) { + MARS_ERR("listen failed, status = %d\n", status); + } + } else { status = kernel_connect(*sock, sockaddr, sizeof(*sockaddr), 0); if (status < 0) { MARS_ERR("connect failed, status = %d\n", status); } } +done: return status; } EXPORT_SYMBOL_GPL(mars_create_socket); diff --git a/userspace/marsadm b/userspace/marsadm index c8c9f2ba..fa0803fe 100644 --- a/userspace/marsadm +++ b/userspace/marsadm @@ -9,7 +9,8 @@ my $mars = "/mars"; my $host = `uname -n` or die "cannot determine my network node name\n"; chomp $host; my $ip = `ip a` or die "cannot determine my IP address\n"; -$ip =~ s/\A.*inet +(?!127\.0\.)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*\Z/$1/ms or die "cannot parse my IP address\n"; +$ip =~ s/\A.*inet +(?!127\.0\.)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*?\Z/$1/ms or die "cannot parse my IP address\n"; +print "my IP is $ip\n"; umask 0177; die "only root may use this tool\n" unless `whoami` eq "root\n"; # getpid() seems to be missing in perlfunc @@ -20,7 +21,7 @@ die "only root may use this tool\n" unless `whoami` eq "root\n"; # getpid() seem sub check_id { my $str = shift; - die "identifier '$str' has disallowed characters" unless $str =~ m/^[A-Za-z_][A-Za-z0-9_]*$/; + die "identifier '$str' has disallowed characters" unless $str =~ m/^[A-Za-z_][-A-Za-z0-9_]*$/; die "identifier '$str' is too long (only 16 chars allowed)" if length($str) > 16; } @@ -214,8 +215,8 @@ sub create_res { system("rm -f $tmp/syncstatus-$host"); symlink("0", "$tmp/syncstatus-$host") or die "cannot start initial sync\n"; system("rm -f $tmp/connect-$host"); - symlink($primary, "$tmp/connect-$host") or die "cannot create peer symlink\n"; - symlink($host, "$tmp/connect-$primary") unless ( -l "$tmp/connect-$primary" or -l "$tmp/off.connect-$primary" ); + symlink($primary, "$tmp/connect-$host") or die "cannot create peer connect symlink\n"; + symlink($host, "$tmp/connect-$primary") unless -l "$tmp/connect-$primary"; print "successfully joined resource '$res'\n"; } }