summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ndmpd/ndmp.xml5
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd.h4
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c28
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_data.c16
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c118
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_util.c83
6 files changed, 104 insertions, 150 deletions
diff --git a/usr/src/cmd/ndmpd/ndmp.xml b/usr/src/cmd/ndmpd/ndmp.xml
index 01a4fa2fe9..b2d36d7061 100644
--- a/usr/src/cmd/ndmpd/ndmp.xml
+++ b/usr/src/cmd/ndmpd/ndmp.xml
@@ -2,6 +2,7 @@
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright 2014 Nexenta Systems, Inc. All rights reserved.
NOTE: This service manifest is not editable; its contents will
be overwritten by package or patch operations, including
@@ -131,8 +132,8 @@ POSSIBILITY OF SUCH DAMAGE.
<propval name='fh-inode' type='boolean' value='false' />
<propval name='include-lmtime' type='boolean' value='false' />
<propval name='restore-fullpath' type='boolean' value='false' />
- <propval name='socket-css' type='integer' value='65' />
- <propval name='socket-crs' type='integer' value='80' />
+ <propval name='socket-css' type='integer' value='60' />
+ <propval name='socket-crs' type='integer' value='60' />
<propval name='mover-recordsize' type='integer' value='60' />
<propval name='restore-wildcard-enable' type='boolean' value='false' />
<propval name='tcp-port' type='integer' value='10000' />
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd.h b/usr/src/cmd/ndmpd/ndmp/ndmpd.h
index c2538f28c3..2472ca04bc 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd.h
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd.h
@@ -896,9 +896,7 @@ extern int ndmp_mtioctl(int, int, int);
extern u_longlong_t quad_to_long_long(ndmp_u_quad);
extern ndmp_u_quad long_long_to_quad(u_longlong_t);
-extern void ndmp_set_socket_nodelay(int);
-extern void ndmp_set_socket_snd_buf(int, int);
-extern void ndmp_set_socket_rcv_buf(int, int);
+extern void set_socket_options(int sock);
extern long ndmp_buffer_get_size(ndmpd_session_t *);
extern int ndmp_lbr_init(ndmpd_session_t *);
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c
index e759e5e1c0..4acd554f92 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -266,11 +267,10 @@ int
ndmp_run(ulong_t port, ndmp_con_handler_func_t con_handler_func)
{
int ns;
- int on, tmp;
+ int on;
int server_socket;
unsigned int ipaddr;
struct sockaddr_in sin;
- int flag = 1;
ndmpd_worker_arg_t *argp;
sin.sin_family = AF_INET;
@@ -303,30 +303,8 @@ ndmp_run(ulong_t port, ndmp_con_handler_func_t con_handler_func)
NDMP_LOG(LOG_DEBUG, "tcp_accept error: %m");
continue;
}
-
NDMP_LOG(LOG_DEBUG, "connection fd: %d", ns);
-
- /*
- * 'css' and 'crs' in the following env variables stand for:
- * 'connection send size' and 'connection receive size'.
- */
- tmp = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CSS,
- "65"));
- if (tmp <= 0)
- tmp = 65;
- NDMP_LOG(LOG_DEBUG, "css: %d_KB", tmp);
- ndmp_set_socket_snd_buf(ns, tmp * KILOBYTE);
-
- tmp = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CRS,
- "80"));
- if (tmp <= 0)
- tmp = 80;
- NDMP_LOG(LOG_DEBUG, "crs: %d_KB", tmp);
- ndmp_set_socket_rcv_buf(ns, tmp * KILOBYTE);
-
- ndmp_set_socket_nodelay(ns);
- (void) setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, &flag,
- sizeof (flag));
+ set_socket_options(ns);
if ((argp = ndmp_malloc(sizeof (ndmpd_worker_arg_t))) != NULL) {
argp->nw_sock = ns;
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
index 24f28f1dcc..9350cb05f7 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -1251,7 +1252,6 @@ data_accept_connection_v3(void *cookie, int fd, ulong_t mode)
ndmpd_session_t *session = (ndmpd_session_t *)cookie;
int from_len;
struct sockaddr_in from;
- int flag = 1;
from_len = sizeof (from);
session->ns_data.dd_sock = accept(fd, (struct sockaddr *)&from,
@@ -1279,18 +1279,8 @@ data_accept_connection_v3(void *cookie, int fd, ulong_t mode)
session->ns_data.dd_data_addr.tcp_ip_v3 = from.sin_addr.s_addr;
session->ns_data.dd_data_addr.tcp_port_v3 = ntohs(from.sin_port);
- /*
- * Set the parameter of the new socket.
- */
- (void) setsockopt(session->ns_data.dd_sock, SOL_SOCKET, SO_KEEPALIVE,
- &flag, sizeof (flag));
- ndmp_set_socket_nodelay(session->ns_data.dd_sock);
- if (ndmp_sbs > 0)
- ndmp_set_socket_snd_buf(session->ns_data.dd_sock,
- ndmp_sbs * KILOBYTE);
- if (ndmp_rbs > 0)
- ndmp_set_socket_rcv_buf(session->ns_data.dd_sock,
- ndmp_rbs * KILOBYTE);
+ /* Set the parameter of the new socket */
+ set_socket_options(session->ns_data.dd_sock);
session->ns_data.dd_state = NDMP_DATA_STATE_CONNECTED;
}
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
index ce93c0f842..e8d84b6d93 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
@@ -88,9 +88,10 @@ static void mover_data_read_v3(void *cookie, int fd, ulong_t mode);
static void accept_connection(void *cookie, int fd, ulong_t mode);
static void mover_data_write_v3(void *cookie, int fd, ulong_t mode);
static void accept_connection_v3(void *cookie, int fd, ulong_t mode);
-static ndmp_error mover_connect_sock_v3(ndmpd_session_t *session,
+static ndmp_error mover_connect_sock(ndmpd_session_t *session,
ndmp_mover_mode mode, ulong_t addr, ushort_t port);
static boolean_t is_writer_running(ndmpd_session_t *session);
+static int set_socket_nonblock(int sock);
int ndmp_max_mover_recsize = MAX_MOVER_RECSIZE; /* patchable */
@@ -99,6 +100,20 @@ int ndmp_max_mover_recsize = MAX_MOVER_RECSIZE; /* patchable */
#define TAPE_NO_WRITER_ERR -2
/*
+ * Set non-blocking mode for socket.
+ */
+static int
+set_socket_nonblock(int sock)
+{
+ int flags;
+
+ flags = fcntl(sock, F_GETFL, 0);
+ if (flags < 0)
+ return (0);
+ return (fcntl(sock, F_SETFL, flags|O_NONBLOCK) == 0);
+}
+
+/*
* ************************************************************************
* NDMP V2 HANDLERS
* ************************************************************************
@@ -1069,7 +1084,7 @@ ndmpd_mover_connect_v3(ndmp_connection_t *connection, void *body)
break;
case NDMP_ADDR_TCP:
- reply.error = mover_connect_sock_v3(session, request->mode,
+ reply.error = mover_connect_sock(session, request->mode,
request->addr.tcp_ip_v3, request->addr.tcp_port_v3);
break;
@@ -1326,7 +1341,7 @@ ndmpd_mover_connect_v4(ndmp_connection_t *connection, void *body)
break;
case NDMP_ADDR_TCP:
- reply.error = mover_connect_sock_v3(session, request->mode,
+ reply.error = mover_connect_sock(session, request->mode,
request->addr.tcp_ip_v4(0), request->addr.tcp_port_v4(0));
break;
@@ -1906,7 +1921,6 @@ ndmpd_mover_connect(ndmpd_session_t *session, ndmp_mover_mode mover_mode)
ndmp_mover_addr *mover = &session->ns_data.dd_mover;
struct sockaddr_in sin;
int sock = -1;
- int flag = 1;
if (mover->addr_type == NDMP_ADDR_TCP) {
if (mover->ndmp_mover_addr_u.addr.ip_addr) {
@@ -1946,17 +1960,7 @@ ndmpd_mover_connect(ndmpd_session_t *session, ndmp_mover_mode mover_mode)
(void) close(sock);
return (NDMP_IO_ERR);
}
-
- if (ndmp_sbs > 0)
- ndmp_set_socket_snd_buf(sock,
- ndmp_sbs * KILOBYTE);
- if (ndmp_rbs > 0)
- ndmp_set_socket_rcv_buf(sock,
- ndmp_rbs * KILOBYTE);
-
- ndmp_set_socket_nodelay(sock);
- (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &flag,
- sizeof (flag));
+ set_socket_options(sock);
} else {
if ((session->ns_mover.md_state !=
NDMP_MOVER_STATE_ACTIVE) ||
@@ -2179,7 +2183,6 @@ create_listen_socket_v2(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
return (0);
}
-
/*
* accept_connection
*
@@ -2202,7 +2205,6 @@ accept_connection(void *cookie, int fd, ulong_t mode)
ndmpd_session_t *session = (ndmpd_session_t *)cookie;
struct sockaddr_in from;
int from_len;
- int flag = 1;
from_len = sizeof (from);
session->ns_mover.md_sock = accept(fd, (struct sockaddr *)&from,
@@ -2217,12 +2219,7 @@ accept_connection(void *cookie, int fd, ulong_t mode)
ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_ERROR);
return;
}
-
- (void) setsockopt(session->ns_mover.md_sock, SOL_SOCKET, SO_KEEPALIVE,
- &flag, sizeof (flag));
- ndmp_set_socket_nodelay(session->ns_mover.md_sock);
- ndmp_set_socket_rcv_buf(session->ns_mover.md_sock, 60 * KILOBYTE);
- ndmp_set_socket_snd_buf(session->ns_mover.md_sock, 60 * KILOBYTE);
+ set_socket_options(session->ns_mover.md_sock);
NDMP_LOG(LOG_DEBUG, "sock fd: %d", session->ns_mover.md_sock);
@@ -3703,11 +3700,21 @@ mover_data_read_v3(void *cookie, int fd, ulong_t mode)
* connection has been closed.
*/
if (n <= 0) {
- if (n < 0 && errno == EWOULDBLOCK) {
- NDMP_LOG(LOG_DEBUG, "n %d errno %d", n, errno);
- return;
+ if (n == 0) {
+ NDMP_LOG(LOG_DEBUG, "Data connection closed");
+ ndmpd_mover_error(session,
+ NDMP_MOVER_HALT_CONNECT_CLOSED);
+ } else {
+ /* Socket is non-blocking, perhaps there are no data */
+ if (errno == EAGAIN) {
+ NDMP_LOG(LOG_ERR, "No data to read");
+ return;
+ }
+
+ NDMP_LOG(LOG_ERR, "Failed to read from socket: %m");
+ ndmpd_mover_error(session,
+ NDMP_MOVER_HALT_INTERNAL_ERROR);
}
- NDMP_LOG(LOG_DEBUG, "n %d errno %d", n, errno);
/* Save the index since mover_tape_flush_v3 resets it. */
index = session->ns_mover.md_w_index;
@@ -3718,13 +3725,6 @@ mover_data_read_v3(void *cookie, int fd, ulong_t mode)
session->ns_mover.md_record_num++;
}
- if (n == 0)
- ndmpd_mover_error(session,
- NDMP_MOVER_HALT_CONNECT_CLOSED);
- else
- ndmpd_mover_error(session,
- NDMP_MOVER_HALT_INTERNAL_ERROR);
-
return;
}
@@ -3984,12 +3984,12 @@ mover_data_write_v3(void *cookie, int fd, ulong_t mode)
&session->ns_mover.md_buf[session->ns_mover.md_r_index], len);
if (n < 0) {
- if (errno == EWOULDBLOCK) {
- NDMP_LOG(LOG_DEBUG, "n %d errno %d", n, errno);
+ /* Socket is non-blocking, perhaps the write queue is full */
+ if (errno == EAGAIN) {
+ NDMP_LOG(LOG_ERR, "Cannot write to socket");
return;
}
-
- NDMP_LOG(LOG_DEBUG, "n %d errno %d", n, errno);
+ NDMP_LOG(LOG_ERR, "Failed to write to socket: %m");
ndmpd_mover_error(session, NDMP_MOVER_HALT_CONNECT_CLOSED);
return;
}
@@ -4046,7 +4046,6 @@ accept_connection_v3(void *cookie, int fd, ulong_t mode)
ndmpd_session_t *session = (ndmpd_session_t *)cookie;
int from_len;
struct sockaddr_in from;
- int flag = 1;
from_len = sizeof (from);
session->ns_mover.md_sock = accept(fd, (struct sockaddr *)&from,
@@ -4071,19 +4070,21 @@ accept_connection_v3(void *cookie, int fd, ulong_t mode)
session->ns_mover.md_data_addr.tcp_ip_v3 = from.sin_addr.s_addr;
session->ns_mover.md_data_addr.tcp_port_v3 = ntohs(from.sin_port);
+ /* Set the parameter of the new socket */
+ set_socket_options(session->ns_mover.md_sock);
+
/*
- * Set the parameter of the new socket.
+ * Backup/restore is handled by a callback called from main event loop,
+ * which reads/writes data to md_sock socket. IO on socket must be
+ * non-blocking, otherwise ndmpd would be unable to process other
+ * incoming requests.
*/
- (void) setsockopt(session->ns_mover.md_sock, SOL_SOCKET, SO_KEEPALIVE,
- &flag, sizeof (flag));
-
- ndmp_set_socket_nodelay(session->ns_mover.md_sock);
- if (ndmp_sbs > 0)
- ndmp_set_socket_snd_buf(session->ns_mover.md_sock,
- ndmp_sbs*KILOBYTE);
- if (ndmp_rbs > 0)
- ndmp_set_socket_rcv_buf(session->ns_mover.md_sock,
- ndmp_rbs*KILOBYTE);
+ if (!set_socket_nonblock(session->ns_mover.md_sock)) {
+ NDMP_LOG(LOG_ERR, "Could not set non-blocking mode "
+ "on socket: %m");
+ ndmpd_mover_error(session, NDMP_MOVER_HALT_INTERNAL_ERROR);
+ return;
+ }
NDMP_LOG(LOG_DEBUG, "sock fd: %d", session->ns_mover.md_sock);
@@ -4148,7 +4149,7 @@ create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
/*
- * mover_connect_sock_v3
+ * mover_connect_sock
*
* Connect the mover to the specified address
*
@@ -4162,7 +4163,7 @@ create_listen_socket_v3(ndmpd_session_t *session, ulong_t *addr, ushort_t *port)
* error code.
*/
static ndmp_error
-mover_connect_sock_v3(ndmpd_session_t *session, ndmp_mover_mode mode,
+mover_connect_sock(ndmpd_session_t *session, ndmp_mover_mode mode,
ulong_t addr, ushort_t port)
{
int sock;
@@ -4171,6 +4172,19 @@ mover_connect_sock_v3(ndmpd_session_t *session, ndmp_mover_mode mode,
if (sock < 0)
return (NDMP_CONNECT_ERR);
+ /*
+ * Backup/restore is handled by a callback called from main event loop,
+ * which reads/writes data to md_sock socket. IO on socket must be
+ * non-blocking, otherwise ndmpd would be unable to process other
+ * incoming requests.
+ */
+ if (!set_socket_nonblock(sock)) {
+ NDMP_LOG(LOG_ERR, "Could not set non-blocking mode "
+ "on socket: %m");
+ (void) close(sock);
+ return (NDMP_CONNECT_ERR);
+ }
+
if (mode == NDMP_MOVER_MODE_READ) {
if (ndmpd_add_file_handler(session, (void*)session, sock,
NDMPD_SELECT_MODE_READ, HC_MOVER, mover_data_read_v3) < 0) {
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
index 3213f8c53b..c053e7cb9d 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_util.c
@@ -40,7 +40,6 @@
/* Copyright 2014 Nexenta Systems, Inc. All rights reserved. */
#include <sys/types.h>
-#include <sys/socket.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -66,15 +65,6 @@
#include "tlm.h"
/*
- * Patchable socket buffer sizes in kilobytes.
- * ssb: send buffer size.
- * rsb: receive buffer size.
- */
-int ndmp_sbs = 60;
-int ndmp_rbs = 60;
-
-
-/*
* Force to backup all the intermediate directories leading to an object
* to be backed up in 'dump' format backup.
*/
@@ -933,44 +923,36 @@ long_long_to_quad(u_longlong_t ull)
return (q);
}
-
-/*
- * ndmp_set_socket_nodelay
- *
- * Set the TCP socket option to nodelay mode
- */
void
-ndmp_set_socket_nodelay(int sock)
+set_socket_options(int sock)
{
- int flag = 1;
+ int val;
- (void) setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag));
-}
+ /* set send buffer size */
+ val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CSS, "60"));
+ if (val <= 0)
+ val = 60;
+ val <<= 10; /* convert the value from kilobytes to bytes */
+ if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof (val)) < 0)
+ NDMP_LOG(LOG_ERR, "SO_SNDBUF failed: %m");
+ /* set receive buffer size */
+ val = atoi((const char *)ndmpd_get_prop_default(NDMP_SOCKET_CRS, "60"));
+ if (val <= 0)
+ val = 60;
+ val <<= 10; /* convert the value from kilobytes to bytes */
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val)) < 0)
+ NDMP_LOG(LOG_ERR, "SO_RCVBUF failed: %m");
-/*
- * ndmp_set_socket_snd_buf
- *
- * Set the socket send buffer size
- */
-void
-ndmp_set_socket_snd_buf(int sock, int size)
-{
- if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
- NDMP_LOG(LOG_DEBUG, "SO_SNDBUF failed errno=%d", errno);
-}
+ /* don't wait to group tcp data */
+ val = 1;
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)) != 0)
+ NDMP_LOG(LOG_ERR, "TCP_NODELAY failed: %m");
-
-/*
- * ndmp_set_socket_rcv_buf
- *
- * Set the socket receive buffer size
- */
-void
-ndmp_set_socket_rcv_buf(int sock, int size)
-{
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
- NDMP_LOG(LOG_DEBUG, "SO_RCVBUF failed errno=%d", errno);
+ /* tcp keep-alive */
+ val = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof (val)) != 0)
+ NDMP_LOG(LOG_ERR, "SO_KEEPALIVE failed: %m");
}
/*
@@ -1950,7 +1932,6 @@ ndmp_connect_sock_v3(ulong_t addr, ushort_t port)
{
int sock;
struct sockaddr_in sin;
- int flag = 1;
NDMP_LOG(LOG_DEBUG, "addr %s:%d", inet_ntoa(IN_ADDR(addr)), port);
@@ -1967,20 +1948,12 @@ ndmp_connect_sock_v3(ulong_t addr, ushort_t port)
if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
NDMP_LOG(LOG_DEBUG, "Connect error: %m");
(void) close(sock);
- sock = -1;
- } else {
- if (ndmp_sbs > 0)
- ndmp_set_socket_snd_buf(sock, ndmp_sbs*KILOBYTE);
- if (ndmp_rbs > 0)
- ndmp_set_socket_rcv_buf(sock, ndmp_rbs*KILOBYTE);
-
- ndmp_set_socket_nodelay(sock);
- (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &flag,
- sizeof (flag));
-
- NDMP_LOG(LOG_DEBUG, "sock %d", sock);
+ return (-1);
}
+ set_socket_options(sock);
+ NDMP_LOG(LOG_DEBUG, "sock %d", sock);
+
return (sock);
}