diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp.xml | 5 | ||||
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_comm.c | 28 | ||||
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_data.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c | 118 | ||||
-rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_util.c | 83 |
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); } |