Re: [systemd-devel] [PATCH] core: support Distribute=n to distribute to n SO_REUSEPORT workers

2013-11-16 Thread Shawn
On Sat, Nov 16, 2013 at 7:38 AM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Fri, Nov 15, 2013 at 08:22:14PM -0800, Shawn Landden wrote:
 v3: make each worker its own service
 v4: be less intrusive
 Hi Shawn,
 unfortunately this doesn't apply cleanly. Can you rebase?
thats because it is 3rd in a series, I will send the whole series
right after this email

 diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
 index 7c10c58..92a9275 100644
 --- a/man/systemd.socket.xml
 +++ b/man/systemd.socket.xml
 @@ -519,6 +519,15 @@
  /varlistentry

  varlistentry
 +termvarnameDistribute=/varname/term
 +listitemparaTakes an integer
 +value. If greater than one, systemd will 
 spawn
 +given number of instances of service each
 +listening to the same socket. This option 
 implies
 +varnameReuseport=/varname 
 above./para/listitem
 +/varlistentry
 +
 +varlistentry
  termvarnameSmackLabel=/varname/term
  
 termvarnameSmackLabelIPIn=/varname/term
  
 termvarnameSmackLabelIPOut=/varname/term
 diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
 index 60a8d05..4644007 100644
 --- a/src/core/dbus-socket.c
 +++ b/src/core/dbus-socket.c
 @@ -68,6 +68,7 @@
property name=\Listen\ type=\a(ss)\ access=\read\/\n
 \
property name=\Result\ type=\s\ access=\read\/\n\
property name=\ReusePort\ type=\b\ access=\read\/\n \
 +  property name=\Distribute\ type=\u\ access=\read\/\n \
property name=\SmackLabel\ type=\s\ access=\read\/\n \
property name=\SmackLabelIPIn\ type=\s\ 
 access=\read\/\n \
property name=\SmackLabelIPOut\ type=\s\ 
 access=\read\/\n \
 @@ -196,6 +197,7 @@ static const BusProperty bus_socket_properties[] = {
  { MessageQueueMessageSize, bus_property_append_long, x, 
 offsetof(Socket, mq_msgsize)  },
  { Result, bus_socket_append_socket_result,   s, 
 offsetof(Socket, result)  },
  { ReusePort,  bus_property_append_bool,  b, 
 offsetof(Socket, reuseport)   },
 +{ Distribute, bus_property_append_unsigned,  u, 
 offsetof(Socket, distribute)   },
  { SmackLabel, bus_property_append_string,s, 
 offsetof(Socket, smack),  true },
  { SmackLabelIPIn, bus_property_append_string,s, 
 offsetof(Socket, smack_ip_in),true },
  { SmackLabelIPOut,bus_property_append_string,s, 
 offsetof(Socket, smack_ip_out),   true },
 diff --git a/src/core/load-fragment-gperf.gperf.m4 
 b/src/core/load-fragment-gperf.gperf.m4
 index b64fdc9..4058a1f 100644
 --- a/src/core/load-fragment-gperf.gperf.m4
 +++ b/src/core/load-fragment-gperf.gperf.m4
 @@ -211,6 +211,7 @@ Socket.PassCredentials,  config_parse_bool,  
 0,
  Socket.PassSecurity, config_parse_bool,  0, 
 offsetof(Socket, pass_sec)
  Socket.TCPCongestion,config_parse_string,0, 
 offsetof(Socket, tcp_congestion)
  Socket.ReusePort,config_parse_bool,  0, 
 offsetof(Socket, reuseport)
 +Socket.Distribute,   config_parse_unsigned,  0, 
 offsetof(Socket, distribute)
  Socket.MessageQueueMaxMessages,  config_parse_long,  0, 
 offsetof(Socket, mq_maxmsg)
  Socket.MessageQueueMessageSize,  config_parse_long,  0, 
 offsetof(Socket, mq_msgsize)
  Socket.Service,  config_parse_socket_service,0, 
 0
 diff --git a/src/core/service.c b/src/core/service.c
 index 3da32a1..8fc55a0 100644
 --- a/src/core/service.c
 +++ b/src/core/service.c
 @@ -3663,7 +3663,6 @@ static void service_bus_query_pid_done(
  int service_set_socket_fd(Service *s, int fd, Socket *sock) {

  assert(s);
 -assert(fd = 0);

  /* This is called by the socket code when instantiating a new
   * service for a stream socket and the socket needs to be
 @@ -3678,8 +3677,10 @@ int service_set_socket_fd(Service *s, int fd, Socket 
 *sock) {
  if (s-state != SERVICE_DEAD)
  return -EAGAIN;

 -s-socket_fd = fd;
 -s-got_socket_fd = true;
 +if (fd = 0) {
 +s-socket_fd = fd;
 +s-got_socket_fd = true;
 +}

  unit_ref_set(s-accept_socket, UNIT(sock));

 diff --git a/src/core/service.h b/src/core/service.h
 index 

[systemd-devel] [PATCH] core: support Distribute=n to distribute to n SO_REUSEPORT workers

2013-11-15 Thread Shawn Landden
v3: make each worker its own service
v4: be less intrusive
---
 TODO  |   3 -
 man/systemd.socket.xml|   9 +++
 src/core/dbus-socket.c|   2 +
 src/core/load-fragment-gperf.gperf.m4 |   1 +
 src/core/service.c|   7 ++-
 src/core/service.h|   1 -
 src/core/socket.c | 114 --
 src/core/socket.h |   4 ++
 8 files changed, 86 insertions(+), 55 deletions(-)

diff --git a/TODO b/TODO
index 57e1122..38cdf5d 100644
--- a/TODO
+++ b/TODO
@@ -82,8 +82,6 @@ Features:
 
 * rfkill,backlight: we probably should run the load tools inside of the udev 
rules so that the state is properly initialized by the time other software sees 
it
 
-* Add a new Distribute=$NUMBER key to socket units that makes use of 
SO_REUSEPORT to distribute network traffic on $NUMBER instances
-
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
 
 * we probably should replace the left-over uses of strv_append() and replace 
them by strv_push() or strv_extend()
@@ -261,7 +259,6 @@ Features:
 * teach ConditionKernelCommandLine= globs or regexes (in order to match 
foobar={no,0,off})
 
 * Support SO_REUSEPORT with socket activation:
-  - Let systemd maintain a pool of servers.
   - Use for seamless upgrades, by running the new server before stopping the
 old.
 
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 7c10c58..92a9275 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -519,6 +519,15 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. If greater than one, systemd will spawn
+given number of instances of service each
+listening to the same socket. This option 
implies
+varnameReuseport=/varname 
above./para/listitem
+/varlistentry
+
+varlistentry
 termvarnameSmackLabel=/varname/term
 termvarnameSmackLabelIPIn=/varname/term
 
termvarnameSmackLabelIPOut=/varname/term
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 60a8d05..4644007 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -68,6 +68,7 @@
   property name=\Listen\ type=\a(ss)\ access=\read\/\n\
   property name=\Result\ type=\s\ access=\read\/\n\
   property name=\ReusePort\ type=\b\ access=\read\/\n \
+  property name=\Distribute\ type=\u\ access=\read\/\n \
   property name=\SmackLabel\ type=\s\ access=\read\/\n \
   property name=\SmackLabelIPIn\ type=\s\ access=\read\/\n \
   property name=\SmackLabelIPOut\ type=\s\ access=\read\/\n \
@@ -196,6 +197,7 @@ static const BusProperty bus_socket_properties[] = {
 { MessageQueueMessageSize, bus_property_append_long, x, 
offsetof(Socket, mq_msgsize)  },
 { Result, bus_socket_append_socket_result,   s, 
offsetof(Socket, result)  },
 { ReusePort,  bus_property_append_bool,  b, 
offsetof(Socket, reuseport)   },
+{ Distribute, bus_property_append_unsigned,  u, 
offsetof(Socket, distribute)   },
 { SmackLabel, bus_property_append_string,s, 
offsetof(Socket, smack),  true },
 { SmackLabelIPIn, bus_property_append_string,s, 
offsetof(Socket, smack_ip_in),true },
 { SmackLabelIPOut,bus_property_append_string,s, 
offsetof(Socket, smack_ip_out),   true },
diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index b64fdc9..4058a1f 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -211,6 +211,7 @@ Socket.PassCredentials,  config_parse_bool, 
 0,
 Socket.PassSecurity, config_parse_bool,  0,
 offsetof(Socket, pass_sec)
 Socket.TCPCongestion,config_parse_string,0,
 offsetof(Socket, tcp_congestion)
 Socket.ReusePort,config_parse_bool,  0,
 offsetof(Socket, reuseport)
+Socket.Distribute,   config_parse_unsigned,  0,
 offsetof(Socket, distribute)
 Socket.MessageQueueMaxMessages,  config_parse_long,  0,
 offsetof(Socket, mq_maxmsg)
 Socket.MessageQueueMessageSize,  config_parse_long,  0,
 offsetof(Socket, 

[systemd-devel] [PATCH] core: support Distribute=n to distribute to n SO_REUSEPORT workers

2013-11-14 Thread Shawn Landden
Should SERVICE_SIMPLE test be a load-time test?

v2 fix assert order
---
 TODO  |  3 +-
 src/core/dbus-socket.c|  2 ++
 src/core/load-fragment-gperf.gperf.m4 |  1 +
 src/core/service.c|  2 +-
 src/core/service.h| 13 ++-
 src/core/socket.c | 64 +++
 src/core/socket.h |  2 ++
 7 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/TODO b/TODO
index efc7e2a..0db4dc6 100644
--- a/TODO
+++ b/TODO
@@ -80,7 +80,7 @@ Features:
 
 * rfkill,backlight: we probably should run the load tools inside of the udev 
rules so that the state is properly initialized by the time other software sees 
it
 
-* Add a new Distribute=$NUMBER key to socket units that makes use of 
SO_REUSEPORT to distribute network traffic on $NUMBER instances
+* respawn Distribute= worker threads when they die unexpectedly
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
 
@@ -259,7 +259,6 @@ Features:
 * teach ConditionKernelCommandLine= globs or regexes (in order to match 
foobar={no,0,off})
 
 * Support SO_REUSEPORT with socket activation:
-  - Let systemd maintain a pool of servers.
   - Use for seamless upgrades, by running the new server before stopping the
 old.
 
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 60a8d05..4644007 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -68,6 +68,7 @@
   property name=\Listen\ type=\a(ss)\ access=\read\/\n\
   property name=\Result\ type=\s\ access=\read\/\n\
   property name=\ReusePort\ type=\b\ access=\read\/\n \
+  property name=\Distribute\ type=\u\ access=\read\/\n \
   property name=\SmackLabel\ type=\s\ access=\read\/\n \
   property name=\SmackLabelIPIn\ type=\s\ access=\read\/\n \
   property name=\SmackLabelIPOut\ type=\s\ access=\read\/\n \
@@ -196,6 +197,7 @@ static const BusProperty bus_socket_properties[] = {
 { MessageQueueMessageSize, bus_property_append_long, x, 
offsetof(Socket, mq_msgsize)  },
 { Result, bus_socket_append_socket_result,   s, 
offsetof(Socket, result)  },
 { ReusePort,  bus_property_append_bool,  b, 
offsetof(Socket, reuseport)   },
+{ Distribute, bus_property_append_unsigned,  u, 
offsetof(Socket, distribute)   },
 { SmackLabel, bus_property_append_string,s, 
offsetof(Socket, smack),  true },
 { SmackLabelIPIn, bus_property_append_string,s, 
offsetof(Socket, smack_ip_in),true },
 { SmackLabelIPOut,bus_property_append_string,s, 
offsetof(Socket, smack_ip_out),   true },
diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index b64fdc9..4058a1f 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -211,6 +211,7 @@ Socket.PassCredentials,  config_parse_bool, 
 0,
 Socket.PassSecurity, config_parse_bool,  0,
 offsetof(Socket, pass_sec)
 Socket.TCPCongestion,config_parse_string,0,
 offsetof(Socket, tcp_congestion)
 Socket.ReusePort,config_parse_bool,  0,
 offsetof(Socket, reuseport)
+Socket.Distribute,   config_parse_unsigned,  0,
 offsetof(Socket, distribute)
 Socket.MessageQueueMaxMessages,  config_parse_long,  0,
 offsetof(Socket, mq_maxmsg)
 Socket.MessageQueueMessageSize,  config_parse_long,  0,
 offsetof(Socket, mq_msgsize)
 Socket.Service,  config_parse_socket_service,0,
 0
diff --git a/src/core/service.c b/src/core/service.c
index 3da32a1..cc337cf 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1668,7 +1668,7 @@ fail:
 return r;
 }
 
-static int service_spawn(
+int service_spawn(
 Service *s,
 ExecCommand *c,
 bool timeout,
diff --git a/src/core/service.h b/src/core/service.h
index 37fa6ff..95aa707 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -26,7 +26,6 @@ typedef struct Service Service;
 #include unit.h
 #include path.h
 #include ratelimit.h
-#include service.h
 #include kill.h
 #include exit-status.h
 
@@ -201,6 +200,18 @@ extern const UnitVTable service_vtable;
 
 struct Socket;
 
+int service_spawn(
+Service *s,
+ExecCommand *c,
+bool timeout,
+bool pass_fds,
+bool apply_permissions,
+bool apply_chroot,
+bool apply_tty_stdin,
+