cmogstored.git  about / heads / tags
alternative mogstored implementation for MogileFS
blob e1f0168372c4a42ca0232bb92768ba95e9fc7d37 1567 bytes (raw)
$ git show wip-1.3:bind_listen.c	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 
/*
 * Copyright (C) 2012-2013, Eric Wong <normalperson@yhbt.net>
 * License: GPLv3 or later (see COPYING for details)
 */
#include "cmogstored.h"

/*
 * TODO
 * - configurable socket buffer sizes (where to put config?)
 * - configurable listen() backlog (where to put config?)
 *
 * TCP_DEFER_ACCEPT is probably not worth using on Linux
 * ref:
 *   https://bugs.launchpad.net/ubuntu/+source/apache2/+bug/134274
 *   http://labs.apnic.net/blabs/?p=57
 */

static int set_tcp_opts(int fd)
{
	int val;
	socklen_t len = sizeof(int);
	int rc;

	val = 1;
	rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, len);
	if (rc < 0) return rc;

	val = 1;
	rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, len);
	if (rc < 0) return rc;

	val = 1;
	rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, len);
	if (rc < 0) return rc;

	return rc;
}

int mog_bind_listen(struct addrinfo *r)
{
	/* see if we inherited the socket, first */
	int fd = mog_inherit_get(r->ai_addr, r->ai_addrlen);

	if (fd >= 0)
		return fd;

	for (; r; r = r->ai_next) {
		fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
		if (fd < 0)
			continue;

		/*
		 * We'll need to unset FD_CLOEXEC in the child for upgrades
		 * Leave FD_CLOEXEC set because we fork+exec iostat(1)
		 * frequently.  We can't guarantee SOCK_CLOEXEC works
		 * everywhere yet (in 2012).
		 */
		if (mog_set_cloexec(fd, true) == 0 &&
		    set_tcp_opts(fd) == 0 &&
		    bind(fd, r->ai_addr, r->ai_addrlen) == 0 &&
		    listen(fd, 1024) == 0)
			break;

		PRESERVE_ERRNO( mog_close(fd) );
		fd = -1;
	}

	return fd;
}

git clone https://yhbt.net/cmogstored.git