ecore_con: add systemd socket activation.

Be careful, systemd socket activation require you to always order
server socket creation in the same order as defined in the unit file.
This means ecore_con_server_add should always been in the same order
for those of them using systemd socket activation.
This commit is contained in:
Cedric Bail 2013-03-10 15:49:54 +09:00
parent 12ceb717ea
commit 9176271492
7 changed files with 155 additions and 26 deletions

View File

@ -1,6 +1,7 @@
2013-03-10 Cedric Bail
* Eeze: add a dummy implementation of libmount when it is not available.
* Ecore_Con: add systemd socket activation support (ECORE_CON_SOCKET_ACTIVATE).
2013-03-08 Igor Murzov

1
NEWS
View File

@ -72,6 +72,7 @@ Additions:
* Ecore_x: Add atom related with indicator type.
* Ecore_x: Add manual render code before deiconify
* Eeze: Add a dummy libmount replacement for when libmount is not there.
* Ecore_Con: Add systemd socket activation support (ECORE_CON_SOCKET_ACTIVATE).
Deprecations:
* ecore_x:

View File

@ -1883,21 +1883,26 @@ want_ecore_con_local_sockets="yes"
want_ecore_con_abstract_sockets="yes"
if test "${have_wince}" = "yes"; then
want_systemd="no"
want_curl="no"
want_cares="no"
want_ecore_con_local_sockets="no"
want_ecore_con_abstract_sockets="no"
elif test "${have_win32}" = "yes"; then
want_systemd="no"
want_cares="yes"
want_ecore_con_abstract_sockets="no"
elif test "${have_darwin}" = "yes"; then
want_systemd="no"
want_cares="no"
want_ecore_con_abstract_sockets="no"
elif test "${have_ps3}" = "yes"; then
want_systemd="no"
want_cares="no"
want_ecore_con_local_sockets="no"
want_ecore_con_abstract_sockets="no"
else
want_systemd="yes"
want_cares="no"
fi
@ -1934,11 +1939,14 @@ else
ecore_con_resolver="fork"
fi
EFL_OPTIONAL_DEPEND_PKG([ECORE_CON], [${want_systemd}], [SYSTEMD], [libsystemd-daemon])
EFL_ADD_FEATURE([ECORE_CON], [curl])
EFL_ADD_FEATURE([ECORE_CON], [cares])
EFL_ADD_FEATURE([ECORE_CON], [local-sockets], [${want_ecore_con_local_sockets}])
EFL_ADD_FEATURE([ECORE_CON], [abstract-sockets], [${want_ecore_con_abstract_sockets}])
EFL_ADD_FEATURE([ECORE_CON], [resolver], [${ecore_con_resolver}])
EFL_ADD_FEATURE([ECORE_CON], [systemd-daemon], [${want_systemd}])
EFL_EVAL_PKGS([ECORE_CON])

View File

@ -662,7 +662,8 @@ typedef enum _Ecore_Con_Type
* @note Only functional for clients
* @since 1.2
*/
ECORE_CON_NO_PROXY = (1 << 8)
ECORE_CON_NO_PROXY = (1 << 8),
ECORE_CON_SOCKET_ACTIVATE = (1 << 9)
} Ecore_Con_Type;
/**

View File

@ -15,6 +15,10 @@
#include <arpa/inet.h>
#include <sys/un.h>
#ifdef HAVE_SYSTEMD
# include <systemd/sd-daemon.h>
#endif
#ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif
@ -88,6 +92,10 @@ static void _ecore_con_lookup_done(void *data,
static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr);
#ifdef HAVE_SYSTEMD
int sd_fd_index = 0;
int sd_fd_max = 0;
#endif
void
_ecore_con_client_kill(Ecore_Con_Client *cl)
@ -158,7 +166,6 @@ ecore_con_init(void)
#ifdef HAVE_EVIL
if (!evil_init())
return --_ecore_con_init_count;
#endif
if (!ecore_init())
@ -197,6 +204,10 @@ ecore_con_init(void)
ecore_con_ssl_init();
ecore_con_info_init();
#ifdef HAVE_SYSTEMD
sd_fd_max = sd_listen_fds(0);
#endif
return _ecore_con_init_count;
}
@ -1425,6 +1436,45 @@ _ecore_con_cb_tcp_listen(void *data,
goto error;
}
#ifdef HAVE_SYSTEMD
if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
{
if (sd_is_socket_inet(SD_LISTEN_FDS_START + sd_fd_index,
net_info->info.ai_family,
net_info->info.ai_socktype,
1,
svr->port) <= 0)
{
ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
goto error;
}
svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
/* I am wondering if that's really going to work as the bind is already done */
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
lin.l_onoff = 1;
lin.l_linger = 0;
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
sizeof(struct linger)) < 0)
goto error;
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
{
int flag = 1;
if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
sizeof(int)) < 0)
{
goto error;
}
}
goto fd_ready;
}
#endif
svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
net_info->info.ai_protocol);
if (svr->fd < 0) goto error;
@ -1439,7 +1489,7 @@ _ecore_con_cb_tcp_listen(void *data,
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
{
int flag = 1;
int flag = 1;
if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
sizeof(int)) < 0)
@ -1453,8 +1503,11 @@ _ecore_con_cb_tcp_listen(void *data,
if (listen(svr->fd, 4096) < 0) goto error;
#ifdef HAVE_SYSTEMD
fd_ready:
#endif
svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
_ecore_con_svr_tcp_handler, svr, NULL, NULL);
_ecore_con_svr_tcp_handler, svr, NULL, NULL);
if (!svr->fd_handler)
{
memerr = "Memory allocation failure";
@ -1492,7 +1545,27 @@ _ecore_con_cb_udp_listen(void *data,
svr->delete_me = EINA_TRUE;
goto error;
}
#ifdef HAVE_SYSTEMD
if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
{
if (sd_is_socket_inet(SD_LISTEN_FDS_START + sd_fd_index,
net_info->info.ai_family,
net_info->info.ai_socktype,
-1,
svr->port) <= 0)
{
ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
goto error;
}
svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0)
goto error;
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
goto fd_ready;
}
#endif
svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
net_info->info.ai_protocol);
if (svr->fd < 0) goto error;
@ -1532,6 +1605,9 @@ _ecore_con_cb_udp_listen(void *data,
if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
goto error;
#ifdef HAVE_SYSTEMD
fd_ready:
#endif
svr->fd_handler =
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
_ecore_con_svr_udp_handler, svr, NULL, NULL);

View File

@ -13,6 +13,10 @@
#include <sys/socket.h>
#include <sys/un.h>
#ifdef HAVE_SYSTEMD
# include <systemd/sd-daemon.h>
#endif
#ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif
@ -186,6 +190,7 @@ ecore_con_local_listen(
struct stat st;
mode_t mask;
int socket_unix_len;
Eina_Bool abstract_socket;
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
@ -249,6 +254,57 @@ ecore_con_local_listen(
pmode = umask(mask);
start:
socket_unix.sun_family = AF_UNIX;
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
{
abstract_socket = EINA_TRUE;
#ifdef HAVE_ABSTRACT_SOCKETS
/* . is a placeholder */
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
svr->name);
/* first char null indicates abstract namespace */
socket_unix.sun_path[0] = '\0';
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
svr->name);
#else
ERR("Your system does not support abstract sockets!");
goto error_umask;
#endif
}
else
{
abstract_socket = EINA_FALSE;
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
}
#ifdef HAVE_SYSTEMD
if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
{
if (sd_is_socket_unix(SD_LISTEN_FDS_START + sd_fd_index,
SOCK_STREAM, 1,
socket_unix.sun_path,
abstract_socket ? socket_unix_len : 0) <= 0)
{
ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
goto error_umask;
}
svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
goto error_umask;
lin.l_onoff = 1;
lin.l_linger = 0;
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
sizeof(struct linger)) < 0)
goto error_umask;
goto fd_ready;
}
#else
(void) abstract_socket;
#endif
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (svr->fd < 0)
goto error_umask;
@ -265,28 +321,6 @@ start:
sizeof(struct linger)) < 0)
goto error_umask;
socket_unix.sun_family = AF_UNIX;
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
{
#ifdef HAVE_ABSTRACT_SOCKETS
/* . is a placeholder */
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
svr->name);
/* first char null indicates abstract namespace */
socket_unix.sun_path[0] = '\0';
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
svr->name);
#else
ERR("Your system does not support abstract sockets!");
goto error_umask;
#endif
}
else
{
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
}
if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
{
if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
@ -302,6 +336,9 @@ start:
if (listen(svr->fd, 4096) < 0)
goto error_umask;
#ifdef HAVE_SYSTEMD
fd_ready:
#endif
svr->path = strdup(buf);
if (!svr->path)
goto error_umask;

View File

@ -270,6 +270,11 @@ struct Ecore_Con_Socks_v5
unsigned int plen;
};
#ifdef HAVE_SYSTEMD
extern int sd_fd_index;
extern int sd_fd_max;
#endif
extern Ecore_Con_Socks *_ecore_con_proxy_once;
extern Ecore_Con_Socks *_ecore_con_proxy_global;
void ecore_con_socks_init(void);