HADOOP-9566. Performing direct read using libhdfs sometimes raises SIGPIPE (which in turn throws SIGABRT) causing client crashes. Contributed by Colin Patrick McCabe.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1483613 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
815f2d7236
commit
966b4ec5e5
|
@ -185,6 +185,10 @@ Release 2.0.5-beta - UNRELEASED
|
||||||
HADOOP-9563. Fix incompatibility introduced by HADOOP-9523.
|
HADOOP-9563. Fix incompatibility introduced by HADOOP-9523.
|
||||||
(Tian Hong Wang via suresh)
|
(Tian Hong Wang via suresh)
|
||||||
|
|
||||||
|
HADOOP-9566. Performing direct read using libhdfs sometimes raises SIGPIPE
|
||||||
|
(which in turn throws SIGABRT) causing client crashes. (Colin Patrick
|
||||||
|
McCabe via atm)
|
||||||
|
|
||||||
Release 2.0.4-alpha - 2013-04-25
|
Release 2.0.4-alpha - 2013-04-25
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#include "config.h"
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "org/apache/hadoop/io/nativeio/file_descriptor.h"
|
#include "org/apache/hadoop/io/nativeio/file_descriptor.h"
|
||||||
#include "org_apache_hadoop.h"
|
#include "org_apache_hadoop.h"
|
||||||
|
@ -31,6 +30,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/ioctl.h> /* for FIONREAD */
|
#include <sys/ioctl.h> /* for FIONREAD */
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -47,6 +47,15 @@
|
||||||
#define DEFAULT_SEND_TIMEOUT 120000
|
#define DEFAULT_SEND_TIMEOUT 120000
|
||||||
#define LISTEN_BACKLOG 128
|
#define LISTEN_BACKLOG 128
|
||||||
|
|
||||||
|
/* In Linux, you can pass the MSG_NOSIGNAL flag to send, sendto, etc. to prevent
|
||||||
|
* those functions from generating SIGPIPE. HDFS-4831 for details.
|
||||||
|
*/
|
||||||
|
#ifdef MSG_NOSIGNAL
|
||||||
|
#define PLATFORM_SEND_FLAGS MSG_NOSIGNAL
|
||||||
|
#else
|
||||||
|
#define PLATFORM_SEND_FLAGS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can't pass more than this number of file descriptors in a single message.
|
* Can't pass more than this number of file descriptors in a single message.
|
||||||
*/
|
*/
|
||||||
|
@ -176,6 +185,19 @@ static jthrowable setup(JNIEnv *env, int *ofd, jobject jpath, int doConnect)
|
||||||
"is %zd bytes.", sizeof(addr.sun_path) - 1);
|
"is %zd bytes.", sizeof(addr.sun_path) - 1);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
#ifdef SO_NOSIGPIPE
|
||||||
|
/* On MacOS and some BSDs, SO_NOSIGPIPE will keep send and sendto from causing
|
||||||
|
* EPIPE. Note: this will NOT help when using write or writev, only with
|
||||||
|
* send, sendto, sendmsg, etc. See HDFS-4831.
|
||||||
|
*/
|
||||||
|
ret = 1;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&ret, sizeof(ret))) {
|
||||||
|
ret = errno;
|
||||||
|
jthr = newSocketException(env, ret,
|
||||||
|
"error setting SO_NOSIGPIPE on socket: error %s", terror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (doConnect) {
|
if (doConnect) {
|
||||||
RETRY_ON_EINTR(ret, connect(fd,
|
RETRY_ON_EINTR(ret, connect(fd,
|
||||||
(struct sockaddr*)&addr, sizeof(addr)));
|
(struct sockaddr*)&addr, sizeof(addr)));
|
||||||
|
@ -583,7 +605,7 @@ static jthrowable write_fully(JNIEnv *env, int fd, int8_t *buf, int amt)
|
||||||
int err, res;
|
int err, res;
|
||||||
|
|
||||||
while (amt > 0) {
|
while (amt > 0) {
|
||||||
res = write(fd, buf, amt);
|
res = send(fd, buf, amt, PLATFORM_SEND_FLAGS);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
err = errno;
|
err = errno;
|
||||||
if (err == EINTR) {
|
if (err == EINTR) {
|
||||||
|
@ -685,7 +707,7 @@ jint offset, jint length)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RETRY_ON_EINTR(ret, sendmsg(fd, &socketMsg, 0));
|
RETRY_ON_EINTR(ret, sendmsg(fd, &socketMsg, PLATFORM_SEND_FLAGS));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = errno;
|
ret = errno;
|
||||||
jthr = newSocketException(env, ret, "sendmsg(2) error: %s", terror(ret));
|
jthr = newSocketException(env, ret, "sendmsg(2) error: %s", terror(ret));
|
||||||
|
|
Loading…
Reference in New Issue