[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r11907 - in gnunet: . src/arm src/include src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r11907 - in gnunet: . src/arm src/include src/util |
Date: |
Wed, 23 Jun 2010 16:23:50 +0200 |
Author: grothoff
Date: 2010-06-23 16:23:50 +0200 (Wed, 23 Jun 2010)
New Revision: 11907
Modified:
gnunet/ChangeLog
gnunet/src/arm/arm_api.c
gnunet/src/arm/do_start_process.c
gnunet/src/arm/gnunet-service-arm.c
gnunet/src/arm/gnunet-service-arm.h
gnunet/src/arm/gnunet-service-arm_interceptor.c
gnunet/src/include/gnunet_network_lib.h
gnunet/src/include/gnunet_os_lib.h
gnunet/src/util/os_priority.c
Log:
listen socket passing support for ARM
Modified: gnunet/ChangeLog
===================================================================
--- gnunet/ChangeLog 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/ChangeLog 2010-06-23 14:23:50 UTC (rev 11907)
@@ -1,3 +1,8 @@
+Wed Jun 23 16:34:38 CEST 2010
+ Added support for systemd-compatible passing of listen-sockets
+ by ARM to services as well as systemd compatibility for
gnunet-service-arm
+ itself. At least for non-MINGW systems this should work.
+
Sat Jun 5 18:08:39 CEST 2010
Added support for UNIX domain sockets, code also defaults to
them when available.
Modified: gnunet/src/arm/arm_api.c
===================================================================
--- gnunet/src/arm/arm_api.c 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/arm/arm_api.c 2010-06-23 14:23:50 UTC (rev 11907)
@@ -434,7 +434,8 @@
GNUNET_free (lopostfix);
return;
}
- pid = do_start_process (loprefix,
+ pid = do_start_process (NULL,
+ loprefix,
binary,
"-c", config,
#if DEBUG_ARM
Modified: gnunet/src/arm/do_start_process.c
===================================================================
--- gnunet/src/arm/do_start_process.c 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/arm/do_start_process.c 2010-06-23 14:23:50 UTC (rev 11907)
@@ -7,12 +7,14 @@
* limitation that it does NOT allow passing command line arguments
* with spaces to the new process.
*
+ * @param lsocks array of listen sockets to dup starting at fd3
(systemd-style), or NULL
* @param first_arg first argument for argv (may be an empty string)
* @param ... more arguments, NULL terminated
* @return PID of the started process, -1 on error
*/
static pid_t
-do_start_process (const char *first_arg, ...)
+do_start_process (const int *lsocks,
+ const char *first_arg, ...)
{
va_list ap;
char **argv;
@@ -86,7 +88,7 @@
while (NULL != (arg = (va_arg (ap, const char*))));
va_end (ap);
argv[argv_size] = NULL;
- pid = GNUNET_OS_start_process_v (argv[0], argv);
+ pid = GNUNET_OS_start_process_v (lsocks, argv[0], argv);
while (argv_size > 0)
GNUNET_free (argv[--argv_size]);
GNUNET_free (argv);
Modified: gnunet/src/arm/gnunet-service-arm.c
===================================================================
--- gnunet/src/arm/gnunet-service-arm.c 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/arm/gnunet-service-arm.c 2010-06-23 14:23:50 UTC (rev 11907)
@@ -344,7 +344,8 @@
* @param sl identifies service to start
*/
static void
-start_process (struct ServiceList *sl)
+start_process (struct ServiceList *sl,
+ const int *lsocks)
{
char *loprefix;
char *options;
@@ -415,14 +416,16 @@
sl->name, sl->binary, sl->config);
#endif
if (GNUNET_YES == use_debug)
- sl->pid = do_start_process (loprefix,
+ sl->pid = do_start_process (lsocks,
+ loprefix,
sl->binary,
"-c", sl->config,
"-L", "DEBUG",
options,
NULL);
else
- sl->pid = do_start_process (loprefix,
+ sl->pid = do_start_process (lsocks,
+ loprefix,
sl->binary,
"-c", sl->config,
options,
@@ -442,9 +445,13 @@
*
* @param client who is asking for this
* @param servicename name of the service to start
+ * @param lsocks -1 terminated list of listen sockets to pass (systemd style),
or NULL
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
-void
-start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
+int
+start_service (struct GNUNET_SERVER_Client *client,
+ const char *servicename,
+ const int *lsocks)
{
struct ServiceList *sl;
char *binary;
@@ -457,7 +464,7 @@
_("ARM is shutting down, service `%s' not started.\n"),
servicename);
signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
- return;
+ return GNUNET_SYSERR;
}
sl = find_name (servicename);
if (sl != NULL)
@@ -467,7 +474,7 @@
sl->next = running;
running = sl;
signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
- return;
+ return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -477,7 +484,7 @@
_("Binary implementing service `%s' not known!\n"),
servicename);
signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
- return;
+ return GNUNET_SYSERR;
}
if ((GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
@@ -492,7 +499,7 @@
signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
GNUNET_free (binary);
GNUNET_free_non_null (config);
- return;
+ return GNUNET_SYSERR;
}
(void) stop_listening (servicename);
sl = GNUNET_malloc (sizeof (struct ServiceList));
@@ -505,9 +512,10 @@
sl->restartAt = GNUNET_TIME_UNIT_FOREVER_ABS;
running = sl;
- start_process (sl);
+ start_process (sl, lsocks);
if (NULL != client)
signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
+ return GNUNET_OK;
}
@@ -610,7 +618,7 @@
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- start_service (client, servicename);
+ start_service (client, servicename, NULL);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -776,7 +784,7 @@
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Restarting service `%s'.\n"), pos->name);
- start_process (pos);
+ start_process (pos, NULL);
}
else
{
@@ -1071,7 +1079,7 @@
pos = strtok (defaultservices, " ");
while (pos != NULL)
{
- start_service (NULL, pos);
+ start_service (NULL, pos, NULL);
pos = strtok (NULL, " ");
}
}
Modified: gnunet/src/arm/gnunet-service-arm.h
===================================================================
--- gnunet/src/arm/gnunet-service-arm.h 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/arm/gnunet-service-arm.h 2010-06-23 14:23:50 UTC (rev 11907)
@@ -27,8 +27,17 @@
#ifndef GNUNET_SERVICE_ARM__H
#define GNUNET_SERVICE_ARM__H
-void start_service (struct GNUNET_SERVER_Client *client,
- const char *servicename);
+/**
+ * Start the specified service.
+ *
+ * @param client who is asking for this
+ * @param servicename name of the service to start
+ * @param lsocks -1 terminated list of listen sockets to pass (systemd style),
or NULL
+ * @return GNUNET_OK on success
+ */
+int start_service (struct GNUNET_SERVER_Client *client,
+ const char *servicename,
+ const int *lsocks);
/**
* Stop listening for connections to a service.
Modified: gnunet/src/arm/gnunet-service-arm_interceptor.c
===================================================================
--- gnunet/src/arm/gnunet-service-arm_interceptor.c 2010-06-23 14:23:25 UTC
(rev 11906)
+++ gnunet/src/arm/gnunet-service-arm_interceptor.c 2010-06-23 14:23:50 UTC
(rev 11907)
@@ -847,7 +847,6 @@
return ret;
}
-
/**
* First connection has come to the listening socket associated with the
service,
* create the service in order to relay the incoming connection to it
@@ -856,14 +855,15 @@
* @param tc context
*/
static void
-acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+#if MINGW
+static void
+accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
{
- struct ServiceListeningInfo *serviceListeningInfo = cls;
struct ForwardedConnection *fc;
- serviceListeningInfo->acceptTask = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
- return;
fc = GNUNET_malloc (sizeof (struct ForwardedConnection));
fc->listen_info = serviceListeningInfo;
fc->service_to_client_bufferPos = fc->service_to_client_buffer;
@@ -879,6 +879,9 @@
serviceListeningInfo->serviceName,
STRERROR (errno));
GNUNET_free (fc);
+ GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
+ serviceListeningInfoList_tail,
+ serviceListeningInfo);
serviceListeningInfo->acceptTask =
GNUNET_SCHEDULER_add_read_net (scheduler,
GNUNET_TIME_UNIT_FOREVER_REL,
@@ -889,10 +892,7 @@
}
GNUNET_break (GNUNET_OK ==
GNUNET_NETWORK_socket_close
(serviceListeningInfo->listeningSocket));
- GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
- serviceListeningInfoList_tail,
- serviceListeningInfo);
- start_service (NULL, serviceListeningInfo->serviceName);
+ start_service (NULL, serviceListeningInfo->serviceName, NULL);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Service `%s' started\n"),
fc->listen_info->serviceName);
@@ -909,9 +909,75 @@
&start_forwarding,
fc);
}
+#endif
/**
+ * First connection has come to the listening socket associated with the
service,
+ * create the service in order to relay the incoming connection to it
+ *
+ * @param cls callback data, struct ServiceListeningInfo describing a listen
socket
+ * @param tc context
+ */
+static void
+acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct ServiceListeningInfo *sli = cls;
+ struct ServiceListeningInfo *pos;
+ struct ServiceListeningInfo *next;
+ int *lsocks;
+ unsigned int ls;
+
+ sli->acceptTask = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ return;
+ GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+ serviceListeningInfoList_tail,
+ sli);
+#ifndef MINGW
+ lsocks = NULL;
+ ls = 0;
+ next = serviceListeningInfoList_head;
+ while (NULL != (pos = next))
+ {
+ next = pos->next;
+ if (0 == strcmp (pos->serviceName,
+ sli->serviceName))
+ {
+ GNUNET_array_append (lsocks, ls,
+ GNUNET_NETWORK_get_fd (pos->listeningSocket));
+ GNUNET_free (pos->listeningSocket); /* deliberately no closing! */
+ GNUNET_free (pos->service_addr);
+ GNUNET_free (pos->serviceName);
+ GNUNET_SCHEDULER_cancel (scheduler,
+ pos->acceptTask);
+ GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+ serviceListeningInfoList_tail,
+ pos);
+ GNUNET_free (pos);
+ }
+ }
+ GNUNET_array_append (lsocks, ls,
+ GNUNET_NETWORK_get_fd (sli->listeningSocket));
+ GNUNET_free (sli->listeningSocket); /* deliberately no closing! */
+ GNUNET_free (sli->service_addr);
+ GNUNET_array_append (lsocks, ls, -1);
+ start_service (NULL,
+ sli->serviceName,
+ lsocks);
+ ls = 0;
+ while (lsocks[ls] != -1)
+ GNUNET_break (0 == close (lsocks[ls++]));
+ GNUNET_array_grow (lsocks, ls, 0);
+ GNUNET_free (sli->serviceName);
+ GNUNET_free (sli);
+#else
+ accept_and_forward (sli);
+#endif
+}
+
+
+/**
* Creating a listening socket for each of the service's addresses and
* wait for the first incoming connection to it
*
Modified: gnunet/src/include/gnunet_network_lib.h
===================================================================
--- gnunet/src/include/gnunet_network_lib.h 2010-06-23 14:23:25 UTC (rev
11906)
+++ gnunet/src/include/gnunet_network_lib.h 2010-06-23 14:23:50 UTC (rev
11907)
@@ -199,6 +199,7 @@
ssize_t GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc,
const void *buffer, size_t length);
+
/**
* Send data to a particular destination (always non-blocking).
* This function only works for UDP sockets.
Modified: gnunet/src/include/gnunet_os_lib.h
===================================================================
--- gnunet/src/include/gnunet_os_lib.h 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/include/gnunet_os_lib.h 2010-06-23 14:23:50 UTC (rev 11907)
@@ -216,12 +216,15 @@
/**
* Start a process.
*
+ * @param lsocks array of listen sockets to dup systemd-style (or NULL);
+ * must be NULL on platforms where dup is not supported
* @param filename name of the binary
* @param argv NULL-terminated list of arguments to the process,
* including the process name as the first argument
* @return process ID of the new process, -1 on error
*/
-pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]);
+pid_t GNUNET_OS_start_process_v (const int *lsocks,
+ const char *filename, char *const argv[]);
/**
Modified: gnunet/src/util/os_priority.c
===================================================================
--- gnunet/src/util/os_priority.c 2010-06-23 14:23:25 UTC (rev 11906)
+++ gnunet/src/util/os_priority.c 2010-06-23 14:23:50 UTC (rev 11907)
@@ -329,16 +329,43 @@
/**
* Start a process.
*
+ * @param lsocks array of listen sockets to dup systemd-style (or NULL);
+ * must be NULL on platforms where dup is not supported
* @param filename name of the binary
* @param argv NULL-terminated list of arguments to the process
* @return process ID of the new process, -1 on error
*/
pid_t
-GNUNET_OS_start_process_v (const char *filename, char *const argv[])
+GNUNET_OS_start_process_v (const int *lsocks,
+ const char *filename, char *const argv[])
{
#ifndef MINGW
pid_t ret;
+ char lpid[16];
+ char fds[16];
+ int i;
+ int j;
+ int k;
+ int tgt;
+ int flags;
+ int *lscp;
+ unsigned int ls;
+ lscp = NULL;
+ ls = 0;
+ if (lsocks != NULL)
+ {
+ i = 0;
+ while (-1 != (k = lsocks[i++]))
+ {
+ flags = fcntl (k, F_GETFD);
+ GNUNET_assert (flags >= 0);
+ flags &= ~FD_CLOEXEC;
+ (void) fcntl (k, F_SETFD, flags);
+ GNUNET_array_append (lscp, ls, k);
+ }
+ GNUNET_array_append (lscp, ls, -1);
+ }
#if HAVE_WORKING_VFORK
ret = vfork ();
#else
@@ -366,6 +393,48 @@
}
return ret;
}
+ if (lscp != NULL)
+ {
+ /* read systemd documentation... */
+ GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid());
+ setenv ("LISTEN_PID", lpid, 1);
+ i = 0;
+ tgt = 3;
+ while (-1 != lscp[i])
+ {
+ j = i + 1;
+ while (-1 != lscp[j])
+ {
+ if (lscp[j] == tgt)
+ {
+ /* dup away */
+ k = dup (lscp[j]);
+ GNUNET_assert (-1 != k);
+ GNUNET_assert (0 == close (lscp[j]));
+ lscp[j] = k;
+ break;
+ }
+ j++;
+ }
+ if (lscp[i] != tgt)
+ {
+ /* Bury any existing FD, no matter what; they should all be closed
+ on exec anyway and the important onces have been dup'ed away */
+ (void) close (tgt);
+ GNUNET_assert (-1 != dup2 (lscp[i], tgt));
+ }
+ /* set close-on-exec flag */
+ flags = fcntl (tgt, F_GETFD);
+ GNUNET_assert (flags >= 0);
+ flags &= ~FD_CLOEXEC;
+ (void) fcntl (tgt, F_SETFD, flags);
+ tgt++;
+ i++;
+ }
+ GNUNET_snprintf (fds, sizeof (fds), "%u", i);
+ setenv ("LISTEN_FDS", fds, 1);
+ }
+ GNUNET_array_grow (lscp, ls, 0);
execvp (filename, argv);
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
_exit (1);
@@ -379,6 +448,7 @@
char *non_const_filename = NULL;
int filenamelen = 0;
+ GNUNET_assert (lsocks == NULL);
/* Count the number of arguments */
arg = argv;
while (*arg)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r11907 - in gnunet: . src/arm src/include src/util,
gnunet <=