[systemd-devel] [PATCH] shared: rename hasprefix() to startswith(), which is functionally identical and removed

2013-07-12 Thread Shawn Landden
as most (if not all) of the prefix strings are static, these will get
forward constant propagation optimized into single memcmp() calls, which
should be much better than the non-SIMD hand-rolled version.
---
 src/journal/journal-send.c |  2 +-
 src/journal/journald-native.c  | 12 ++--
 src/libsystemd-bus/bus-match.c | 26 +-
 src/shared/logs-show.c |  2 +-
 src/shared/macro.h |  2 +-
 src/shared/util.c  | 17 -
 src/shared/util.h  |  1 -
 7 files changed, 22 insertions(+), 40 deletions(-)

diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index fef66fc..d00e26f 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -245,7 +245,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int 
n) {
 
 have_syslog_identifier = have_syslog_identifier ||
 (c == (char *) iov[i].iov_base + 17 
- hasprefix(iov[i].iov_base, SYSLOG_IDENTIFIER));
+ startswith(iov[i].iov_base, SYSLOG_IDENTIFIER));
 
 nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
 if (nl) {
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 0f9af37..c50cf64 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -154,23 +154,23 @@ void server_process_native_message(
  * of this entry for the rate limiting
  * logic */
 if (l == 10 
-hasprefix(p, PRIORITY=) 
+startswith(p, PRIORITY=) 
 p[9] = '0'  p[9] = '9')
 priority = (priority  LOG_FACMASK) | 
(p[9] - '0');
 
 else if (l == 17 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9')
 priority = (priority  LOG_PRIMASK) | 
((p[16] - '0')  3);
 
 else if (l == 18 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9' 
  p[17] = '0'  p[17] = '9')
 priority = (priority  LOG_PRIMASK) | 
(((p[16] - '0')*10 + (p[17] - '0'))  3);
 
 else if (l = 19 
- hasprefix(p, SYSLOG_IDENTIFIER=)) {
+ startswith(p, SYSLOG_IDENTIFIER=)) {
 char *t;
 
 t = strndup(p + 18, l - 18);
@@ -179,7 +179,7 @@ void server_process_native_message(
 identifier = t;
 }
 } else if (l = 8 
-   hasprefix(p, MESSAGE=)) {
+   startswith(p, MESSAGE=)) {
 char *t;
 
 t = strndup(p + 8, l - 8);
@@ -189,7 +189,7 @@ void server_process_native_message(
 }
 } else if (l  strlen(OBJECT_PID=) 
l  strlen(OBJECT_PID=)  + 
DECIMAL_STR_MAX(pid_t) 
-   hasprefix(p, OBJECT_PID=) 
+   startswith(p, OBJECT_PID=) 
allow_object_pid(ucred)) {
 char buf[DECIMAL_STR_MAX(pid_t)];
 memcpy(buf, p + strlen(OBJECT_PID=), 
l - strlen(OBJECT_PID=));
diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c
index 750acfe..1411167 100644
--- a/src/libsystemd-bus/bus-match.c
+++ b/src/libsystemd-bus/bus-match.c
@@ -555,22 +555,22 @@ static int bus_match_find_leaf(
 enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t 
n) {
 assert(k);
 
-if (n == 4  hasprefix(k, type))
+if (n == 4  startswith(k, type))
 return BUS_MATCH_MESSAGE_TYPE;
-if (n == 6  hasprefix(k, sender))
+if (n == 6  startswith(k, sender))
 return BUS_MATCH_SENDER;
-if (n == 11  hasprefix(k, destination))
+if (n == 11  startswith(k, destination))
 return BUS_MATCH_DESTINATION;
-if (n == 9  hasprefix(k, interface))
+if (n == 

[systemd-devel] [PATCH v2] shared: rename hasprefix() to startswith(), which is functionally identical and removed

2013-07-12 Thread Shawn Landden
as most (if not all) of the prefix strings are static, these will get
forward constant propagation optimized into single memcmp() calls, which
should be much better than the non-SIMD hand-rolled version.
---
 TODO   |  2 --
 src/journal/journal-send.c |  2 +-
 src/journal/journald-native.c  | 12 ++--
 src/libsystemd-bus/bus-match.c | 26 +-
 src/shared/logs-show.c |  2 +-
 src/shared/macro.h |  2 +-
 src/shared/util.c  | 17 -
 src/shared/util.h  |  1 -
 8 files changed, 22 insertions(+), 42 deletions(-)

diff --git a/TODO b/TODO
index 5d4ba8f..ad600c2 100644
--- a/TODO
+++ b/TODO
@@ -57,8 +57,6 @@ Features:
 * Get rid of systemd-sysv:
   https://fedoraproject.org/wiki/User:Toshio/Systemd_Convert_draft
 
-* do we really need both hasprefix() and startswith()?
-
 * when a kernel driver logs in a tight loop we should ratelimit that too.
 
 * journald: when we drop syslog messages because the syslog socket is
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index fef66fc..d00e26f 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -245,7 +245,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int 
n) {
 
 have_syslog_identifier = have_syslog_identifier ||
 (c == (char *) iov[i].iov_base + 17 
- hasprefix(iov[i].iov_base, SYSLOG_IDENTIFIER));
+ startswith(iov[i].iov_base, SYSLOG_IDENTIFIER));
 
 nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
 if (nl) {
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 0f9af37..c50cf64 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -154,23 +154,23 @@ void server_process_native_message(
  * of this entry for the rate limiting
  * logic */
 if (l == 10 
-hasprefix(p, PRIORITY=) 
+startswith(p, PRIORITY=) 
 p[9] = '0'  p[9] = '9')
 priority = (priority  LOG_FACMASK) | 
(p[9] - '0');
 
 else if (l == 17 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9')
 priority = (priority  LOG_PRIMASK) | 
((p[16] - '0')  3);
 
 else if (l == 18 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9' 
  p[17] = '0'  p[17] = '9')
 priority = (priority  LOG_PRIMASK) | 
(((p[16] - '0')*10 + (p[17] - '0'))  3);
 
 else if (l = 19 
- hasprefix(p, SYSLOG_IDENTIFIER=)) {
+ startswith(p, SYSLOG_IDENTIFIER=)) {
 char *t;
 
 t = strndup(p + 18, l - 18);
@@ -179,7 +179,7 @@ void server_process_native_message(
 identifier = t;
 }
 } else if (l = 8 
-   hasprefix(p, MESSAGE=)) {
+   startswith(p, MESSAGE=)) {
 char *t;
 
 t = strndup(p + 8, l - 8);
@@ -189,7 +189,7 @@ void server_process_native_message(
 }
 } else if (l  strlen(OBJECT_PID=) 
l  strlen(OBJECT_PID=)  + 
DECIMAL_STR_MAX(pid_t) 
-   hasprefix(p, OBJECT_PID=) 
+   startswith(p, OBJECT_PID=) 
allow_object_pid(ucred)) {
 char buf[DECIMAL_STR_MAX(pid_t)];
 memcpy(buf, p + strlen(OBJECT_PID=), 
l - strlen(OBJECT_PID=));
diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c
index 750acfe..1411167 100644
--- a/src/libsystemd-bus/bus-match.c
+++ b/src/libsystemd-bus/bus-match.c
@@ -555,22 +555,22 @@ static int bus_match_find_leaf(
 enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t 
n) {
 assert(k);
 
-if (n == 4  

[systemd-devel] [PATCH] journalctl: have a useful --setup-keys error message when using non-persistant logging

2013-07-12 Thread Shawn Landden
Generating seed...

Generating key pair...
Generating sealing key...
Failed to open 
/var/log/journal/33f46101703a10c5fc6fa4f451840101/fss.tmp.k2wDDU: No such file 
or directory
---
 src/journal/journalctl.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 7baea23..458d80d 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -725,6 +725,23 @@ static int setup_keys(void) {
 char *p = NULL, *k = NULL;
 struct FSSHeader h;
 uint64_t n;
+stat st;
+
+r = stat(/var/log/journal, st);
+if (r  0) {
+if (errno == ENOENT || errno == ENOTDIR) {
+log_error(%s is not a directory, must be using 
persistant logging for FSS: %s, /var/log/journal, strerror(errno));
+return -errno;
+} else {
+log_error(stat(\%s\) failed: %m, 
/var/log/journal);
+return -errno;
+}
+}
+
+if (!S_ISDIR(st.st_mode)) {
+log_error(%s is not a directory, must be using persistant 
logging for FSS: %s, /var/log/journal, strerror(ENOTDIR));
+return -ENOTDIR;
+}
 
 r = sd_id128_get_machine(machine);
 if (r  0) {
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] journalctl: add --force option to recreate FSS

2013-07-14 Thread Shawn Landden
reuse -f?
---
 src/journal/journalctl.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 32665b7..5f44fce 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -79,6 +79,7 @@ static int arg_priorities = 0xFF;
 static const char *arg_verify_key = NULL;
 #ifdef HAVE_GCRYPT
 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
+static bool arg_force = false;
 #endif
 static usec_t arg_since, arg_until;
 static bool arg_since_set = false, arg_until_set = false;
@@ -149,6 +150,7 @@ static int help(void) {
 --update-catalogUpdate the message catalog database\n
 #ifdef HAVE_GCRYPT
 --setup-keysGenerate new FSS key pair\n
+--force Force overriding new FSS key pair 
with --setup-keys\n
 --verifyVerify journal file consistency\n
 #endif
, program_invocation_short_name);
@@ -179,6 +181,7 @@ static int parse_argv(int argc, char *argv[]) {
 ARG_LIST_CATALOG,
 ARG_DUMP_CATALOG,
 ARG_UPDATE_CATALOG,
+ARG_FORCE,
 };
 
 static const struct option options[] = {
@@ -187,6 +190,7 @@ static int parse_argv(int argc, char *argv[]) {
 { no-pager, no_argument,   NULL, ARG_NO_PAGER },
 { pager-end,no_argument,   NULL, 'e'  },
 { follow,   no_argument,   NULL, 'f'  },
+{ force,no_argument,   NULL, ARG_FORCE},
 { output,   required_argument, NULL, 'o'  },
 { all,  no_argument,   NULL, 'a'  },
 { full, no_argument,   NULL, 'l'  },
@@ -375,6 +379,10 @@ static int parse_argv(int argc, char *argv[]) {
 break;
 
 #ifdef HAVE_GCRYPT
+case ARG_FORCE:
+arg_force = true;
+break;
+
 case ARG_SETUP_KEYS:
 arg_action = ACTION_SETUP_KEYS;
 break;
@@ -397,6 +405,7 @@ static int parse_argv(int argc, char *argv[]) {
 case ARG_SETUP_KEYS:
 case ARG_VERIFY_KEY:
 case ARG_INTERVAL:
+case ARG_FORCE:
 log_error(Forward-secure sealing not available.);
 return -ENOTSUP;
 #endif
@@ -756,9 +765,18 @@ static int setup_keys(void) {
 return log_oom();
 
 if (access(p, F_OK) = 0) {
-log_error(Sealing key file %s exists already., p);
-r = -EEXIST;
-goto finish;
+if (arg_force) {
+r = unlink(p);
+if (r  0) {
+log_error(unlink(\%s\) failed: %m, p);
+r = -errno;
+goto finish;
+}
+} else {
+log_error(Sealing key file %s exists already. 
(--force to recreate), p);
+r = -EEXIST;
+goto finish;
+}
 }
 
 if (asprintf(k, /var/log/journal/ SD_ID128_FORMAT_STR 
/fss.tmp.XX,
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v4] journal: add logging of effective capabilities _CAP_EFFECTIVE

2013-07-15 Thread Shawn Landden
I think this is the most important of the capabilities bitmasks to log.
---
 TODO   |  2 --
 man/systemd.journal-fields.xml |  9 +
 src/journal/journald-server.c  |  7 +++
 src/shared/util.c  | 34 ++
 src/shared/util.h  |  1 +
 5 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/TODO b/TODO
index 5d4ba8f..0782038 100644
--- a/TODO
+++ b/TODO
@@ -208,8 +208,6 @@ Features:
 
 * teach ConditionKernelCommandLine= globs or regexes (in order to match 
foobar={no,0,off})
 
-* we should log capabilities too
-
 * 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
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index ed62edc..452406c 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -197,6 +197,15 @@
 /varlistentry
 
 varlistentry
+termvarname_CAP_EFFECTIVE=/varname/term
+listitem
+paraThe effective 
citerefentryrefentrytitlecapabilities/refentrytitlemanvolnum7/manvolnum/citerefentry
 of
+the process the journal entry
+originates from./para
+/listitem
+/varlistentry
+
+varlistentry
 termvarname_AUDIT_SESSION=/varname/term
 
termvarname_AUDIT_LOGINUID=/varname/term
 listitem
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 6beaa8a..332ba41 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -578,6 +578,13 @@ static void dispatch_message_real(
 IOVEC_SET_STRING(iovec[n++], x);
 }
 
+r = get_process_capeff(ucred-pid, t);
+if (r = 0) {
+x = strappenda(_CAP_EFFECTIVE=, t);
+free(t);
+IOVEC_SET_STRING(iovec[n++], x);
+}
+
 #ifdef HAVE_AUDIT
 r = audit_session_from_pid(ucred-pid, audit);
 if (r = 0) {
diff --git a/src/shared/util.c b/src/shared/util.c
index ceee6f2..7e9c8ea 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -726,6 +726,40 @@ int is_kernel_thread(pid_t pid) {
 return 0;
 }
 
+int get_process_capeff(pid_t pid, char **capeff) {
+const char *p;
+_cleanup_free_ char *status = NULL;
+char *t = NULL;
+int r;
+
+assert(capeff);
+assert(pid = 0);
+
+if (pid == 0)
+p = /proc/self/status;
+else
+p = procfs_file_alloca(pid, status);
+
+r = read_full_file(p, status, NULL);
+if (r  0)
+return r;
+
+t = strstr(status, \nCapEff:\t);
+if (!t)
+return -ENOENT;
+
+for (t += strlen(\nCapEff:\t); t[0] == '0'; t++)
+continue;
+
+if (t[0] == '\n')
+t--;
+
+*capeff = strndup(t, strchr(t, '\n') - t);
+if (!*capeff)
+return -ENOMEM;
+
+return 0;
+}
 
 int get_process_exe(pid_t pid, char **name) {
 const char *p;
diff --git a/src/shared/util.h b/src/shared/util.h
index ddb21b4..fac08ca 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -210,6 +210,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool 
comm_fallback, char *
 int get_process_exe(pid_t pid, char **name);
 int get_process_uid(pid_t pid, uid_t *uid);
 int get_process_gid(pid_t pid, gid_t *gid);
+int get_process_capeff(pid_t pid, char **capeff);
 
 char hexchar(int x) _const_;
 int unhexchar(char c) _const_;
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] configure: add -Wno-cast-align to CFLAGS

2013-07-15 Thread Shawn Landden
these warnings on !x86 arches for good code are annoying, and
there is no way to mark the offending code safe, so I guess we are
just going to have to deal with the resulting problems as we
come across them. Also, these warnings are present for armv6+armv7,
when they moreso effect armv5.
---
 configure.ac | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure.ac b/configure.ac
index afbe8e9..709262e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,6 +129,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
 -Wno-unused-parameter \
 -Wno-missing-field-initializers \
 -Wno-unused-result \
+-Wno-cast-align \
 -Werror=overflow \
 -ffast-math \
 -fno-common \
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] shared: fix build on !x86

2013-07-20 Thread Shawn Landden
---
 src/shared/virt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/shared/virt.c b/src/shared/virt.c
index 1abd686..4f8134a 100644
--- a/src/shared/virt.c
+++ b/src/shared/virt.c
@@ -29,6 +29,8 @@
 
 /* Returns a short identifier for the various VM implementations */
 int detect_vm(const char **id) {
+_cleanup_free_ char *cpuinfo_contents = NULL;
+int r;
 
 #if defined(__i386__) || defined(__x86_64__)
 
@@ -67,8 +69,6 @@ int detect_vm(const char **id) {
 const char *j, *k;
 bool hypervisor;
 _cleanup_free_ char *hvtype = NULL;
-_cleanup_free_ char *cpuinfo_contents = NULL;
-int r;
 
 /* Try high-level hypervisor sysfs file first:
  *
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] build: do not link everything with -lrt (and therefore -pthread)

2013-07-21 Thread Shawn Landden
---
 Makefile.am  | 1 +
 configure.ac | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 3ece887..f96866c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1832,6 +1832,7 @@ libsystemd_daemon_internal_la_SOURCES = \
$(libsystemd_daemon_la_SOURCES)
 
 libsystemd_daemon_la_CFLAGS = \
+   $(RT_LIBS) \
$(AM_CFLAGS) \
-fvisibility=hidden \
-DSD_EXPORT_SYMBOLS
diff --git a/configure.ac b/configure.ac
index a14b609..5735bd5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -194,7 +194,6 @@ AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test 
$have_python_devel = yes])
 
 # 
--
 
-AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not 
found])])
 AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader 
library not found])])
 
 save_LIBS=$LIBS
@@ -202,6 +201,9 @@ LIBS=
 AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library 
not found])])
 AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers 
not found])])
 CAP_LIBS=$LIBS
+AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not 
found])])
+RT_LIBS=$LIBS
+AC_SUBST(RT_LIBS)
 LIBS=$save_LIBS
 AC_SUBST(CAP_LIBS)
 
-- 
1.8.3.2

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] man: make reference to bind(2) explicit

2013-08-21 Thread Shawn Landden
---
 man/systemd.socket.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 852010b..1fc28c5 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -510,7 +510,7 @@
 varlistentry
 termvarnameReusePort=/varname/term
 listitemparaTakes a boolean
-value. If true, allows multiple bind()s
+value. If true, allows multiple 
citerefentryrefentrytitlebind/refentrytitlemanvolnum2/manvolnum/citerefentrys
 to this TCP or UDP port.  This
 controls the SO_REUSEPORT socket
 option.  See
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] remove hasprefix(), use startswith()

2013-08-21 Thread Shawn Landden
memcmp() could read from uninitilized memory if string is at the end
of a page boundry and shorter than prefix
---
 TODO   |  2 --
 src/journal/journal-send.c |  2 +-
 src/journal/journald-native.c  | 12 ++--
 src/libsystemd-bus/bus-match.c | 26 +-
 src/shared/logs-show.c |  2 +-
 src/shared/macro.h |  2 --
 6 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/TODO b/TODO
index 9bc14fd..3800ce4 100644
--- a/TODO
+++ b/TODO
@@ -96,8 +96,6 @@ Features:
 
 * systemctl list-unit-files should list generated files (and probably with a 
new state generated for them, or so)
 
-* do we really need both hasprefix() and startswith()?
-
 * journald: when we drop syslog messages because the syslog socket is
   full, make sure to write how many messages are lost as first thing
   to syslog when it works again.
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index fef66fc..d00e26f 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -245,7 +245,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int 
n) {
 
 have_syslog_identifier = have_syslog_identifier ||
 (c == (char *) iov[i].iov_base + 17 
- hasprefix(iov[i].iov_base, SYSLOG_IDENTIFIER));
+ startswith(iov[i].iov_base, SYSLOG_IDENTIFIER));
 
 nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
 if (nl) {
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 0f9af37..c50cf64 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -154,23 +154,23 @@ void server_process_native_message(
  * of this entry for the rate limiting
  * logic */
 if (l == 10 
-hasprefix(p, PRIORITY=) 
+startswith(p, PRIORITY=) 
 p[9] = '0'  p[9] = '9')
 priority = (priority  LOG_FACMASK) | 
(p[9] - '0');
 
 else if (l == 17 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9')
 priority = (priority  LOG_PRIMASK) | 
((p[16] - '0')  3);
 
 else if (l == 18 
- hasprefix(p, SYSLOG_FACILITY=) 
+ startswith(p, SYSLOG_FACILITY=) 
  p[16] = '0'  p[16] = '9' 
  p[17] = '0'  p[17] = '9')
 priority = (priority  LOG_PRIMASK) | 
(((p[16] - '0')*10 + (p[17] - '0'))  3);
 
 else if (l = 19 
- hasprefix(p, SYSLOG_IDENTIFIER=)) {
+ startswith(p, SYSLOG_IDENTIFIER=)) {
 char *t;
 
 t = strndup(p + 18, l - 18);
@@ -179,7 +179,7 @@ void server_process_native_message(
 identifier = t;
 }
 } else if (l = 8 
-   hasprefix(p, MESSAGE=)) {
+   startswith(p, MESSAGE=)) {
 char *t;
 
 t = strndup(p + 8, l - 8);
@@ -189,7 +189,7 @@ void server_process_native_message(
 }
 } else if (l  strlen(OBJECT_PID=) 
l  strlen(OBJECT_PID=)  + 
DECIMAL_STR_MAX(pid_t) 
-   hasprefix(p, OBJECT_PID=) 
+   startswith(p, OBJECT_PID=) 
allow_object_pid(ucred)) {
 char buf[DECIMAL_STR_MAX(pid_t)];
 memcpy(buf, p + strlen(OBJECT_PID=), 
l - strlen(OBJECT_PID=));
diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c
index 750acfe..1411167 100644
--- a/src/libsystemd-bus/bus-match.c
+++ b/src/libsystemd-bus/bus-match.c
@@ -555,22 +555,22 @@ static int bus_match_find_leaf(
 enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t 
n) {
 assert(k);
 
-if (n == 4  hasprefix(k, type))
+if (n == 4  startswith(k, type))
 return BUS_MATCH_MESSAGE_TYPE;
-if (n == 6  

[systemd-devel] [PATCH] udev: fix printf(3) type specifier

2013-08-22 Thread Shawn Landden
From: Shawn Landden shawnland...@gmail.com

src/udev/udev-rules.c: In function 'add_rule':
src/udev/udev-rules.c:1078:33: warning: format '%lu' expects argument of type 
'long unsigned int', but argument 8 has type 'int' [-Wformat=]
 log_error(invalid key/value pair in file %s 
on line %u,
 ^
---
 src/udev/udev-rules.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 1634812..f14158b 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1076,7 +1076,7 @@ static int add_rule(struct udev_rules *rules, char *line,
 
 tmp = cescape(buf);
 log_error(invalid key/value pair in file %s 
on line %u,
-  starting at character %lu ('%s')\n,
+  starting at character %tu ('%s')\n,
   filename, lineno, linepos - line + 
1, tmp);
 if (linepos[1] == '#')
 log_info(hint: comments can only 
start at beginning of line);
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] util, utf8: recognize wide characters in wellipsize_mem()

2013-08-28 Thread Shawn Landden
---
 src/shared/utf8.c | 64 +++
 src/shared/utf8.h |  4 +++-
 src/shared/util.c | 19 ++---
 src/shared/util.h |  1 +
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/src/shared/utf8.c b/src/shared/utf8.c
index 8a37c3a..607f0c1 100644
--- a/src/shared/utf8.c
+++ b/src/shared/utf8.c
@@ -372,4 +372,68 @@ utf8_get_char (const char *p)
   UTF8_GET (result, p, i, mask, len);
 
   return result;
+}
+
+struct Interval
+{
+  unichar start, end;
+};
+
+static int
+interval_compare (const void *key, const void *elt)
+{
+  unichar c = (unichar) (long) (key);
+  struct Interval *interval = (struct Interval *)elt;
+
+  if (c  interval-start)
+return -1;
+  if (c  interval-end)
+return +1;
+
+  return 0;
+}
+
+/*
+ * NOTE:
+ *
+ * The tables for g_unichar_iswide() and g_unichar_iswide_cjk() are
+ * generated from the Unicode Character Database's file
+ * extracted/DerivedEastAsianWidth.txt using the gen-iswide-table.py
+ * in this way:
+ *
+ *   ./gen-iswide-table.py  path/to/ucd/extracted/DerivedEastAsianWidth.txt | 
fmt
+ *
+ * Last update for Unicode 6.0.
+ */
+
+/**
+ * g_unichar_iswide:
+ * @c: a Unicode character
+ *
+ * Determines if a character is typically rendered in a double-width
+ * cell.
+ *
+ * Return value: %TRUE if the character is wide
+ **/
+bool
+unichar_iswide (unichar c)
+{
+  /* See NOTE earlier for how to update this table. */
+  static const struct Interval wide[] = {
+{0x1100, 0x115F}, {0x2329, 0x232A}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3},
+{0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, {0x3000, 0x303E}, {0x3041, 0x3096},
+{0x3099, 0x30FF}, {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
+{0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x32FE},
+{0x3300, 0x4DBF}, {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6},
+{0x1B000, 0x1B001}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23A}, {0x1F240,
+0x1F248}, {0x1F250, 0x1F251}, {0x2, 0x2FFFD}, {0x3, 0x3FFFD}
+  };
+
+  if (bsearch ((long)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof 
wide[0],
+  interval_compare))
+return true;
+
+  return false;
 }
\ No newline at end of file
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
index 020bc27..f1be180 100644
--- a/src/shared/utf8.h
+++ b/src/shared/utf8.h
@@ -131,4 +131,6 @@ static const char utf8_skip_data[256] = {
  * Before using this macro, use g_utf8_validate() to validate strings
  * that may contain invalid UTF-8.
  */
-#define utf8_next_char(p) (char *)((p) + utf8_skip_data[*(const char *)(p)])
\ No newline at end of file
+#define utf8_next_char(p) (char *)((p) + utf8_skip_data[*(const char *)(p)])
+
+bool unichar_iswide (unichar c);
\ No newline at end of file
diff --git a/src/shared/util.c b/src/shared/util.c
index 58a1787..1c73b3e 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3357,22 +3357,35 @@ char *wellipsize_mem(const char *s, size_t old_length, 
size_t new_length, unsign
 if (x  new_length - 3)
 x = new_length - 3;
 
-for (i = (char *)s;k  x;i = utf8_next_char(i))
+for (i = (char *)s;k  x;i = utf8_next_char(i)) {
+c = utf8_get_char(i);
 k++;
+if (unichar_iswide(c))
+k++;
+}
+
+if (k  x) /* last character was wide and went over quota */
+x++;
 
 j = i - s;
 memcpy(e, s, j);
-e[j] = '.';   /* TODO: use … tri-dot? */
-e[j+1] = '.'; /* 0xe2 0x80 0xa6 */
+e[j]   = '.'; /* TODO: use … tri-dot? */
+e[j+1] = '.'; /* 0xE2 0x80 0xA6 */
 e[j+2] = '.';
 
 k = 0;
 for (i = (char *)s + old_length;
  k  new_length - x - 3;) {
 i = utf8_prev_char(i);
+c = utf8_get_char(i);
 k++;
+if (unichar_iswide(c))
+k++;
 }
 
+if (k  new_length - x - 3) /* last (reverse) character was wide and 
went over quota */
+i = utf8_next_char(i);
+
 strcpy(e + j + 3, i);
 
 return e;
diff --git a/src/shared/util.h b/src/shared/util.h
index 9b17db9..97d8697 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -405,6 +405,7 @@ int running_in_chroot(void);
 char *ellipsize(const char *s, size_t length, unsigned percent);
 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, 
unsigned percent);
 char *wellipsize(const char *s, size_t length, unsigned percent);
+/* bytes  columns */
 char *wellipsize_mem(const char *s, size_t old_length, size_t new_length, 
unsigned percent);
 
 int touch(const char *path);
-- 
1.8.4.rc3

___
systemd-devel 

[systemd-devel] [PATCH 2/3] util, utf8: new wellipsize and wellipsize_mem that take into account multi-byte characters

2013-09-11 Thread Shawn Landden
This version counts all multibyte characters as 1 width, not taking into
account double width cjk characters and zerowidth characters
---
 src/shared/util.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/shared/util.c b/src/shared/util.c
index b791433..c6375e5 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3310,14 +3310,14 @@ char *ascii_ellipsize_mem(const char *s, size_t 
old_length, size_t new_length, u
 continue;
 
 memcpy(r, s, x);
-r[x] = '.';
-r[x+1] = '.';
-r[x+2] = '.';
+r[x] = 0xe2;
+r[x+1] = 0x80;
+r[x+2] = 0xa6;
 
 for (j=(x+3);(unsigned char)s[j]  0x80;j++)
 continue;
 
-memcpy(r + x + 3,
+memcpy(r + x + 1,
s + old_length - (new_length - j),
new_length - j);
 
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] util, utf8: recognize wide characters in wellipsize_mem()

2013-09-11 Thread Shawn Landden
 Original Message 
 From: Zbigniew Jędrzejewski-Szmek 
 To: shawnland...@gmail.com
CC: systemd-devel@lists.freedesktop.org, Shawn Landden 
 Sent: Tue, Sep 10, 2013, 08:59
 Subject: Re: [systemd-devel] [PATCH] util, utf8: recognize wide characters in 
wellipsize_mem()
Hi Shawn,
thank you for attacking this, and sorry for the long delay in answering.
I think that the approach of copying working code from elsewhere for this
is right, but I think it should go into its own file, so that two coding
styles are not mixed.The functions come from the same original source however 
(same two files in glib) so I think they should go together, perhaps the older
take functions should be transfered back to their original style? 

Also, can those new functions replace normal ellipsize and ellipsize_mem,
so that we have support everywhere?renamed old to ascii_* 

e = new0(char, new_length*4  old_length ? new_length*4 : old_length);

→ we have a min macro

fixed 
There are some compilation warnings:

../src/shared/utf8.c: In function 'unichar_iswide':
../src/shared/utf8.c:435:9: warning: passing argument 1 of 'bsearch' makes 
pointer from integer without a cast [enabled by default]
interval_compare))
^
In file included from ../src/shared/utf8.c:51:0:
/usr/include/stdlib.h:754:14: note: expected 'const void *' but argument is of 
type 'long int'
extern void *bsearch (const void *__key, const void *__base,

fixed 
../src/shared/util.c: In function 'wellipsize_mem':
../src/shared/util.c:3353:9: warning: array subscript has type 'char' 
[-Wchar-subscripts]
for (i = (char *)s;k  x;i = utf8_next_char(i)) {
^
../src/shared/util.c:3380:17: warning: array subscript has type 'char' 
[-Wchar-subscripts]
i = utf8_next_char(i);
^not sure how to fix this,I am iterating over a pointer to char, but i am not 
evaluating it (it is a warning about signed vs unsigned char.) 

and valgrind finds some leaks:

% valgrind --leak-check=full build/.libs/test-wellipsize 
==19953== 
==19953== HEAP SUMMARY:
==19953== in use at exit: 1,379 bytes in 6 blocks
==19953==   total heap usage: 6 allocs, 0 frees, 1,379 bytes allocated
==19953== 
==19953== 81 bytes in 1 blocks are definitely lost in loss record 1 of 6
==19953==at 0x4A08121: calloc (in 
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19953==by 0x400F57: ellipsize_mem (util.c:3300)
==19953==by 0x401082: wellipsize_mem (util.c:3336)
==19953==by 0x40122A: wellipsize (util.c:3388)
==19953==by 0x400CFF: test_one (test-wellipsize.c:28)
==19953==by 0x400D4C: main (test-wellipsize.c:37)
...

I think it was just my lazy test, which I fixed, but I am on ARM, so let me 
know if this persists on amd64
On Wed, Aug 28, 2013 at 03:58:29PM -0700, Shawn wrote:
here is the test runner I am using, doesn't really make sense to add this
to the tree as it has to be visually inspected
I think it is still useful, since we don't have anything better for now. Anyway,
we have a bunch of tests which can only be run manually. Your test is certainly
good enough for valgrind testing and visual inspection, so it should go in.

ok 
Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/3] util: ellipsize_mem: do not print partial utf-8 characters

2013-09-11 Thread Shawn Landden
, unsigned percent);
+   /* bytes columns */
 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, 
unsigned percent);
 
 int touch(const char *path);
diff --git a/src/test/test-wellipsize.c b/src/test/test-wellipsize.c
new file mode 100644
index 000..f6db82c
--- /dev/null
+++ b/src/test/test-wellipsize.c
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see http://www.gnu.org/licenses/.
+***/
+
+#include stdio.h
+
+#include util.h
+#include utf8.h
+
+static void test_one(const char *p) {
+   _cleanup_free_ char *t = NULL;
+   t = ellipsize(p, 80, 70);
+   puts(t);
+}
+
+int main(int argc, char *argv[]) {
+
test_one(s??);
+
test_one(?);
+
test_one(??);
+
test_one(?);
+
test_one();
+
test_one(asdfnjaskdfnklasdgnjaskdghnkasdgfklasdfjkasdfjaksdfaskldfnaskldfnaskldfnaklsdfnaklsdfnklnaskjgdknl);
+
+return 0;
+}
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] util, utf8: make ellipsize and ellipsize_mem take into account multi-byte characters

2013-09-13 Thread Shawn Landden
rename old versions to ascii_*

Do not take into account zerowidth characters, but do consider double-wide 
characters.
Import needed utf8 helper code from glib.
---
 TODO  |   4 --
 src/shared/utf8.c | 120 ++
 src/shared/utf8.h | 100 +
 src/shared/util.c |  70 ++-
 src/shared/util.h |   3 ++
 5 files changed, 292 insertions(+), 5 deletions(-)

diff --git a/TODO b/TODO
index 08d4914..509b31f 100644
--- a/TODO
+++ b/TODO
@@ -19,10 +19,6 @@ Bugfixes:
 
 * properly handle .mount unit state tracking when two mount points are stacked 
one on top of another on the exact same mount point.
 
-* ellipsize_mem must take into account multi-byte unicode characters, and
-  - make the resulting line the requested number of *characters*, not *bytes*,
-  - avoid truncuating multi-byte sequences in the middle.
-
 * When we detect invalid UTF-8, we cant't use it in an error message:
   log...(Path is not UTF-8 clean, ignoring assignment: %s, rvalue);
 
diff --git a/src/shared/utf8.c b/src/shared/utf8.c
index 655cc77..a9308b5 100644
--- a/src/shared/utf8.c
+++ b/src/shared/utf8.c
@@ -22,6 +22,11 @@
 /* This file is based on the GLIB utf8 validation functions. The
  * original license text follows. */
 
+/* gunicode.h - Unicode manipulation functions
+ *
+ *  Copyright (C) 1999, 2000 Tom Tromey
+ *  Copyright 2000, 2005 Red Hat, Inc.
+ */
 /* gutf8.c - Operations on UTF-8 strings.
  *
  * Copyright (C) 1999 Tom Tromey
@@ -317,3 +322,118 @@ char *utf16_to_utf8(const void *s, size_t length) {
 
 return r;
 }
+
+/**
+ * g_utf8_prev_char:
+ * @p: a pointer to a position within a UTF-8 encoded string
+ *
+ * Finds the previous UTF-8 character in the string before @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte. If @p might be the first
+ * character of the string, you must use g_utf8_find_prev_char() instead.
+ *
+ * Return value: a pointer to the found character.
+ **/
+char *
+utf8_prev_char (const char *p)
+{
+  while (1)
+{
+  p--;
+  if ((*p  0xc0) != 0x80)
+   return (char *)p;
+}
+}
+
+/**
+ * g_utf8_get_char:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ *
+ * Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * If @p does not point to a valid UTF-8 encoded character, results are
+ * undefined. If you are not sure that the bytes are complete
+ * valid Unicode characters, you should use g_utf8_get_char_validated()
+ * instead.
+ *
+ * Return value: the resulting character
+ **/
+unichar
+utf8_get_char (const char *p)
+{
+  int i, mask = 0, len;
+  unichar result;
+  unsigned char c = (unsigned char) *p;
+
+  UTF8_COMPUTE (c, mask, len);
+  if (len == -1)
+return (unichar)-1;
+  UTF8_GET (result, p, i, mask, len);
+
+  return result;
+}
+
+struct Interval
+{
+  unichar start, end;
+};
+
+static int
+interval_compare (const void *key, const void *elt)
+{
+  unichar c = (unichar) (long) (key);
+  struct Interval *interval = (struct Interval *)elt;
+
+  if (c  interval-start)
+return -1;
+  if (c  interval-end)
+return +1;
+
+  return 0;
+}
+
+/*
+ * NOTE:
+ *
+ * The tables for g_unichar_iswide() and g_unichar_iswide_cjk() are
+ * generated from the Unicode Character Database's file
+ * extracted/DerivedEastAsianWidth.txt using the gen-iswide-table.py
+ * in this way:
+ *
+ *   ./gen-iswide-table.py  path/to/ucd/extracted/DerivedEastAsianWidth.txt | 
fmt
+ *
+ * Last update for Unicode 6.0.
+ */
+
+/**
+ * g_unichar_iswide:
+ * @c: a Unicode character
+ *
+ * Determines if a character is typically rendered in a double-width
+ * cell.
+ *
+ * Return value: %TRUE if the character is wide
+ **/
+bool
+unichar_iswide (unichar c)
+{
+  /* See NOTE earlier for how to update this table. */
+  static const struct Interval wide[] = {
+{0x1100, 0x115F}, {0x2329, 0x232A}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3},
+{0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, {0x3000, 0x303E}, {0x3041, 0x3096},
+{0x3099, 0x30FF}, {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
+{0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x32FE},
+{0x3300, 0x4DBF}, {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6},
+{0x1B000, 0x1B001}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23A}, {0x1F240,
+0x1F248}, {0x1F250, 0x1F251}, {0x2, 0x2FFFD}, {0x3, 0x3FFFD}
+  };
+
+  if (bsearch ((long *)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof 
wide[0],
+  interval_compare))
+return true;
+
+  return false;
+}
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
index f805ea6..f1be180 100644
--- a/src/shared/utf8.h
+++ 

[systemd-devel] [PATCH 2/2] test: test for new ellipsize_mem (requires user)

2013-09-13 Thread Shawn Landden
---
 Makefile.am   |  7 +++
 src/test/test-ellipsize.c | 42 ++
 2 files changed, 49 insertions(+)
 create mode 100644 src/test/test-ellipsize.c

diff --git a/Makefile.am b/Makefile.am
index 7b7539a..0e4f58c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1125,6 +1125,7 @@ tests += \
test-unit-file \
test-util \
test-date \
+   test-ellipsize \
test-sleep \
test-replace-var \
test-sched-prio \
@@ -1303,6 +1304,12 @@ test_date_SOURCES = \
 test_date_LDADD = \
libsystemd-core.la
 
+test_ellipsize_SOURCES = \
+src/test/test-wellipsize.c
+
+test_ellipsize_LDADD = \
+libsystemd-core.la
+
 test_sleep_SOURCES = \
src/test/test-sleep.c
 
diff --git a/src/test/test-ellipsize.c b/src/test/test-ellipsize.c
new file mode 100644
index 000..f6db82c
--- /dev/null
+++ b/src/test/test-ellipsize.c
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see http://www.gnu.org/licenses/.
+***/
+
+#include stdio.h
+
+#include util.h
+#include utf8.h
+
+static void test_one(const char *p) {
+   _cleanup_free_ char *t = NULL;
+   t = ellipsize(p, 80, 70);
+   puts(t);
+}
+
+int main(int argc, char *argv[]) {
+
test_one(s??);
+
test_one(?);
+
test_one(??);
+
test_one(?);
+
test_one();
+
test_one(asdfnjaskdfnklasdgnjaskdghnkasdgfklasdfjkasdfjaksdfaskldfnaskldfnaskldfnaklsdfnaklsdfnklnaskjgdknl);
+
+return 0;
+}
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] util, utf8: make ellipsize and ellipsize_mem take into account multi-byte characters

2013-09-13 Thread Shawn Landden
rename old versions to ascii_*

Do not take into account zerowidth characters, but do consider double-wide 
characters.
Import needed utf8 helper code from glib.
---
 TODO  |   4 --
 src/shared/utf8.c | 120 ++
 src/shared/utf8.h | 100 +
 src/shared/util.c |  77 +--
 src/shared/util.h |   3 ++
 5 files changed, 296 insertions(+), 8 deletions(-)

diff --git a/TODO b/TODO
index 08d4914..509b31f 100644
--- a/TODO
+++ b/TODO
@@ -19,10 +19,6 @@ Bugfixes:
 
 * properly handle .mount unit state tracking when two mount points are stacked 
one on top of another on the exact same mount point.
 
-* ellipsize_mem must take into account multi-byte unicode characters, and
-  - make the resulting line the requested number of *characters*, not *bytes*,
-  - avoid truncuating multi-byte sequences in the middle.
-
 * When we detect invalid UTF-8, we cant't use it in an error message:
   log...(Path is not UTF-8 clean, ignoring assignment: %s, rvalue);
 
diff --git a/src/shared/utf8.c b/src/shared/utf8.c
index 655cc77..a9308b5 100644
--- a/src/shared/utf8.c
+++ b/src/shared/utf8.c
@@ -22,6 +22,11 @@
 /* This file is based on the GLIB utf8 validation functions. The
  * original license text follows. */
 
+/* gunicode.h - Unicode manipulation functions
+ *
+ *  Copyright (C) 1999, 2000 Tom Tromey
+ *  Copyright 2000, 2005 Red Hat, Inc.
+ */
 /* gutf8.c - Operations on UTF-8 strings.
  *
  * Copyright (C) 1999 Tom Tromey
@@ -317,3 +322,118 @@ char *utf16_to_utf8(const void *s, size_t length) {
 
 return r;
 }
+
+/**
+ * g_utf8_prev_char:
+ * @p: a pointer to a position within a UTF-8 encoded string
+ *
+ * Finds the previous UTF-8 character in the string before @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte. If @p might be the first
+ * character of the string, you must use g_utf8_find_prev_char() instead.
+ *
+ * Return value: a pointer to the found character.
+ **/
+char *
+utf8_prev_char (const char *p)
+{
+  while (1)
+{
+  p--;
+  if ((*p  0xc0) != 0x80)
+   return (char *)p;
+}
+}
+
+/**
+ * g_utf8_get_char:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ *
+ * Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * If @p does not point to a valid UTF-8 encoded character, results are
+ * undefined. If you are not sure that the bytes are complete
+ * valid Unicode characters, you should use g_utf8_get_char_validated()
+ * instead.
+ *
+ * Return value: the resulting character
+ **/
+unichar
+utf8_get_char (const char *p)
+{
+  int i, mask = 0, len;
+  unichar result;
+  unsigned char c = (unsigned char) *p;
+
+  UTF8_COMPUTE (c, mask, len);
+  if (len == -1)
+return (unichar)-1;
+  UTF8_GET (result, p, i, mask, len);
+
+  return result;
+}
+
+struct Interval
+{
+  unichar start, end;
+};
+
+static int
+interval_compare (const void *key, const void *elt)
+{
+  unichar c = (unichar) (long) (key);
+  struct Interval *interval = (struct Interval *)elt;
+
+  if (c  interval-start)
+return -1;
+  if (c  interval-end)
+return +1;
+
+  return 0;
+}
+
+/*
+ * NOTE:
+ *
+ * The tables for g_unichar_iswide() and g_unichar_iswide_cjk() are
+ * generated from the Unicode Character Database's file
+ * extracted/DerivedEastAsianWidth.txt using the gen-iswide-table.py
+ * in this way:
+ *
+ *   ./gen-iswide-table.py  path/to/ucd/extracted/DerivedEastAsianWidth.txt | 
fmt
+ *
+ * Last update for Unicode 6.0.
+ */
+
+/**
+ * g_unichar_iswide:
+ * @c: a Unicode character
+ *
+ * Determines if a character is typically rendered in a double-width
+ * cell.
+ *
+ * Return value: %TRUE if the character is wide
+ **/
+bool
+unichar_iswide (unichar c)
+{
+  /* See NOTE earlier for how to update this table. */
+  static const struct Interval wide[] = {
+{0x1100, 0x115F}, {0x2329, 0x232A}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3},
+{0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, {0x3000, 0x303E}, {0x3041, 0x3096},
+{0x3099, 0x30FF}, {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
+{0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x32FE},
+{0x3300, 0x4DBF}, {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6},
+{0x1B000, 0x1B001}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23A}, {0x1F240,
+0x1F248}, {0x1F250, 0x1F251}, {0x2, 0x2FFFD}, {0x3, 0x3FFFD}
+  };
+
+  if (bsearch ((long *)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof 
wide[0],
+  interval_compare))
+return true;
+
+  return false;
+}
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
index f805ea6..f1be180 100644
--- a/src/shared/utf8.h
+++ 

[systemd-devel] [PATCH] util: preserve get_process_capeff behavior

2013-09-17 Thread Shawn Landden
69ab80881552d5f79ca95f6b3be48ad122ab1ec2 tried to unify
parsing of status files, but removed the logic of skipping
extra '0's when getting the effective capabilities. Restore
that logic.
---
 src/shared/util.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/shared/util.c b/src/shared/util.c
index bf31511..b68f15c 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -694,7 +694,8 @@ int is_kernel_thread(pid_t pid) {
 }
 
 int get_process_capeff(pid_t pid, char **capeff) {
-const char *p;
+const char *p, *t;
+int r;
 
 assert(capeff);
 assert(pid = 0);
@@ -704,7 +705,18 @@ int get_process_capeff(pid_t pid, char **capeff) {
 else
 p = procfs_file_alloca(pid, status);
 
-return get_status_field(p, \nCapEff:, capeff);
+r = get_status_field(p, \nCapEff:, capeff);
+
+for (t = *capeff; t[0] == '0'; t++)
+continue;
+
+if (t[0] == '\0')
+t--;
+
+if (t != *capeff)
+memmove(*capeff, t, strlen(t) + 1);
+
+return r;
 }
 
 int get_process_exe(pid_t pid, char **name) {
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] Actually fix capability logging when effective caps are 0

2013-09-18 Thread Shawn Landden
---
 src/shared/fileio.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 8aa4cdb..3a7f84e 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -677,13 +677,11 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
  * always maps to the same string, irrespective of the total
  * capability set size. For other numbers it shouldn't matter.
  */
-if (*t) {
-t += strspn(t, WHITESPACE 0);
-/* Back off one char if there's nothing but whitespace
-   and zeros */
-if (!*t)
-t --;
-}
+t += strspn(t, WHITESPACE 0);
+/* Back off to last '0' if there's nothing but whitespace
+   and zeros */
+if (*(t - 1) == '\n')
+t -= 2;
 
 len = strcspn(t, WHITESPACE);
 
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] Actually fix capability logging when effective caps are 0

2013-09-18 Thread Shawn Landden
---
 src/shared/fileio.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 8aa4cdb..3eaa911 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -673,17 +673,15 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
 
 t += strlen(pattern);
 /* Also skip zeros, because when this is used for capabilities,
- * we don't want the zeros. This way the same cabality set
+ * we don't want the zeros. This way the same cabability set
  * always maps to the same string, irrespective of the total
  * capability set size. For other numbers it shouldn't matter.
  */
-if (*t) {
-t += strspn(t, WHITESPACE 0);
-/* Back off one char if there's nothing but whitespace
-   and zeros */
-if (!*t)
-t --;
-}
+t += strspn(t, WHITESPACE 0);
+/* Back off to last '0' if there's nothing but whitespace
+   and zeros */
+if (*(t - 1) == '\n')
+t -= 2;
 
 len = strcspn(t, WHITESPACE);
 
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] Actually fix capability logging when effective caps are 0

2013-09-19 Thread Shawn Landden
---
 src/shared/fileio.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 01b803c..909a58f 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -662,6 +662,8 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
 
 assert(filename);
 assert(field);
+assert(pattern);
+assert(strlen(pattern) = 2);
 
 r = read_full_file(filename, status, NULL);
 if (r  0)
@@ -677,13 +679,11 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
  * always maps to the same string, irrespective of the total
  * capability set size. For other numbers it shouldn't matter.
  */
-if (*t) {
-t += strspn(t, WHITESPACE 0);
-/* Back off one char if there's nothing but whitespace
-   and zeros */
-if (!*t)
-t --;
-}
+t += strspn(t, WHITESPACE 0);
+/* Back off to last '0' if there's nothing but whitespace
+   and zeros */
+if (*(t - 1) == '\n')
+t -= 2;
 
 len = strcspn(t, WHITESPACE);
 
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] util, fileio: do not use get_status_field() for get_process_capeff()

2013-09-19 Thread Shawn Landden
Tt is in the logging hot path and has too many special needs, like
skipping extra '0's.
---
 src/shared/fileio.c | 16 +++-
 src/shared/util.c   | 24 +++-
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 01b803c..0df5d3f 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -662,6 +662,7 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
 
 assert(filename);
 assert(field);
+assert(pattern);
 
 r = read_full_file(filename, status, NULL);
 if (r  0)
@@ -672,20 +673,9 @@ int get_status_field(const char *filename, const char 
*pattern, char **field) {
 return -ENOENT;
 
 t += strlen(pattern);
-/* Also skip zeros, because when this is used for capabilities,
- * we don't want the zeros. This way the same capability set
- * always maps to the same string, irrespective of the total
- * capability set size. For other numbers it shouldn't matter.
- */
-if (*t) {
-t += strspn(t, WHITESPACE 0);
-/* Back off one char if there's nothing but whitespace
-   and zeros */
-if (!*t)
-t --;
-}
+t += strspn(t,  \t);
 
-len = strcspn(t, WHITESPACE);
+len = strcspn(t,  \n);
 
 *field = strndup(t, len);
 if (!*field)
diff --git a/src/shared/util.c b/src/shared/util.c
index bf31511..a81541e 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -695,6 +695,10 @@ int is_kernel_thread(pid_t pid) {
 
 int get_process_capeff(pid_t pid, char **capeff) {
 const char *p;
+_cleanup_free_ char *status = NULL;
+char *t = NULL;
+int r;
+
 
 assert(capeff);
 assert(pid = 0);
@@ -704,7 +708,25 @@ int get_process_capeff(pid_t pid, char **capeff) {
 else
 p = procfs_file_alloca(pid, status);
 
-return get_status_field(p, \nCapEff:, capeff);
+r = read_full_file(p, status, NULL);
+if (r  0)
+return r;
+
+t = strstr(status, \nCapEff:\t);
+if (!t)
+return -ENOENT;
+
+for (t += strlen(\nCapEff:\t); t[0] == '0'; t++)
+continue;
+
+if (t[0] == '\n')
+t--;
+
+*capeff = strndup(t, (char *)rawmemchr(t, '\n') - t);
+if (!*capeff)
+return -ENOMEM;
+
+return 0;
 }
 
 int get_process_exe(pid_t pid, char **name) {
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] util, fileio: do not use get_status_field() for get_process_capeff()

2013-09-19 Thread Shawn Landden
On Thu, Sep 19, 2013 at 11:58 AM, David Strauss 
da...@davidstrauss.net wrote:

Does this supersede your earlier patch for get_status_field()?

Yes. I tried to optimize the previous patch, and realized it is not 
really possible without splitting back out the capeff handling, which 
is the one where performance matters, because it gets called every time 
we log a message.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] util, utf8: make ellipsize and ellipsize_mem take into account multi-byte characters

2013-09-20 Thread Shawn Landden
rename old versions to ascii_*

Do not take into account zerowidth characters, but do consider double-wide 
characters.
Import needed utf8 helper code from glib.

v3: rebase ontop of utf8 restructuring work
---
 TODO  |   4 --
 src/shared/utf8.c | 120 ++
 src/shared/utf8.h | 100 +
 src/shared/util.c |  70 ++-
 src/shared/util.h |   3 ++
 5 files changed, 292 insertions(+), 5 deletions(-)

diff --git a/TODO b/TODO
index 01bc993..c54e986 100644
--- a/TODO
+++ b/TODO
@@ -19,10 +19,6 @@ Bugfixes:
 
 * properly handle .mount unit state tracking when two mount points are stacked 
one on top of another on the exact same mount point.
 
-* ellipsize_mem must take into account multi-byte unicode characters, and
-  - make the resulting line the requested number of *characters*, not *bytes*,
-  - avoid truncuating multi-byte sequences in the middle.
-
 * When we detect invalid UTF-8, we cant't use it in an error message:
   log...(Path is not UTF-8 clean, ignoring assignment: %s, rvalue);
 
diff --git a/src/shared/utf8.c b/src/shared/utf8.c
index c3d97cc..2b07265 100644
--- a/src/shared/utf8.c
+++ b/src/shared/utf8.c
@@ -22,6 +22,11 @@
 /* This file is based on the GLIB utf8 validation functions. The
  * original license text follows. */
 
+/* gunicode.h - Unicode manipulation functions
+ *
+ *  Copyright (C) 1999, 2000 Tom Tromey
+ *  Copyright 2000, 2005 Red Hat, Inc.
+ */
 /* gutf8.c - Operations on UTF-8 strings.
  *
  * Copyright (C) 1999 Tom Tromey
@@ -285,3 +290,118 @@ int utf8_encoded_valid_unichar(const char *str) {
 
 return len;
 }
+
+/**
+ * g_utf8_prev_char:
+ * @p: a pointer to a position within a UTF-8 encoded string
+ *
+ * Finds the previous UTF-8 character in the string before @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte. If @p might be the first
+ * character of the string, you must use g_utf8_find_prev_char() instead.
+ *
+ * Return value: a pointer to the found character.
+ **/
+char *
+utf8_prev_char (const char *p)
+{
+  while (1)
+{
+  p--;
+  if ((*p  0xc0) != 0x80)
+return (char *)p;
+}
+}
+
+/**
+ * g_utf8_get_char:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ *
+ * Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * If @p does not point to a valid UTF-8 encoded character, results are
+ * undefined. If you are not sure that the bytes are complete
+ * valid Unicode characters, you should use g_utf8_get_char_validated()
+ * instead.
+ *
+ * Return value: the resulting character
+ **/
+unichar
+utf8_get_char (const char *p)
+{
+  int i, mask = 0, len;
+  unichar result;
+  unsigned char c = (unsigned char) *p;
+
+  UTF8_COMPUTE (c, mask, len);
+  if (len == -1)
+return (unichar)-1;
+  UTF8_GET (result, p, i, mask, len);
+
+  return result;
+}
+
+struct Interval
+{
+  unichar start, end;
+};
+
+static int
+interval_compare (const void *key, const void *elt)
+{
+  unichar c = (unichar) (long) (key);
+  struct Interval *interval = (struct Interval *)elt;
+
+  if (c  interval-start)
+return -1;
+  if (c  interval-end)
+return +1;
+
+  return 0;
+}
+
+/*
+ * NOTE:
+ *
+ * The tables for g_unichar_iswide() and g_unichar_iswide_cjk() are
+ * generated from the Unicode Character Database's file
+ * extracted/DerivedEastAsianWidth.txt using the gen-iswide-table.py
+ * in this way:
+ *
+ *   ./gen-iswide-table.py  path/to/ucd/extracted/DerivedEastAsianWidth.txt | 
fmt
+ *
+ * Last update for Unicode 6.0.
+ */
+
+/**
+ * g_unichar_iswide:
+ * @c: a Unicode character
+ *
+ * Determines if a character is typically rendered in a double-width
+ * cell.
+ *
+ * Return value: %TRUE if the character is wide
+ **/
+bool
+unichar_iswide (unichar c)
+{
+  /* See NOTE earlier for how to update this table. */
+  static const struct Interval wide[] = {
+{0x1100, 0x115F}, {0x2329, 0x232A}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3},
+{0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, {0x3000, 0x303E}, {0x3041, 0x3096},
+{0x3099, 0x30FF}, {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
+{0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x32FE},
+{0x3300, 0x4DBF}, {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6},
+{0x1B000, 0x1B001}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23A}, {0x1F240,
+0x1F248}, {0x1F250, 0x1F251}, {0x2, 0x2FFFD}, {0x3, 0x3FFFD}
+  };
+
+  if (bsearch ((long *)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof 
wide[0],
+   interval_compare))
+return true;
+
+  return false;
+}
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
index 

[systemd-devel] [PATCH 2/2] test: test for ellipsize (manual)

2013-09-20 Thread Shawn Landden
---
 Makefile.am   |  7 +++
 src/test/test-ellipsize.c | 42 ++
 2 files changed, 49 insertions(+)
 create mode 100644 src/test/test-ellipsize.c

diff --git a/Makefile.am b/Makefile.am
index 89a5c86..802f6eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1114,6 +1114,7 @@ manual_tests += \
test-cgroup \
test-install \
test-watchdog \
+   test-ellipsize \
test-log
 
 tests += \
@@ -1319,6 +1320,12 @@ test_log_SOURCES = \
 test_log_LDADD = \
libsystemd-core.la
 
+test_ellipsize_SOURCES = \
+   src/test/test-ellipsize.c
+
+test_ellipsize_LDADD = \
+   libsystemd-core.la
+
 test_date_SOURCES = \
src/test/test-date.c
 
diff --git a/src/test/test-ellipsize.c b/src/test/test-ellipsize.c
new file mode 100644
index 000..fab5e4b
--- /dev/null
+++ b/src/test/test-ellipsize.c
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see http://www.gnu.org/licenses/.
+***/
+
+#include stdio.h
+
+#include util.h
+#include utf8.h
+
+static void test_one(const char *p) {
+_cleanup_free_ char *t = NULL;
+t = ellipsize(p, 80, 70);
+puts(t);
+}
+
+int main(int argc, char *argv[]) {
+
test_one(??);
+
test_one(-?);
+
test_one(-??);
+test_one(s??st??md s??st??md s??st??md s??st??md s??st??md s??st??md 
s??st??md s??st??md s??st??md s??st??md s??st??md s??st??md s??st??md);
+
test_one();
+test_one(Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad 
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit 
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat 
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.);
+
+return 0;
+}
-- 
1.8.4.rc3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] util: preserve get_process_capeff behavior

2013-09-21 Thread Shawn Landden
On Thu, Sep 19, 2013 at 2:40 PM, Zbigniew Jędrzejewski-Szmek 
zbys...@in.waw.pl wrote:

 On Thu, Sep 19, 2013 at 10:28:40AM -0700, Shawn Landden wrote:
  We can't optimize the strcspn(t, WHITESPACE); to a strchr(t, '\n') - t;
  because of the  kB that meminfo and a few other places have, that we
 want
  to drop.
 
  get_status_field() has to be run every time we log a message, and I am
  starting to not like this function at all. I think we should go back to
  having it hand-rolled in get_process_capeff(), at least for that one in
 the
  hot-path.
 Hi Shawn,

 I think there's value in having one function to parse /proc/self/status.
 I pushed some tests and a simple fix to avoid backtracking.

It wasn't backtracking more than it has already gone forward. I even had an
assert for this, anyways, the current version is correct.

 Anyway, this
 parsing might be going away, once we start using the equivalent of
 SCM_CREDENTIALS
 for capabilities,

That requires a kernel patch, meanwhile we will have compatibility code for
old kernels...I think my optimized version still makes sense, although
something like SCM_CREDIENTIALS would certainly be more optimized.

 so I don't think it makes sense to optimize it at this point.

 Zbyszek




-- 

---
Shawn Landden
+1 360 389 3001 (SMS preferred)
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [ANNOUNCE] systemd 208

2013-10-03 Thread Shawn Landden
 Ott, Tom Gundersen, Zbigniew Jędrzejewski-Szmek

 -- Berlin, 2013-10-02

 Lennart

 --
 Lennart Poettering - Red Hat, Inc.
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel




-- 

---
Shawn Landden
+1 360 389 3001 (SMS preferred)
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


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

2013-11-14 Thread Shawn Landden
---
 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 | 63 +++
 src/core/socket.h |  2 ++
 7 files changed, 82 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,
+bool set_notify_socket,
+bool 

[systemd-devel] [PATCH 2/3] core/socket: fix SO_REUSEPORT

2013-11-14 Thread Shawn Landden
---
 src/core/load-fragment-gperf.gperf.m4 | 1 +
 src/core/socket.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index e3025d2..b64fdc9 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -210,6 +210,7 @@ Socket.Broadcast,config_parse_bool, 
 0,
 Socket.PassCredentials,  config_parse_bool,  0,
 offsetof(Socket, pass_cred)
 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.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/socket.c b/src/core/socket.c
index f505e4f..751f20b 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -771,7 +771,7 @@ static void socket_apply_socket_options(Socket *s, int fd) {
 
 if (s-reuseport) {
 int b = s-reuseport;
-if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, b, sizeof(b)))
+if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, b, sizeof(b))  
0)
 log_warning_unit(UNIT(s)-id, SO_REUSEPORT failed: 
%m);
 }
 
-- 
1.8.4.3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[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,
+  

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

2013-11-14 Thread Shawn Landden
v3 make each worker its own service
---
 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 | 124 --
 src/core/socket.h |   4 ++
 8 files changed, 96 insertions(+), 55 deletions(-)

diff --git a/TODO b/TODO
index 57e1122..733e528 100644
--- a/TODO
+++ b/TODO
@@ -82,7 +82,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
 
@@ -261,7 +261,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, mq_msgsize)
 Socket.Service,  config_parse_socket_service,  

[systemd-devel] [PATCH 2/2] core: lazy distribute for Distribute pools

2013-11-14 Thread Shawn Landden
---
 man/systemd.socket.xml| 9 +
 src/core/dbus-socket.c| 2 ++
 src/core/load-fragment-gperf.gperf.m4 | 1 +
 src/core/socket.c | 7 ++-
 src/core/socket.h | 1 +
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 92a9275..327c098 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -528,6 +528,15 @@
 /varlistentry
 
 varlistentry
+termvarnameLazyDistribute=/varname/term
+listitemparaTakes an boolean
+value. If true, Distribute=n workers will not 
be spawned
+simultameously, but one at a time while 
connections come it
+until n are running. Because of the nature of 
SO_REUSEPORT workers are
+spawned at an exponentially decreasing rate to 
the number of incoming connections./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 4644007..4e2a31d 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -69,6 +69,7 @@
   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=\LazyDistribute\ type=\b\ 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 \
@@ -198,6 +199,7 @@ static const BusProperty bus_socket_properties[] = {
 { 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)   },
+{ LazyDistribute, bus_property_append_bool,  b, 
offsetof(Socket, lazy_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 4058a1f..a023b0e 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -212,6 +212,7 @@ Socket.PassSecurity, config_parse_bool, 
 0,
 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.LazyDistribute,   config_parse_bool,  0,
 offsetof(Socket, lazy_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/socket.c b/src/core/socket.c
index 10a0d95..c968902 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -514,6 +514,11 @@ static void socket_dump(Unit *u, FILE *f, const char 
*prefix) {
 %sDistribute: %d\n,
  prefix, s-distribute);
 
+if (s-lazy_distribute)
+fprintf(f,
+%sLazyDistribute: %s\n,
+ prefix, yes_no(s-lazy_distribute));
+
 if (s-smack)
 fprintf(f,
 %sSmackLabel: %s\n,
@@ -1554,7 +1559,7 @@ static void socket_enter_running(Socket *s, int cfd) {
 
 socket_enter_listening(s);
 }
-} while(s-distribute  s-n_connections);
+} while(s-distribute  s-n_connections  
!(s-lazy_distribute));
 
 /* Notify clients about changed counters */
  

[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 1/4] core/socket: use _cleanup_free_

2013-11-16 Thread Shawn Landden
---
 src/core/socket.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/core/socket.c b/src/core/socket.c
index 03b8f92..f505e4f 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1475,7 +1475,7 @@ static void socket_enter_running(Socket *s, int cfd) {
 
 socket_set_state(s, SOCKET_RUNNING);
 } else {
-char *prefix, *instance = NULL, *name;
+_cleanup_free_ char *prefix = NULL, *instance = NULL, *name = 
NULL;
 Service *service;
 
 if (s-n_connections = s-max_connections) {
@@ -1503,14 +1503,11 @@ static void socket_enter_running(Socket *s, int cfd) {
 
 prefix = unit_name_to_prefix(UNIT(s)-id);
 if (!prefix) {
-free(instance);
 r = -ENOMEM;
 goto fail;
 }
 
 name = unit_name_build(prefix, instance, .service);
-free(prefix);
-free(instance);
 
 if (!name) {
 r = -ENOMEM;
@@ -1518,10 +1515,8 @@ static void socket_enter_running(Socket *s, int cfd) {
 }
 
 r = unit_add_name(UNIT_DEREF(s-service), name);
-if (r  0) {
-free(name);
+if (r  0)
 goto fail;
-}
 
 service = SERVICE(UNIT_DEREF(s-service));
 unit_ref_unset(s-service);
@@ -1530,7 +1525,6 @@ static void socket_enter_running(Socket *s, int cfd) {
 UNIT(service)-no_gc = false;
 
 unit_choose_id(UNIT(service), name);
-free(name);
 
 r = service_set_socket_fd(service, cfd, s);
 if (r  0)
-- 
1.8.4.3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


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

2013-11-16 Thread Shawn Landden
v3: make each worker its own service
v4: be less intrusive
v5: misc fixups
---
 TODO  |   3 -
 man/systemd.socket.xml|  11 
 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 | 119 +++---
 src/core/socket.h |   4 ++
 8 files changed, 89 insertions(+), 59 deletions(-)

diff --git a/TODO b/TODO
index efc7e2a..6067efb 100644
--- a/TODO
+++ b/TODO
@@ -80,8 +80,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()
@@ -259,7 +257,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..4a2189b 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -519,6 +519,17 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+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,   

[systemd-devel] [PATCH 4/4] core: lazy distribute for Distribute pools

2013-11-16 Thread Shawn Landden
---
 man/systemd.socket.xml| 9 +
 src/core/dbus-socket.c| 2 ++
 src/core/load-fragment-gperf.gperf.m4 | 1 +
 src/core/socket.c | 7 ++-
 src/core/socket.h | 1 +
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 4a2189b..fd6ec69 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -530,6 +530,15 @@
 /varlistentry
 
 varlistentry
+termvarnameLazyDistribute=/varname/term
+listitemparaTakes an boolean
+value. If true, Distribute=n workers will not 
be spawned
+simultameously, but one at a time while 
connections come it
+until n are running. Because of the nature of 
SO_REUSEPORT workers are
+spawned at an exponentially decreasing rate to 
the number of incoming connections./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 4644007..4e2a31d 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -69,6 +69,7 @@
   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=\LazyDistribute\ type=\b\ 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 \
@@ -198,6 +199,7 @@ static const BusProperty bus_socket_properties[] = {
 { 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)   },
+{ LazyDistribute, bus_property_append_bool,  b, 
offsetof(Socket, lazy_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 4058a1f..a023b0e 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -212,6 +212,7 @@ Socket.PassSecurity, config_parse_bool, 
 0,
 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.LazyDistribute,   config_parse_bool,  0,
 offsetof(Socket, lazy_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/socket.c b/src/core/socket.c
index 4d4627a..a85ae88 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -514,6 +514,11 @@ static void socket_dump(Unit *u, FILE *f, const char 
*prefix) {
 %sDistribute: %d\n,
  prefix, s-distribute);
 
+if (s-lazy_distribute)
+fprintf(f,
+%sLazyDistribute: %s\n,
+ prefix, yes_no(s-lazy_distribute));
+
 if (s-smack)
 fprintf(f,
 %sSmackLabel: %s\n,
@@ -1545,7 +1550,7 @@ static void socket_enter_running(Socket *s, int cfd) {
 
 if (s-n_connections  s-distribute)
 socket_enter_listening(s);
-} while (s-n_connections  s-distribute);
+} while (s-n_connections  s-distribute  
!(s-lazy_distribute));
 
 /* Notify 

[systemd-devel] [PATCH 2/4] core/socket: fix SO_REUSEPORT

2013-11-16 Thread Shawn Landden
---
 src/core/load-fragment-gperf.gperf.m4 | 1 +
 src/core/socket.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index e3025d2..b64fdc9 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -210,6 +210,7 @@ Socket.Broadcast,config_parse_bool, 
 0,
 Socket.PassCredentials,  config_parse_bool,  0,
 offsetof(Socket, pass_cred)
 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.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/socket.c b/src/core/socket.c
index f505e4f..751f20b 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -771,7 +771,7 @@ static void socket_apply_socket_options(Socket *s, int fd) {
 
 if (s-reuseport) {
 int b = s-reuseport;
-if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, b, sizeof(b)))
+if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, b, sizeof(b))  
0)
 log_warning_unit(UNIT(s)-id, SO_REUSEPORT failed: 
%m);
 }
 
-- 
1.8.4.3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 4/4] core: lazy distribute for Distribute pools

2013-11-17 Thread Shawn Landden
On Sun, Nov 17, 2013 at 2:28 PM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Sun, Nov 17, 2013 at 08:46:46PM +0100, Lennart Poettering wrote:
 On Sat, 16.11.13 13:18, Shawn Landden (sh...@churchofgit.com) wrote:
   varlistentry
  +
  termvarnameLazyDistribute=/varname/term
  +listitemparaTakes an boolean
  +value. If true, Distribute=n workers will 
  not be spawned
  +simultameously, but one at a time while 
  connections come it
  +until n are running. Because of the 
  nature of SO_REUSEPORT workers are
  +spawned at an exponentially decreasing 
  rate to the number of incoming connections./para/listitem
  +/varlistentry
  +
  +varlistentry

 Hmm, so I think support for SO_REUSEPORT should just be a special case
 of the Distribute= logic. i.e. When Distribute= is set but ReusePort is
 off, then we'd pass the same original listening socket to all services
 we spawn. If Distribute is set but ReusePort is on then we'd create a
 new socket when we want to spawn a new instance, and simply bind it to
 the same sockaddr as the original one.
What types of sockets allow multiple bind()s/accept()s without SO_REUSEPORT?
I don't see what the use is having a socket passed to children that
can't be used.

 Thinking about this: I have the suspicion that LazyDistribute shouldn't
 be an option but the normal and only behaviour...
 Agreed.
OK

 Also, I think ReusePort=1 should be the default if Distribute is used,
 and the kernel supports it. I don't think there are any downsides.
ReusePort=1 makes it where systemd no longer sits on the port which
prevents rogue applications
(root for 1024) from stealing the port.

 Zbyszek
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel



-- 

---
Shawn Landden
+1 360 389 3001 (SMS preferred)
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] use #pragma once instead of foo*foo define guards

2013-11-18 Thread Shawn Landden
---
 src/core/killall.h  | 5 +
 src/core/switch-root.h  | 5 +
 src/core/syscall-list.h | 5 +
 src/core/transaction.h  | 5 +
 src/login/logind-action.h   | 5 +
 src/login/logind-button.h   | 5 +
 src/login/logind-inhibit.h  | 5 +
 src/nss-myhostname/ifconf.h | 9 ++---
 src/shared/audit.h  | 5 +
 src/shared/capability.h | 5 +
 src/shared/cgroup-show.h| 5 +
 src/shared/conf-files.h | 5 +
 src/shared/hwclock.h| 5 +
 src/shared/spawn-polkit-agent.h | 5 +
 14 files changed, 15 insertions(+), 59 deletions(-)

diff --git a/src/core/killall.h b/src/core/killall.h
index d08ac14..95b110f 100644
--- a/src/core/killall.h
+++ b/src/core/killall.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef fookillallhfoo
-#define fookillallhfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -23,5 +22,3 @@
 ***/
 
 void broadcast_signal(int sig, bool wait);
-
-#endif
diff --git a/src/core/switch-root.h b/src/core/switch-root.h
index 0c4cd1e..ab493b5 100644
--- a/src/core/switch-root.h
+++ b/src/core/switch-root.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef fooswitchroothfoo
-#define fooswitchroothfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -23,5 +22,3 @@
 ***/
 
 int switch_root(const char *switch_root);
-
-#endif
diff --git a/src/core/syscall-list.h b/src/core/syscall-list.h
index 6bb4d91..37efc56 100644
--- a/src/core/syscall-list.h
+++ b/src/core/syscall-list.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef foosyscalllisthfoo
-#define foosyscalllisthfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -40,5 +39,3 @@ const char *syscall_to_name(int id);
 int syscall_from_name(const char *name);
 
 int syscall_max(void);
-
-#endif
diff --git a/src/core/transaction.h b/src/core/transaction.h
index 12f9194..b6ee237 100644
--- a/src/core/transaction.h
+++ b/src/core/transaction.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef footransactionhfoo
-#define footransactionhfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -53,5 +52,3 @@ int transaction_add_job_and_dependencies(
 int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError 
*e);
 int transaction_add_isolate_jobs(Transaction *tr, Manager *m);
 void transaction_abort(Transaction *tr);
-
-#endif
diff --git a/src/login/logind-action.h b/src/login/logind-action.h
index 5527136..74f7144 100644
--- a/src/login/logind-action.h
+++ b/src/login/logind-action.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef foologindactionhfoo
-#define foologindactionhfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -50,5 +49,3 @@ const char* handle_action_to_string(HandleAction h) _const_;
 HandleAction handle_action_from_string(const char *s) _pure_;
 
 int config_parse_handle_action(const char *unit, const char *filename, 
unsigned line, const char *section, const char *lvalue, int ltype, const char 
*rvalue, void *data, void *userdata);
-
-#endif
diff --git a/src/login/logind-button.h b/src/login/logind-button.h
index 83bf1fc..824106c 100644
--- a/src/login/logind-button.h
+++ b/src/login/logind-button.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef foologindbuttonhfoo
-#define foologindbuttonhfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -45,5 +44,3 @@ void button_free(Button*b);
 int button_open(Button *b);
 int button_recheck(Button *b);
 int button_set_seat(Button *b, const char *sn);
-
-#endif
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index ed3b2eb..da3d7e7 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef foologindinhibithfoo
-#define foologindinhibithfoo
+#pragma once
 
 /***
   This file is part of systemd.
@@ -93,5 +92,3 @@ InhibitWhat inhibit_what_from_string(const char *s);
 
 const char *inhibit_mode_to_string(InhibitMode k);
 InhibitMode inhibit_mode_from_string(const char *s);
-
-#endif
diff --git a/src/nss-myhostname/ifconf.h b/src/nss-myhostname/ifconf.h
index 2764a0a..cd598d2 100644
--- a/src/nss-myhostname/ifconf.h
+++ b/src/nss-myhostname/ifconf.h
@@ -1,9 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef fooifconfhfoo
-#define fooifconfhfoo
-
-#include sys/socket.h
+#pragma once
 
 /***
   This file is part of systemd.
@@ -27,6 +24,7 @@
 #include inttypes.h
 #include sys/types.h
 #include assert.h
+#include sys/socket.h
 
 struct address {
 unsigned char family;
@@ -68,6 +66,3 @@ static inline int address_compare(const void *_a, const void 
*_b) {
 
 return 0;
 }
-
-
-#endif
diff --git 

[systemd-devel] [PATCH] service: remove unneccesary Socket.got_socket_fd

2013-11-20 Thread Shawn Landden
---
 src/core/service.c | 3 +--
 src/core/service.h | 2 --
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/core/service.c b/src/core/service.c
index c0ee114..24f7a42 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2812,7 +2812,7 @@ _pure_ static bool service_check_snapshot(Unit *u) {
 
 assert(s);
 
-return !s-got_socket_fd;
+return (s-socket_fd  0);
 }
 
 static int service_retry_pid_file(Service *s) {
@@ -3695,7 +3695,6 @@ int service_set_socket_fd(Service *s, int fd, Socket 
*sock) {
 return -EAGAIN;
 
 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 37fa6ff..40c3a85 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
 
@@ -170,7 +169,6 @@ struct Service {
 bool main_pid_alien:1;
 bool bus_name_good:1;
 bool forbid_restart:1;
-bool got_socket_fd:1;
 bool start_timeout_defined:1;
 #ifdef HAVE_SYSV_COMPAT
 bool is_sysv:1;
-- 
1.8.4.3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 2/2] systemctl: add systemctl cat

2013-11-22 Thread Shawn Landden
---
 TODO  |  2 --
 src/shared/fileio.c   | 73 -
 src/shared/fileio.h   |  1 +
 src/systemctl/systemctl.c | 91 +++
 4 files changed, 149 insertions(+), 18 deletions(-)

diff --git a/TODO b/TODO
index 6ba4b31..7c6003b 100644
--- a/TODO
+++ b/TODO
@@ -125,8 +125,6 @@ Features:
 
 * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
cgroup_context_get_mask()
 
-* systemctl cat or systemctl view command or or so, that cats the backing 
unit file of a service, plus its drop-ins and shows them in a pager
-
 * 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
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 733b320..ac1b409 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,6 +20,7 @@
 ***/
 
 #include unistd.h
+#include sys/sendfile.h
 #include fileio.h
 #include util.h
 #include strv.h
@@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
 return 0;
 }
 
+ssize_t sendfile_full(int out_fd, const char *fn) {
+_cleanup_fclose_ FILE *f;
+struct stat st;
+int r;
+ssize_t s;
+
+size_t n, l;
+_cleanup_free_ char *buf = NULL;
+
+assert(out_fd  0);
+assert(fn);
+
+f = fopen(fn, r);
+if (!f)
+return -errno;
+
+r = fstat(fileno(f), st);
+if (r  0)
+return -errno;
+
+s = sendfile(out_fd, fileno(f), NULL, st.st_size);
+if (s  0)
+if (errno == EINVAL || errno == ENOSYS) {
+/* continue below */
+} else
+return -errno;
+else
+return s;
+
+/* sendfile() failed, fall back to read/write */
+
+/* Safety check */
+if (st.st_size  4*1024*1024)
+return -E2BIG;
+
+n = st.st_size  0 ? st.st_size : LINE_MAX;
+l = 0;
+
+while (true) {
+char *t;
+size_t k;
+
+t = realloc(buf, n);
+if (!t)
+return -ENOMEM;
+
+buf = t;
+k = fread(buf + l, 1, n - l, f);
+
+if (k = 0) {
+if (ferror(f))
+return -errno;
+
+break;
+}
+
+l += k;
+n *= 2;
+
+/* Safety check */
+if (n  4*1024*1024)
+return -E2BIG;
+}
+
+r = write(out_fd, buf, l);
+if (r  0)
+return -errno;
+
+return (ssize_t) l;
+}
+
 int read_full_file(const char *fn, char **contents, size_t *size) {
 _cleanup_fclose_ FILE *f = NULL;
 size_t n, l;
@@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
-buf = NULL;
 
 if (size)
 *size = l;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index 59e4150..06c2887 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
*line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(const char *fname, const char *separator, char ***l);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 576396f..18d5e45 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3665,16 +3665,25 @@ static int show_all(
 return 0;
 }
 
-static int get_unit_from_arg(sd_bus *bus, char *arg, char **unitp, bool 
interpret_as_job_id) {
-uint32_t id;
+static int cat(sd_bus *bus, char **args) {
 int r = 0;
+char **name;
 
-if (safe_atou32(arg, id)  0) {
-_cleanup_free_ char *n = NULL;
-char *unit;
-/* Interpret as unit name */
+_cleanup_free_ char *unit = NULL, *n = NULL;
+
+assert(bus);
+assert(args);
 
-n = unit_name_mangle(arg);
+pager_open_if_enabled();
+
+STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *fragment_path = NULL;
+_cleanup_strv_free_ char **dropin_paths = NULL;
+sd_bus_error error;
+FILE *stdout;
+char **path;
+
+n = unit_name_mangle(*name);
 if (!n)
 

[systemd-devel] [PATCH 1/2] systemctl: refactor show()

2013-11-22 Thread Shawn Landden
---
 src/systemctl/systemctl.c | 66 ++-
 1 file changed, 43 insertions(+), 23 deletions(-)

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 84826a3..576396f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3594,16 +3594,13 @@ static int show_one(
 return r;
 }
 
-static int show_one_by_pid(
-const char *verb,
+static int get_unit_dbus_path_by_pid(
 sd_bus *bus,
 uint32_t pid,
-bool *new_line,
-bool *ellipsized) {
+char **unit) {
 
 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-const char *path = NULL;
 int r;
 
 r = sd_bus_call_method(
@@ -3620,11 +3617,11 @@ static int show_one_by_pid(
 return r;
 }
 
-r = sd_bus_message_read(reply, o, path);
+r = sd_bus_message_read(reply, o, unit);
 if (r  0)
 return bus_log_parse_error(r);
 
-return show_one(verb, bus, path, false, new_line, ellipsized);
+return 0;
 }
 
 static int show_all(
@@ -3668,6 +3665,36 @@ static int show_all(
 return 0;
 }
 
+static int get_unit_from_arg(sd_bus *bus, char *arg, char **unitp, bool 
interpret_as_job_id) {
+uint32_t id;
+int r = 0;
+
+if (safe_atou32(arg, id)  0) {
+_cleanup_free_ char *n = NULL;
+char *unit;
+/* Interpret as unit name */
+
+n = unit_name_mangle(arg);
+if (!n)
+return log_oom();
+
+unit = unit_dbus_path_from_name(n);
+if (!unit)
+return log_oom();
+
+*unitp = unit;
+} else if (interpret_as_job_id) {
+/* Interpret as job id */
+if (asprintf(unitp, /org/freedesktop/systemd1/job/%u, id)  
0)
+return log_oom();
+} else {
+/* Interpret as PID */
+r = get_unit_by_pid(bus, id, unitp);
+}
+
+return r;
+}
+
 static int show(sd_bus *bus, char **args) {
 int r, ret = 0;
 bool show_properties, show_status, new_line = false;
@@ -3692,41 +3719,34 @@ static int show(sd_bus *bus, char **args) {
 ret = show_all(args[0], bus, false, new_line, ellipsized);
 else
 STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *unit = NULL;
 uint32_t id;
 
 if (safe_atou32(*name, id)  0) {
-_cleanup_free_ char *p = NULL, *n = NULL;
+_cleanup_free_ char *n = NULL;
 /* Interpret as unit name */
 
 n = unit_name_mangle(*name);
 if (!n)
 return log_oom();
 
-p = unit_dbus_path_from_name(n);
-if (!p)
+unit = unit_dbus_path_from_name(n);
+if (!unit)
 return log_oom();
 
-r = show_one(args[0], bus, p, show_properties, 
new_line, ellipsized);
-if (r != 0)
-ret = r;
-
 } else if (show_properties) {
-_cleanup_free_ char *p = NULL;
-
 /* Interpret as job id */
-if (asprintf(p, 
/org/freedesktop/systemd1/job/%u, id)  0)
+if (asprintf(unit, 
/org/freedesktop/systemd1/job/%u, id)  0)
 return log_oom();
 
-r = show_one(args[0], bus, p, show_properties, 
new_line, ellipsized);
-if (r != 0)
-ret = r;
-
 } else {
 /* Interpret as PID */
-r = show_one_by_pid(args[0], bus, id, 
new_line, ellipsized);
-if (r != 0)
+r = get_unit_dbus_path_by_pid(bus, id, unit);
+if (r  0)
 ret = r;
 }
+
+show_one(args[0], bus, unit, show_properties, 
new_line, ellipsized);
 }
 
 if (ellipsized  !arg_quiet)
-- 
1.8.4.3

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] core/socket: we only want one event on standard sockets

2013-11-22 Thread Shawn Landden
With EPOLLONESHOT we are guaranteed to only recieve one event
until we reload with socket_enter_listening(s), otherwise
multiple events can be generated upon receipt of multiple chunks of data.

We also only want wake-ups when external events happen, i.e.
edge-triggered wakeups.
---
 src/core/socket.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/socket.c b/src/core/socket.c
index 5fa4a5a..2f860a4 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1119,7 +1119,9 @@ static int socket_watch_fds(Socket *s) {
 if (p-event_source)
 r = sd_event_source_set_enabled(p-event_source, 
SD_EVENT_ON);
 else
-r = sd_event_add_io(UNIT(s)-manager-event, p-fd, 
EPOLLIN, socket_dispatch_io, p, p-event_source);
+r = sd_event_add_io(UNIT(s)-manager-event, p-fd,
+EPOLLIN|EPOLLET|((s-accept || 
s-distribute) ? 0 : EPOLLONESHOT),
+socket_dispatch_io, p, 
p-event_source);
 
 if (r  0) {
 log_warning_unit(UNIT(s)-id, Failed to watch 
listening fds: %s, strerror(-r));
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] systemctl: refactor show()

2013-11-23 Thread Shawn Landden
v2, don't leave in unused function
---
 src/systemctl/systemctl.c | 36 +---
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 84826a3..6cb7a82 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3594,16 +3594,13 @@ static int show_one(
 return r;
 }
 
-static int show_one_by_pid(
-const char *verb,
+static int get_unit_dbus_path_by_pid(
 sd_bus *bus,
 uint32_t pid,
-bool *new_line,
-bool *ellipsized) {
+char **unit) {
 
 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-const char *path = NULL;
 int r;
 
 r = sd_bus_call_method(
@@ -3620,11 +3617,11 @@ static int show_one_by_pid(
 return r;
 }
 
-r = sd_bus_message_read(reply, o, path);
+r = sd_bus_message_read(reply, o, unit);
 if (r  0)
 return bus_log_parse_error(r);
 
-return show_one(verb, bus, path, false, new_line, ellipsized);
+return 0;
 }
 
 static int show_all(
@@ -3692,41 +3689,34 @@ static int show(sd_bus *bus, char **args) {
 ret = show_all(args[0], bus, false, new_line, ellipsized);
 else
 STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *unit = NULL;
 uint32_t id;
 
 if (safe_atou32(*name, id)  0) {
-_cleanup_free_ char *p = NULL, *n = NULL;
+_cleanup_free_ char *n = NULL;
 /* Interpret as unit name */
 
 n = unit_name_mangle(*name);
 if (!n)
 return log_oom();
 
-p = unit_dbus_path_from_name(n);
-if (!p)
+unit = unit_dbus_path_from_name(n);
+if (!unit)
 return log_oom();
 
-r = show_one(args[0], bus, p, show_properties, 
new_line, ellipsized);
-if (r != 0)
-ret = r;
-
 } else if (show_properties) {
-_cleanup_free_ char *p = NULL;
-
 /* Interpret as job id */
-if (asprintf(p, 
/org/freedesktop/systemd1/job/%u, id)  0)
+if (asprintf(unit, 
/org/freedesktop/systemd1/job/%u, id)  0)
 return log_oom();
 
-r = show_one(args[0], bus, p, show_properties, 
new_line, ellipsized);
-if (r != 0)
-ret = r;
-
 } else {
 /* Interpret as PID */
-r = show_one_by_pid(args[0], bus, id, 
new_line, ellipsized);
-if (r != 0)
+r = get_unit_dbus_path_by_pid(bus, id, unit);
+if (r  0)
 ret = r;
 }
+
+show_one(args[0], bus, unit, show_properties, 
new_line, ellipsized);
 }
 
 if (ellipsized  !arg_quiet)
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 2/2] systemctl: add systemctl cat

2013-11-23 Thread Shawn Landden
---
 TODO  |  2 --
 src/shared/fileio.c   | 73 -
 src/shared/fileio.h   |  1 +
 src/systemctl/systemctl.c | 91 +++
 4 files changed, 164 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 6ba4b31..7c6003b 100644
--- a/TODO
+++ b/TODO
@@ -125,8 +125,6 @@ Features:
 
 * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
cgroup_context_get_mask()
 
-* systemctl cat or systemctl view command or or so, that cats the backing 
unit file of a service, plus its drop-ins and shows them in a pager
-
 * 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
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 733b320..ac1b409 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,6 +20,7 @@
 ***/
 
 #include unistd.h
+#include sys/sendfile.h
 #include fileio.h
 #include util.h
 #include strv.h
@@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
 return 0;
 }
 
+ssize_t sendfile_full(int out_fd, const char *fn) {
+_cleanup_fclose_ FILE *f;
+struct stat st;
+int r;
+ssize_t s;
+
+size_t n, l;
+_cleanup_free_ char *buf = NULL;
+
+assert(out_fd  0);
+assert(fn);
+
+f = fopen(fn, r);
+if (!f)
+return -errno;
+
+r = fstat(fileno(f), st);
+if (r  0)
+return -errno;
+
+s = sendfile(out_fd, fileno(f), NULL, st.st_size);
+if (s  0)
+if (errno == EINVAL || errno == ENOSYS) {
+/* continue below */
+} else
+return -errno;
+else
+return s;
+
+/* sendfile() failed, fall back to read/write */
+
+/* Safety check */
+if (st.st_size  4*1024*1024)
+return -E2BIG;
+
+n = st.st_size  0 ? st.st_size : LINE_MAX;
+l = 0;
+
+while (true) {
+char *t;
+size_t k;
+
+t = realloc(buf, n);
+if (!t)
+return -ENOMEM;
+
+buf = t;
+k = fread(buf + l, 1, n - l, f);
+
+if (k = 0) {
+if (ferror(f))
+return -errno;
+
+break;
+}
+
+l += k;
+n *= 2;
+
+/* Safety check */
+if (n  4*1024*1024)
+return -E2BIG;
+}
+
+r = write(out_fd, buf, l);
+if (r  0)
+return -errno;
+
+return (ssize_t) l;
+}
+
 int read_full_file(const char *fn, char **contents, size_t *size) {
 _cleanup_fclose_ FILE *f = NULL;
 size_t n, l;
@@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
-buf = NULL;
 
 if (size)
 *size = l;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index 59e4150..06c2887 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
*line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(const char *fname, const char *separator, char ***l);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 6cb7a82..18d5e45 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3665,6 +3665,95 @@ static int show_all(
 return 0;
 }
 
+static int cat(sd_bus *bus, char **args) {
+int r = 0;
+char **name;
+
+_cleanup_free_ char *unit = NULL, *n = NULL;
+
+assert(bus);
+assert(args);
+
+pager_open_if_enabled();
+
+STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *fragment_path = NULL;
+_cleanup_strv_free_ char **dropin_paths = NULL;
+sd_bus_error error;
+FILE *stdout;
+char **path;
+
+n = unit_name_mangle(*name);
+if (!n)
+return log_oom();
+
+unit = unit_dbus_path_from_name(n);
+if (!unit)
+return log_oom();
+
+if (need_daemon_reload(bus, n)) {
+log_error(Unit file of %s changed on disk. Run 
'systemctl%s daemon-reload'.,
+ 

[systemd-devel] [PATCH] nspawn: Give a more helpful error message when -D argument is bogus.

2013-11-25 Thread Shawn Landden
---
 src/nspawn/nspawn.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 0973a00..1ee4ab3 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -200,6 +200,11 @@ static int parse_argv(int argc, char *argv[]) {
 
 case 'D':
 free(arg_directory);
+if (access(optarg, F_OK)  0) {
+log_error(Root directory %s is not 
accessable: %m, optarg);
+return -EACCES;
+}
+
 arg_directory = canonicalize_file_name(optarg);
 if (!arg_directory) {
 log_error(Failed to canonicalize root 
directory.);
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] core/socket: we only want one event on standard sockets

2013-11-26 Thread Shawn Landden
As we only reciece one event at a time, and dequeue it in the same go,
yeah ONESHOT won't change anything.

On Tue, Nov 26, 2013 at 9:33 AM, David Timothy Strauss
da...@davidstrauss.net wrote:
 On Wed, Nov 27, 2013 at 2:32 AM, Lennart Poettering
 lenn...@poettering.net wrote:
 Well, but EPOLLET only works correctly if each time an event is
 triggered we dispatch *all* possibly queued events on the fd, until
 EAGAIN is read again. But we don't do that, heck, if Listen=no is used
 we don''t even read a single incoming connection of the scket, we leave
 that to the daemon we spawn, but we cannot trust that. So, I don't get
 what EPOLLET is supposed to do good here?

 I should have more selectively quoted before answering. I was only
 trying to answer why we'd continue having poll for the socket fds
 after queuing the initial service. I was not trying to suggest EPOLLET
 is appropriate for the goal of lazy distribute process pool
 expansion. You've clearly correct about that.
I was worried that the fact that we never accept() the socket when using
distribute (now I am convinced we shouldn't use it otherwise)
would cause it to trigger multiple times for only one incoming connection,
if the spawned thread never entered accept() (or we raced it),
but reading this thread makes me think I don't fully understand the
semantics of EPOLLET.
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] core/socket: we only want one event on standard sockets

2013-11-26 Thread Shawn Landden
On Tue, Nov 26, 2013 at 1:48 PM, David Timothy Strauss
da...@davidstrauss.net wrote:
 On Wed, Nov 27, 2013 at 6:23 AM, Shawn Landden sh...@churchofgit.com wrote:
 I was worried that the fact that we never accept() the socket when using
 distribute (now I am convinced we shouldn't use it otherwise)

 I'm not sure what you mean here. Distribute-style functionality is
 absolutely useful with Accept=true (to cap the number of simultaneous
 connections)
Are you sure applications can handle the extra file descriptor of
passing both the sockfd
and the acceptfd in this case? I don't see why they wouldn't just do
the accept() themselves?

Can you explain what you mean here, and how it differs from the
existing MaxConnections.

 as well as Accept=false (to allow running of a process
 pool of self-accepting, long-running workers).

 would cause it to trigger multiple times for only one incoming connection,
 if the spawned thread never entered accept() (or we raced it),
 but reading this thread makes me think I don't fully understand the
 semantics of EPOLLET.

 There are some decent examples on the man page: 
 http://linux.die.net/man/7/epoll
Yeah I had read that, and seen it in the kernel source. I am just
confused and need to think about it some more.

-Shawn
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] core/socket: we only want one event on standard sockets

2013-11-27 Thread Shawn Landden
On Tue, Nov 26, 2013 at 7:57 PM, David Timothy Strauss
da...@davidstrauss.net wrote:
 On Wed, Nov 27, 2013 at 7:57 AM, Shawn Landden sh...@churchofgit.com wrote:
 Are you sure applications can handle the extra file descriptor of
 passing both the sockfd
 and the acceptfd in this case? I don't see why they wouldn't just do
 the accept() themselves?

 Can you explain what you mean here, and how it differs from the
 existing MaxConnections.

 Actually, MaxConnections was exactly what I was thinking of. I agree
 with you now on Distribute=true only being useful with Accept=false.
The current code I have has Distribute take a number, but it certainly
would be possible to use
the MaxConnections number---however I don't do that as connections
isn't quite the
right word, and we can't easily change it because it is part of the API.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] systemctl: add systemctl cat

2013-11-28 Thread Shawn Landden
---
 TODO  |  2 -
 src/shared/fileio.c   | 73 ++-
 src/shared/fileio.h   |  1 +
 src/shared/util.c |  2 +
 src/systemctl/systemctl.c | 97 +++
 5 files changed, 172 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 6ba4b31..7c6003b 100644
--- a/TODO
+++ b/TODO
@@ -125,8 +125,6 @@ Features:
 
 * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
cgroup_context_get_mask()
 
-* systemctl cat or systemctl view command or or so, that cats the backing 
unit file of a service, plus its drop-ins and shows them in a pager
-
 * 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
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 733b320..ac1b409 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,6 +20,7 @@
 ***/
 
 #include unistd.h
+#include sys/sendfile.h
 #include fileio.h
 #include util.h
 #include strv.h
@@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
 return 0;
 }
 
+ssize_t sendfile_full(int out_fd, const char *fn) {
+_cleanup_fclose_ FILE *f;
+struct stat st;
+int r;
+ssize_t s;
+
+size_t n, l;
+_cleanup_free_ char *buf = NULL;
+
+assert(out_fd  0);
+assert(fn);
+
+f = fopen(fn, r);
+if (!f)
+return -errno;
+
+r = fstat(fileno(f), st);
+if (r  0)
+return -errno;
+
+s = sendfile(out_fd, fileno(f), NULL, st.st_size);
+if (s  0)
+if (errno == EINVAL || errno == ENOSYS) {
+/* continue below */
+} else
+return -errno;
+else
+return s;
+
+/* sendfile() failed, fall back to read/write */
+
+/* Safety check */
+if (st.st_size  4*1024*1024)
+return -E2BIG;
+
+n = st.st_size  0 ? st.st_size : LINE_MAX;
+l = 0;
+
+while (true) {
+char *t;
+size_t k;
+
+t = realloc(buf, n);
+if (!t)
+return -ENOMEM;
+
+buf = t;
+k = fread(buf + l, 1, n - l, f);
+
+if (k = 0) {
+if (ferror(f))
+return -errno;
+
+break;
+}
+
+l += k;
+n *= 2;
+
+/* Safety check */
+if (n  4*1024*1024)
+return -E2BIG;
+}
+
+r = write(out_fd, buf, l);
+if (r  0)
+return -errno;
+
+return (ssize_t) l;
+}
+
 int read_full_file(const char *fn, char **contents, size_t *size) {
 _cleanup_fclose_ FILE *f = NULL;
 size_t n, l;
@@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
-buf = NULL;
 
 if (size)
 *size = l;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index 59e4150..06c2887 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
*line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(const char *fname, const char *separator, char ***l);
diff --git a/src/shared/util.c b/src/shared/util.c
index deb74c4..e6a32b9 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5904,6 +5904,8 @@ void* greedy_realloc(void **p, size_t *allocated, size_t 
need) {
 size_t a;
 void *q;
 
+assert(allocated);
+
 if (*allocated = need)
 return *p;
 
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 6cb7a82..633c07d 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3665,6 +3665,101 @@ static int show_all(
 return 0;
 }
 
+static int cat(sd_bus *bus, char **args) {
+int r = 0;
+char **name;
+
+_cleanup_free_ char *unit = NULL, *n = NULL;
+
+assert(bus);
+assert(args);
+
+pager_open_if_enabled();
+
+STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *fragment_path = NULL;
+_cleanup_strv_free_ char **dropin_paths = NULL;
+sd_bus_error error;
+FILE *stdout;
+char **path;
+
+n = unit_name_mangle(*name);

Re: [systemd-devel] [PATCH 2/2] systemctl: add systemctl cat

2013-11-28 Thread Shawn Landden
On Wed, Nov 27, 2013 at 11:59 PM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Sat, Nov 23, 2013 at 07:52:53PM -0800, Shawn Landden wrote:
 ---
  TODO  |  2 --
  src/shared/fileio.c   | 73 -
  src/shared/fileio.h   |  1 +
  src/systemctl/systemctl.c | 91 
 +++
  4 files changed, 164 insertions(+), 3 deletions(-)

 diff --git a/TODO b/TODO
 index 6ba4b31..7c6003b 100644
 --- a/TODO
 +++ b/TODO
 @@ -125,8 +125,6 @@ Features:

  * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
 cgroup_context_get_mask()

 -* systemctl cat or systemctl view command or or so, that cats the 
 backing unit file of a service, plus its drop-ins and shows them in a pager
 -
  * 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

  * tmpfiles: when applying ownership to /run/log/journal, also do this for 
 the journal fails contained in it
 diff --git a/src/shared/fileio.c b/src/shared/fileio.c
 index 733b320..ac1b409 100644
 --- a/src/shared/fileio.c
 +++ b/src/shared/fileio.c
 @@ -20,6 +20,7 @@
  ***/

  #include unistd.h
 +#include sys/sendfile.h
  #include fileio.h
  #include util.h
  #include strv.h
 @@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
  return 0;
  }

 +ssize_t sendfile_full(int out_fd, const char *fn) {
 +_cleanup_fclose_ FILE *f;
 +struct stat st;
 +int r;
 +ssize_t s;
 +
 +size_t n, l;
 +_cleanup_free_ char *buf = NULL;
 +
 +assert(out_fd  0);
 +assert(fn);
 +
 +f = fopen(fn, r);
 +if (!f)
 +return -errno;
 +
 +r = fstat(fileno(f), st);
 +if (r  0)
 +return -errno;
 +
 +s = sendfile(out_fd, fileno(f), NULL, st.st_size);
 +if (s  0)
 +if (errno == EINVAL || errno == ENOSYS) {
 +/* continue below */
 +} else
 +return -errno;
 +else
 +return s;
 +
 +/* sendfile() failed, fall back to read/write */
 +
 +/* Safety check */
 +if (st.st_size  4*1024*1024)
 +return -E2BIG;
 +
 +n = st.st_size  0 ? st.st_size : LINE_MAX;
 +l = 0;
 +
 +while (true) {
 +char *t;
 +size_t k;
 +
 +t = realloc(buf, n);
 +if (!t)
 +return -ENOMEM;
 Can you convert this to GREEDY_REALLOC? It should be a bit simpler then.
GREEDY_REALLOC isn't appropriate here, (or read_full_file() which this
code is from), as in general stat is going to succeed and we are going
to read
the whole file in one run.

 +
 +buf = t;
 +k = fread(buf + l, 1, n - l, f);
 +
 +if (k = 0) {
 +if (ferror(f))
 +return -errno;
 +
 +break;
 +}
 +
 +l += k;
 +n *= 2;
 +
 +/* Safety check */
 +if (n  4*1024*1024)
 +return -E2BIG;
 +}
 +
 +r = write(out_fd, buf, l);
 +if (r  0)
 +return -errno;
 +
 +return (ssize_t) l;
 +}
 +
  int read_full_file(const char *fn, char **contents, size_t *size) {
  _cleanup_fclose_ FILE *f = NULL;
  size_t n, l;
 @@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, 
 size_t *size) {

  buf[l] = 0;
  *contents = buf;
 -buf = NULL;

  if (size)
  *size = l;
 diff --git a/src/shared/fileio.h b/src/shared/fileio.h
 index 59e4150..06c2887 100644
 --- a/src/shared/fileio.h
 +++ b/src/shared/fileio.h
 @@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
 *line);

  int read_one_line_file(const char *fn, char **line);
  int read_full_file(const char *fn, char **contents, size_t *size);
 +ssize_t sendfile_full(int out_fd, const char *fn);

  int parse_env_file(const char *fname, const char *separator, ...) 
 _sentinel_;
  int load_env_file(const char *fname, const char *separator, char ***l);
 diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
 index 6cb7a82..18d5e45 100644
 --- a/src/systemctl/systemctl.c
 +++ b/src/systemctl/systemctl.c
 @@ -3665,6 +3665,95 @@ static int show_all(
  return 0;
  }

 +static int cat(sd_bus *bus, char **args) {
 +int r = 0;
 +char **name;
 +
 +_cleanup_free_ char *unit = NULL, *n = NULL;
 +
 +assert(bus);
 +assert(args);
 +
 +pager_open_if_enabled();
 +
 +STRV_FOREACH(name, args+1) {
 +_cleanup_free_ char *fragment_path = NULL;
 +_cleanup_strv_free_ char

[systemd-devel] [PATCH] systemctl: add systemctl cat

2013-11-28 Thread Shawn Landden
v3: log_warning() inserts a trailing newline
---
 TODO  |  2 -
 src/shared/fileio.c   | 73 ++-
 src/shared/fileio.h   |  1 +
 src/shared/util.c |  2 +
 src/systemctl/systemctl.c | 97 +++
 5 files changed, 172 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 6ba4b31..7c6003b 100644
--- a/TODO
+++ b/TODO
@@ -125,8 +125,6 @@ Features:
 
 * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
cgroup_context_get_mask()
 
-* systemctl cat or systemctl view command or or so, that cats the backing 
unit file of a service, plus its drop-ins and shows them in a pager
-
 * 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
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 733b320..ac1b409 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,6 +20,7 @@
 ***/
 
 #include unistd.h
+#include sys/sendfile.h
 #include fileio.h
 #include util.h
 #include strv.h
@@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
 return 0;
 }
 
+ssize_t sendfile_full(int out_fd, const char *fn) {
+_cleanup_fclose_ FILE *f;
+struct stat st;
+int r;
+ssize_t s;
+
+size_t n, l;
+_cleanup_free_ char *buf = NULL;
+
+assert(out_fd  0);
+assert(fn);
+
+f = fopen(fn, r);
+if (!f)
+return -errno;
+
+r = fstat(fileno(f), st);
+if (r  0)
+return -errno;
+
+s = sendfile(out_fd, fileno(f), NULL, st.st_size);
+if (s  0)
+if (errno == EINVAL || errno == ENOSYS) {
+/* continue below */
+} else
+return -errno;
+else
+return s;
+
+/* sendfile() failed, fall back to read/write */
+
+/* Safety check */
+if (st.st_size  4*1024*1024)
+return -E2BIG;
+
+n = st.st_size  0 ? st.st_size : LINE_MAX;
+l = 0;
+
+while (true) {
+char *t;
+size_t k;
+
+t = realloc(buf, n);
+if (!t)
+return -ENOMEM;
+
+buf = t;
+k = fread(buf + l, 1, n - l, f);
+
+if (k = 0) {
+if (ferror(f))
+return -errno;
+
+break;
+}
+
+l += k;
+n *= 2;
+
+/* Safety check */
+if (n  4*1024*1024)
+return -E2BIG;
+}
+
+r = write(out_fd, buf, l);
+if (r  0)
+return -errno;
+
+return (ssize_t) l;
+}
+
 int read_full_file(const char *fn, char **contents, size_t *size) {
 _cleanup_fclose_ FILE *f = NULL;
 size_t n, l;
@@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
-buf = NULL;
 
 if (size)
 *size = l;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index 59e4150..06c2887 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
*line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(const char *fname, const char *separator, char ***l);
diff --git a/src/shared/util.c b/src/shared/util.c
index deb74c4..e6a32b9 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5904,6 +5904,8 @@ void* greedy_realloc(void **p, size_t *allocated, size_t 
need) {
 size_t a;
 void *q;
 
+assert(allocated);
+
 if (*allocated = need)
 return *p;
 
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 6cb7a82..284020c 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3665,6 +3665,101 @@ static int show_all(
 return 0;
 }
 
+static int cat(sd_bus *bus, char **args) {
+int r = 0;
+char **name;
+
+_cleanup_free_ char *unit = NULL, *n = NULL;
+
+assert(bus);
+assert(args);
+
+pager_open_if_enabled();
+
+STRV_FOREACH(name, args+1) {
+_cleanup_free_ char *fragment_path = NULL;
+_cleanup_strv_free_ char **dropin_paths = NULL;
+sd_bus_error error;
+FILE *stdout;
+char **path;
+

[systemd-devel] [PATCH 1/2] nspawn: --populate to run static binaries on empty target directory

2013-11-30 Thread Shawn Landden
nspawn has been called chroot on steroids.

Continue that tradition by supporting target directories that
are not root directories.

This patch handles the simple case: a static binary.
---
 Makefile.am|   2 +
 man/systemd-nspawn.xml |  11 +
 src/nspawn/elf.c   | 127 +
 src/nspawn/elf.h   |  30 
 src/nspawn/nspawn.c|  46 +++---
 src/shared/path-util.c |  57 --
 src/shared/path-util.h |   5 +-
 7 files changed, 256 insertions(+), 22 deletions(-)
 create mode 100644 src/nspawn/elf.c
 create mode 100644 src/nspawn/elf.h

diff --git a/Makefile.am b/Makefile.am
index 47c269d..da905a5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1839,6 +1839,8 @@ systemd_cgtop_LDADD = \
 # 
--
 systemd_nspawn_SOURCES = \
src/nspawn/nspawn.c \
+   src/nspawn/elf.c \
+   src/nspawn/elf.h \
src/core/mount-setup.c \
src/core/mount-setup.h \
src/core/loopback-setup.c \
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 75d2e6d..24bc0d7 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -211,6 +211,17 @@
 /varlistentry
 
 varlistentry
+termoption-p/option/term
+termoption--populate/option/term
+
+listitemparaIf COMMAND does not exist in
+target root directory, launch host 
COMMAND./para
+
+paraCan be used on empty target directories
+(if COMMAND a static 
executable)./para/listitem
+/varlistentry
+
+varlistentry
 termoption-u/option/term
 termoption--user=/option/term
 
diff --git a/src/nspawn/elf.c b/src/nspawn/elf.c
new file mode 100644
index 000..c399d59
--- /dev/null
+++ b/src/nspawn/elf.c
@@ -0,0 +1,127 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see http://www.gnu.org/licenses/.
+***/
+
+
+#include elf.h
+#include fcntl.h
+
+#include elf.h
+#include util.h
+#include log.h
+
+int analyze_executable(const char *path,
+   int *_fd,
+   bool *_elf64,
+   char **_linker,
+   char **shebang) {
+
+char e_ident[sizeof(Elf64_Ehdr)];
+uint16_t e_type;
+bool elf64;
+int fd = -1;
+int r;
+
+assert(path);
+assert(_elf64);
+assert(_linker);
+assert(shebang);
+
+fd = open(path, O_RDONLY | O_CLOEXEC);
+if (fd  0) {
+log_error(open(\%s\) failed: %m, path);
+return -errno;
+}
+
+r = read(fd, e_ident, sizeof(Elf64_Ehdr));
+if (r  0) {
+log_error(read() on %s failed: %m, path);
+return -errno;
+}
+
+if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
+log_error(%s is not an ELF executable., path);
+return -ENOSYS;
+} else
+if (shebang)
+*shebang = NULL;
+
+switch (e_ident[EI_CLASS]) {
+case ELFCLASS32:
+elf64 = false;
+break;
+case ELFCLASS64:
+elf64 = true;
+break;
+default:
+log_error(Unknown ELF class.);
+return -EINVAL;
+}
+
+if (elf64) {
+Elf64_Ehdr *ehdr = (Elf64_Ehdr *)e_ident;
+
+e_type = ehdr-e_type;
+} else {
+Elf32_Ehdr *ehdr = (Elf32_Ehdr *)e_ident;
+
+e_type = ehdr-e_type;
+}
+
+/* Not checking e_ident[E_DATA], file is assumed to be of host 
endianness. */
+if (e_type != ET_EXEC) {
+log_error(%s is not an ELF executable, or is of alien 
endianness., path);
+return -EINVAL;
+}
+
+char phdrs[e_phentsize * e_phnum];
+char *phdr;
+
+lseek(fd, e_phoff, SEEK_SET);
+r = read(fd

[systemd-devel] [PATCH 2/2] nspawn: --populate with dynamic libs and one-file scripts

2013-11-30 Thread Shawn Landden
the whitelist of dynamic linker paths comes from clang
---
 src/nspawn/elf.c| 174 ++-
 src/nspawn/elf.h|  14 +++-
 src/nspawn/nspawn.c | 191 +---
 src/shared/util.c   |  80 ++
 src/shared/util.h   |   2 +
 5 files changed, 435 insertions(+), 26 deletions(-)

diff --git a/src/nspawn/elf.c b/src/nspawn/elf.c
index c399d59..2f0b7ef 100644
--- a/src/nspawn/elf.c
+++ b/src/nspawn/elf.c
@@ -26,23 +26,30 @@
 #include elf.h
 #include util.h
 #include log.h
+#include strv.h
 
 int analyze_executable(const char *path,
int *_fd,
bool *_elf64,
char **_linker,
-   char **shebang) {
+   char **shebang,
+   char ***_libs) {
 
-char e_ident[sizeof(Elf64_Ehdr)];
+char e_ident[MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr))];
 uint16_t e_type;
+off_t e_phoff;
+uint16_t e_phentsize, e_phnum;
 bool elf64;
-int fd = -1;
+_cleanup_close_ int fd = -1;
+bool have_interp = false;
 int r;
 
 assert(path);
+assert(_fd);
 assert(_elf64);
 assert(_linker);
 assert(shebang);
+assert(_libs);
 
 fd = open(path, O_RDONLY | O_CLOEXEC);
 if (fd  0) {
@@ -50,18 +57,59 @@ int analyze_executable(const char *path,
 return -errno;
 }
 
-r = read(fd, e_ident, sizeof(Elf64_Ehdr));
+r = read(fd, e_ident, MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr)));
 if (r  0) {
-log_error(read() on %s failed: %m, path);
+log_error(read() on %s failed: %s, path, strerror(errno));
 return -errno;
 }
 
 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
-log_error(%s is not an ELF executable., path);
-return -ENOSYS;
-} else
-if (shebang)
-*shebang = NULL;
+if (startswith(e_ident, #!)) {
+_cleanup_close_ int shebang_fd = -1;
+char shebang_e_ident[sizeof(Elf64_Ehdr)];
+char *t;
+
+  /* from 
fs/binfmt_script.c:42 */
+t = (char *)e_ident + strcspn(e_ident,  \t\n);
+t[0] = '\0';
+
+t = e_ident[2];
+
+shebang_fd = open(t, O_RDONLY|O_CLOEXEC);
+if (shebang_fd  0) {
+log_error(Cannot read interpreter %s: %m, t);
+return -errno;
+}
+
+r = read(shebang_fd, shebang_e_ident, 
sizeof(Elf64_Ehdr));
+if (r  SELFMAG) {
+log_error(read() on %s failed: %s, t, 
strerror(r  0 ? errno : EIO));
+return -errno;
+}
+
+/* the kernel actually supports interpreters of 
interpreters
+ * but we don't support that here */
+if (memcmp(shebang_e_ident, ELFMAG, SELFMAG) != 0) {
+log_error(Interpreter %s is not an ELF 
executable., t);
+return -EINVAL;
+}
+
+*_fd = fd;
+fd = shebang_fd; /* analyze and */
+shebang_fd = -1; /* don't close ELF */
+*shebang = strdup(t);
+if (!*shebang)
+return log_oom();
+
+memcpy(e_ident, shebang_e_ident, sizeof(Elf64_Ehdr));
+} else {
+log_error(%s is not an ELF executable or script 
starting with #!., path);
+return -ENOSYS;
+}
+} else {
+*_fd = fd;
+*shebang = NULL;
+}
 
 switch (e_ident[EI_CLASS]) {
 case ELFCLASS32:
@@ -79,10 +127,16 @@ int analyze_executable(const char *path,
 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)e_ident;
 
 e_type = ehdr-e_type;
+e_phoff = ehdr-e_phoff;
+e_phentsize = ehdr-e_phentsize;
+e_phnum = ehdr-e_phnum;
 } else {
 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)e_ident;
 
 e_type = ehdr-e_type;
+e_phoff = ehdr-e_phoff;
+e_phentsize = ehdr-e_phentsize;
+e_phnum = ehdr-e_phnum;
 }
 
 /* Not checking e_ident[E_DATA], file is assumed to be of host 
endianness. */
@@ -113,15 +167,103 @@ int analyze_executable(const char *path,
 }
 
 if (!have_interp) {
- 

[systemd-devel] [PATCH] systemctl: add systemctl cat

2013-11-30 Thread Shawn Landden
---
 TODO  |   2 -
 man/systemctl.xml |   9 
 src/shared/fileio.c   |  73 ++-
 src/shared/fileio.h   |   1 +
 src/shared/util.c |   2 +
 src/systemctl/systemctl.c | 107 ++
 6 files changed, 191 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 6ba4b31..7c6003b 100644
--- a/TODO
+++ b/TODO
@@ -125,8 +125,6 @@ Features:
 
 * optimize the cgroup propagation bits, especially unit_get_members_mask(), 
cgroup_context_get_mask()
 
-* systemctl cat or systemctl view command or or so, that cats the backing 
unit file of a service, plus its drop-ins and shows them in a pager
-
 * 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
 
 * tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 33a2935..8a66130 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -727,7 +727,16 @@ kobject-uevent 1 systemd-udevd-kernel.socket 
systemd-udevd.service
 human-readable output./para
   /listitem
 /varlistentry
+varlistentry
+  termcommandcat 
replaceableNAME/replaceable.../command/term
 
+  listitem
+paraShow backing files of one or more units.
+Prints the fragment, drop-ins, and source (sysvinit compat)
+of units. Each file is preceded by a comment which includes the
+file name./para
+  /listitem
+/varlistentry
 varlistentry
   termcommandset-property replaceableNAME/replaceable 
replaceableASSIGNMENT/replaceable.../command/term
 
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 733b320..ac1b409 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,6 +20,7 @@
 ***/
 
 #include unistd.h
+#include sys/sendfile.h
 #include fileio.h
 #include util.h
 #include strv.h
@@ -117,6 +118,77 @@ int read_one_line_file(const char *fn, char **line) {
 return 0;
 }
 
+ssize_t sendfile_full(int out_fd, const char *fn) {
+_cleanup_fclose_ FILE *f;
+struct stat st;
+int r;
+ssize_t s;
+
+size_t n, l;
+_cleanup_free_ char *buf = NULL;
+
+assert(out_fd  0);
+assert(fn);
+
+f = fopen(fn, r);
+if (!f)
+return -errno;
+
+r = fstat(fileno(f), st);
+if (r  0)
+return -errno;
+
+s = sendfile(out_fd, fileno(f), NULL, st.st_size);
+if (s  0)
+if (errno == EINVAL || errno == ENOSYS) {
+/* continue below */
+} else
+return -errno;
+else
+return s;
+
+/* sendfile() failed, fall back to read/write */
+
+/* Safety check */
+if (st.st_size  4*1024*1024)
+return -E2BIG;
+
+n = st.st_size  0 ? st.st_size : LINE_MAX;
+l = 0;
+
+while (true) {
+char *t;
+size_t k;
+
+t = realloc(buf, n);
+if (!t)
+return -ENOMEM;
+
+buf = t;
+k = fread(buf + l, 1, n - l, f);
+
+if (k = 0) {
+if (ferror(f))
+return -errno;
+
+break;
+}
+
+l += k;
+n *= 2;
+
+/* Safety check */
+if (n  4*1024*1024)
+return -E2BIG;
+}
+
+r = write(out_fd, buf, l);
+if (r  0)
+return -errno;
+
+return (ssize_t) l;
+}
+
 int read_full_file(const char *fn, char **contents, size_t *size) {
 _cleanup_fclose_ FILE *f = NULL;
 size_t n, l;
@@ -168,7 +240,6 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
-buf = NULL;
 
 if (size)
 *size = l;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index 59e4150..06c2887 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -31,6 +31,7 @@ int write_string_file_atomic(const char *fn, const char 
*line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(const char *fname, const char *separator, char ***l);
diff --git a/src/shared/util.c b/src/shared/util.c
index deb74c4..e6a32b9 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5904,6 +5904,8 @@ void* greedy_realloc(void **p, size_t *allocated, size_t 
need) {
 size_t a;
   

Re: [systemd-devel] build broken on clang

2013-11-30 Thread Shawn Landden
On Sat, Nov 30, 2013 at 5:46 PM, Greg KH gre...@linuxfoundation.org wrote:
 On Sun, Dec 01, 2013 at 12:38:44AM +0100, Thomas H.P. Andersen wrote:
 Hi,

 Since 777d7a6123cbb192a8ff9e4ac5c05b1da84b4217 the build is broken on clang:

 src/libsystemd-bus/bus-control.c:686:41: error: fields must have a
 constant size: 'variable length array in structure' extension will
 never be supported
 uint8_t buffer[sz];
 ^
 src/libsystemd-bus/bus-control.c:748:33: error: fields must have a
 constant size: 'variable length array in structure' extension will
 never be supported
 uint8_t buffer[sz];

 Seems like someone needs to fix clang with this well-known gcc
 extension :)
There was a whole talk about this at the recent Linux Plumbers Conference 2013
http://www.linuxplumbersconf.org/2013/ocw/sessions/1221
http://www.youtube.com/watch?v=aliQx0uDSX0

 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] fix regression of read_full_file() in fileio.c

2013-11-30 Thread Shawn Landden
my e93c33d4aa broke this stupidly
---
 src/shared/fileio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index ac1b409..ede8819 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -240,6 +240,7 @@ int read_full_file(const char *fn, char **contents, size_t 
*size) {
 
 buf[l] = 0;
 *contents = buf;
+buf = NULL; /* do not free */
 
 if (size)
 *size = l;
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [RFC 05/12] gfx: add sd-gfx library with unifont section

2013-11-30 Thread Shawn Landden
On Sat, Nov 30, 2013 at 9:28 PM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Wed, Nov 27, 2013 at 07:48:40PM +0100, David Herrmann wrote:
 As a first step, we add the required header+build-chain and add the
 font-handling. To avoid heavy font-pipelines in systemd, we only provide
 a statically-sized fallback-font based on GNU-Unifont.
 Hi David,
 I don't think that GNU-Unifont is licensed in a way that allows it to
 be embedded in systemd. Systemd is LGPLv2+, while Unifont is GPLv2+ + 
 FontException.
 FontException allows embedding in documents, so it doesn't apply.
 It would be possible have some sources which are GPLv2+ only, but I
 think we want to avoid such complications.

 Also, if the font was embedded in systemd, distributions would then
 remove it in order to replace is with the system version. So I think
 that including the font sources is pointless... Debian has it packaged [1],
 but an old version, I'm not sure if there have been recent updates, and
 possibly in the wrong format. Fedora doesn't seem to have it yet.
 But adding fonts is easy, I'd do the Fedora package myself, and other
 distributions could surely add/update it.

 So if it is acceptable for systemd-gfx *binary* to be GPLv2+ licensed,
 we could use the system unifont.hex file at build time, and actually
 link it into the binary. I propose that we try to go this way.

 Or we could have the package also contain the converted font in appropriate
 format, and mmap it at runtime. But this is more complex, and doesn't actually
 avoid the licensing issue, since the font would still be GPLv2+.
The font is needed in the initramfs

 Zbyszek

 [1] http://packages.debian.org/sid/all/unifont/filelist
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/4] nspawn: shorten conditional path

2013-12-01 Thread Shawn Landden
---
 src/nspawn/nspawn.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index dd7337b..0151cf3 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -481,10 +481,8 @@ static int setup_timezone(const char *dest) {
 return 0;
 }
 
-z = path_startswith(p, ../usr/share/zoneinfo/);
-if (!z)
-z = path_startswith(p, /usr/share/zoneinfo/);
-if (!z) {
+if ((z = path_startswith(p, ../usr/share/zoneinfo/)) ||
+(z = path_startswith(p, /usr/share/zoneinfo/))) {
 log_warning(/etc/localtime does not point into 
/usr/share/zoneinfo/, not updating container timezone.);
 return 0;
 }
@@ -495,14 +493,11 @@ static int setup_timezone(const char *dest) {
 
 r = readlink_malloc(where, q);
 if (r = 0) {
-y = path_startswith(q, ../usr/share/zoneinfo/);
-if (!y)
-y = path_startswith(q, /usr/share/zoneinfo/);
-
-
-/* Already pointing to the right place? Then do nothing .. */
-if (y  streq(y, z))
-return 0;
+if ((y = path_startswith(q, ../usr/share/zoneinfo/)) ||
+(y = path_startswith(q, /usr/share/zoneinfo/)))
+/* Already pointing to the right place? Then do 
nothing .. */
+if (streq(y, z))
+return 0;
 }
 
 check = strjoin(dest, /usr/share/zoneinfo/, z, NULL);
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 2/4] shared: mark strv_length() _pure_

2013-12-01 Thread Shawn Landden
---
 src/shared/strv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/shared/strv.c b/src/shared/strv.c
index 607c221..cc6adfa 100644
--- a/src/shared/strv.c
+++ b/src/shared/strv.c
@@ -84,7 +84,7 @@ char **strv_copy(char * const *l) {
 return r;
 }
 
-unsigned strv_length(char * const *l) {
+_pure_ unsigned strv_length(char * const *l) {
 unsigned n = 0;
 
 if (!l)
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 4/4] nspawn: --populate with dynamic libs and one-file scripts

2013-12-01 Thread Shawn Landden
the whitelist of dynamic linker paths comes from clang
---
 man/systemd-nspawn.xml |   8 +--
 src/nspawn/elf.c   | 162 +
 src/nspawn/elf.h   |  14 +++-
 src/nspawn/nspawn.c| 191 ++---
 src/shared/util.c  |  80 +
 src/shared/util.h  |   2 +
 6 files changed, 431 insertions(+), 26 deletions(-)

diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 24bc0d7..723ec09 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -214,11 +214,11 @@
 termoption-p/option/term
 termoption--populate/option/term
 
-listitemparaIf COMMAND does not exist in
-target root directory, launch host 
COMMAND./para
+listitemparaUse COMMAND from host./para
 
-paraCan be used on empty target directories
-(if COMMAND a static 
executable)./para/listitem
+paraCan be used on empty target directories,
+if COMMAND an ELF executable, or
+one-file script./para/listitem
 /varlistentry
 
 varlistentry
diff --git a/src/nspawn/elf.c b/src/nspawn/elf.c
index f91b374..62d0fda 100644
--- a/src/nspawn/elf.c
+++ b/src/nspawn/elf.c
@@ -26,44 +26,90 @@
 #include elf.h
 #include util.h
 #include log.h
+#include strv.h
 
 int analyze_executable(const char *path,
int *_fd,
bool *_elf64,
char **_linker,
-   char **shebang) {
+   char **shebang,
+   char ***_libs) {
 
-char e_ident[sizeof(Elf64_Ehdr)];
+char e_ident[MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr))];
 uint16_t e_type;
 off_t e_phoff;
 uint16_t e_phentsize, e_phnum;
 bool elf64;
-int fd = -1;
+_cleanup_close_ int fd = -1;
 bool have_interp = false;
 int r;
 
 assert(path);
+assert(_fd);
 assert(_elf64);
 assert(_linker);
 assert(shebang);
+assert(_libs);
 
 fd = open(path, O_RDONLY | O_CLOEXEC);
 if (fd  0) {
-log_error(open(\%s\) failed: %m, path);
+log_error(open(%s) failed: %m, path);
 return -errno;
 }
 
-r = read(fd, e_ident, sizeof(Elf64_Ehdr));
+r = read(fd, e_ident, MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr)));
 if (r  0) {
-log_error(read() on %s failed: %m, path);
+log_error(read(%s) failed: %s, path, strerror(errno));
 return -errno;
 }
 
 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
-log_error(%s is not an ELF executable., path);
-return -ENOSYS;
-} else
+if (startswith(e_ident, #!)) {
+_cleanup_close_ int shebang_fd = -1;
+char shebang_e_ident[sizeof(Elf64_Ehdr)];
+char *t;
+
+  /* from 
fs/binfmt_script.c:42 */
+t = e_ident + strcspn(e_ident,  \t\n);
+t[0] = '\0';
+
+t = e_ident[2];
+
+shebang_fd = open(t, O_RDONLY|O_CLOEXEC);
+if (shebang_fd  0) {
+log_error(Cannot open interpreter %s: %m, t);
+return -errno;
+}
+
+r = read(shebang_fd, shebang_e_ident, 
sizeof(Elf64_Ehdr));
+if (r  SELFMAG) {
+log_error(read(%s) failed: %s, t, strerror(r 
 0 ? errno : EIO));
+return -errno;
+}
+
+/* The kernel actually supports interpreters of 
interpreters
+ * but we don't support that here. */
+if (memcmp(shebang_e_ident, ELFMAG, SELFMAG) != 0) {
+log_error(Interpreter %s is not an ELF 
executable., t);
+return -EINVAL;
+}
+
+*_fd = fd;
+fd = shebang_fd; /* analyze and */
+shebang_fd = -1; /* don't close ELF */
+*shebang = strdup(t);
+if (!*shebang)
+return log_oom();
+
+memcpy(e_ident, shebang_e_ident, sizeof(Elf64_Ehdr));
+} else {
+log_error(%s is not an ELF executable or script 
starting with #!., 

[systemd-devel] [PATCH 3/4] nspawn: --populate to run static binaries on empty target directory

2013-12-01 Thread Shawn Landden
nspawn has been called chroot on steroids.

Continue that tradition by supporting target directories that
are not root directories.

This patch handles the simple case: a static binary.
---
 Makefile.am|   2 +
 man/systemd-nspawn.xml |  11 +
 src/nspawn/elf.c   | 131 +
 src/nspawn/elf.h   |  30 +++
 src/nspawn/nspawn.c|  47 +++---
 src/shared/path-util.c |  57 +++--
 src/shared/path-util.h |   5 +-
 7 files changed, 260 insertions(+), 23 deletions(-)
 create mode 100644 src/nspawn/elf.c
 create mode 100644 src/nspawn/elf.h

diff --git a/Makefile.am b/Makefile.am
index 7a45029..67c26f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1832,6 +1832,8 @@ systemd_cgtop_LDADD = \
 # 
--
 systemd_nspawn_SOURCES = \
src/nspawn/nspawn.c \
+   src/nspawn/elf.c \
+   src/nspawn/elf.h \
src/core/mount-setup.c \
src/core/mount-setup.h \
src/core/loopback-setup.c \
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 75d2e6d..24bc0d7 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -211,6 +211,17 @@
 /varlistentry
 
 varlistentry
+termoption-p/option/term
+termoption--populate/option/term
+
+listitemparaIf COMMAND does not exist in
+target root directory, launch host 
COMMAND./para
+
+paraCan be used on empty target directories
+(if COMMAND a static 
executable)./para/listitem
+/varlistentry
+
+varlistentry
 termoption-u/option/term
 termoption--user=/option/term
 
diff --git a/src/nspawn/elf.c b/src/nspawn/elf.c
new file mode 100644
index 000..f91b374
--- /dev/null
+++ b/src/nspawn/elf.c
@@ -0,0 +1,131 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Shawn Landden
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see http://www.gnu.org/licenses/.
+***/
+
+
+#include elf.h
+#include fcntl.h
+
+#include elf.h
+#include util.h
+#include log.h
+
+int analyze_executable(const char *path,
+   int *_fd,
+   bool *_elf64,
+   char **_linker,
+   char **shebang) {
+
+char e_ident[sizeof(Elf64_Ehdr)];
+uint16_t e_type;
+off_t e_phoff;
+uint16_t e_phentsize, e_phnum;
+bool elf64;
+int fd = -1;
+bool have_interp = false;
+int r;
+
+assert(path);
+assert(_elf64);
+assert(_linker);
+assert(shebang);
+
+fd = open(path, O_RDONLY | O_CLOEXEC);
+if (fd  0) {
+log_error(open(\%s\) failed: %m, path);
+return -errno;
+}
+
+r = read(fd, e_ident, sizeof(Elf64_Ehdr));
+if (r  0) {
+log_error(read() on %s failed: %m, path);
+return -errno;
+}
+
+if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
+log_error(%s is not an ELF executable., path);
+return -ENOSYS;
+} else
+*shebang = NULL;
+
+switch (e_ident[EI_CLASS]) {
+case ELFCLASS32:
+elf64 = false;
+break;
+case ELFCLASS64:
+elf64 = true;
+break;
+default:
+log_error(Unknown ELF class.);
+return -EINVAL;
+}
+
+if (elf64) {
+Elf64_Ehdr *ehdr = (Elf64_Ehdr *)e_ident;
+
+e_type = ehdr-e_type;
+e_phoff = ehdr-e_phoff;
+e_phentsize = ehdr-e_phentsize;
+e_phnum = ehdr-e_phnum;
+} else {
+Elf32_Ehdr *ehdr = (Elf32_Ehdr *)e_ident;
+
+e_type = ehdr-e_type;
+e_phoff = ehdr-e_phoff;
+e_phentsize = ehdr-e_phentsize;
+e_phnum = ehdr-e_phnum;
+}
+
+/* Not checking e_ident[E_DATA], file is assumed to be of host

[systemd-devel] [PATCH] nspawn: --populate with dynamic libs and one-file scripts

2013-12-01 Thread Shawn Landden
the whitelist of dynamic linker paths comes from clang
---
 man/systemd-nspawn.xml |   8 +--
 src/nspawn/elf.c   | 161 +
 src/nspawn/elf.h   |  14 +++-
 src/nspawn/nspawn.c| 191 ++---
 src/shared/util.c  |  80 +
 src/shared/util.h  |   2 +
 6 files changed, 430 insertions(+), 26 deletions(-)

diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 24bc0d7..723ec09 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -214,11 +214,11 @@
 termoption-p/option/term
 termoption--populate/option/term
 
-listitemparaIf COMMAND does not exist in
-target root directory, launch host 
COMMAND./para
+listitemparaUse COMMAND from host./para
 
-paraCan be used on empty target directories
-(if COMMAND a static 
executable)./para/listitem
+paraCan be used on empty target directories,
+if COMMAND an ELF executable, or
+one-file script./para/listitem
 /varlistentry
 
 varlistentry
diff --git a/src/nspawn/elf.c b/src/nspawn/elf.c
index f91b374..63ada56 100644
--- a/src/nspawn/elf.c
+++ b/src/nspawn/elf.c
@@ -26,44 +26,90 @@
 #include elf.h
 #include util.h
 #include log.h
+#include strv.h
 
 int analyze_executable(const char *path,
int *_fd,
bool *_elf64,
char **_linker,
-   char **shebang) {
+   char **shebang,
+   char ***_libs) {
 
-char e_ident[sizeof(Elf64_Ehdr)];
+char e_ident[MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr))];
 uint16_t e_type;
 off_t e_phoff;
 uint16_t e_phentsize, e_phnum;
 bool elf64;
-int fd = -1;
+_cleanup_close_ int fd = -1;
 bool have_interp = false;
 int r;
 
 assert(path);
+assert(_fd);
 assert(_elf64);
 assert(_linker);
 assert(shebang);
+assert(_libs);
 
 fd = open(path, O_RDONLY | O_CLOEXEC);
 if (fd  0) {
-log_error(open(\%s\) failed: %m, path);
+log_error(open(%s) failed: %m, path);
 return -errno;
 }
 
-r = read(fd, e_ident, sizeof(Elf64_Ehdr));
+r = read(fd, e_ident, MAX(2u + PATH_MAX, sizeof(Elf64_Ehdr)));
 if (r  0) {
-log_error(read() on %s failed: %m, path);
+log_error(read(%s) failed: %s, path, strerror(errno));
 return -errno;
 }
 
 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
-log_error(%s is not an ELF executable., path);
-return -ENOSYS;
-} else
+if (startswith(e_ident, #!)) {
+_cleanup_close_ int shebang_fd = -1;
+char shebang_e_ident[sizeof(Elf64_Ehdr)];
+char *t;
+
+  /* from 
fs/binfmt_script.c:42 */
+t = e_ident + strcspn(e_ident,  \t\n);
+t[0] = '\0';
+
+t = e_ident[2];
+
+shebang_fd = open(t, O_RDONLY|O_CLOEXEC);
+if (shebang_fd  0) {
+log_error(Cannot open interpreter %s: %m, t);
+return -errno;
+}
+
+r = read(shebang_fd, shebang_e_ident, 
sizeof(Elf64_Ehdr));
+if (r  SELFMAG) {
+log_error(read(%s) failed: %s, t, strerror(r 
 0 ? errno : EIO));
+return -errno;
+}
+
+/* The kernel actually supports interpreters of 
interpreters
+ * but we don't support that here. */
+if (memcmp(shebang_e_ident, ELFMAG, SELFMAG) != 0) {
+log_error(Interpreter %s is not an ELF 
executable., t);
+return -EINVAL;
+}
+
+*_fd = fd;
+fd = shebang_fd; /* analyze and */
+shebang_fd = -1; /* don't close ELF */
+*shebang = strdup(t);
+if (!*shebang)
+return log_oom();
+
+memcpy(e_ident, shebang_e_ident, sizeof(Elf64_Ehdr));
+} else {
+log_error(%s is not an ELF executable or script 
starting with #!., 

[systemd-devel] [PATCH] nspawn: shorten conditional path

2013-12-01 Thread Shawn Landden
---
 src/nspawn/nspawn.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index dd7337b..f400a65 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -481,10 +481,8 @@ static int setup_timezone(const char *dest) {
 return 0;
 }
 
-z = path_startswith(p, ../usr/share/zoneinfo/);
-if (!z)
-z = path_startswith(p, /usr/share/zoneinfo/);
-if (!z) {
+if (!((z = path_startswith(p, ../usr/share/zoneinfo/)) ||
+  (z = path_startswith(p,   /usr/share/zoneinfo/ {
 log_warning(/etc/localtime does not point into 
/usr/share/zoneinfo/, not updating container timezone.);
 return 0;
 }
@@ -495,14 +493,11 @@ static int setup_timezone(const char *dest) {
 
 r = readlink_malloc(where, q);
 if (r = 0) {
-y = path_startswith(q, ../usr/share/zoneinfo/);
-if (!y)
-y = path_startswith(q, /usr/share/zoneinfo/);
-
-
-/* Already pointing to the right place? Then do nothing .. */
-if (y  streq(y, z))
-return 0;
+if ((y = path_startswith(q, ../usr/share/zoneinfo/)) ||
+(y = path_startswith(q,   /usr/share/zoneinfo/)))
+/* Already pointing to the right place? Then do 
nothing .. */
+if (streq(y, z))
+return 0;
 }
 
 check = strjoin(dest, /usr/share/zoneinfo/, z, NULL);
-- 
1.8.4.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/2] nspawn: --populate to run static binaries on empty target directory

2013-12-02 Thread Shawn Landden
On Mon, Dec 2, 2013 at 8:27 AM, Lennart Poettering
lenn...@poettering.net wrote:
 On Sat, 30.11.13 10:20, Shawn Landden (sh...@churchofgit.com) wrote:

 nspawn has been called chroot on steroids.

 Continue that tradition by supporting target directories that
 are not root directories.

 This patch handles the simple case: a static binary.

 Hmm, I am not sure how I feel about this. This appears a bit too
 specific for me, and given the requirement for static binaries this is
 also so limited.
The next patch is the series adds support for dynamic libraries. This patch
also doesn't need bind mounts, and it executes through /proc/self/fd/%n, but
support for one-file scripts and dynamic libraries in the next patch does
require bind mounts. I feel you don't really understand my patch. :/
I'll sum up what I'm doing:

If --populate is passed, analyze the executable, which opens it and set the
exec path to /proc/self/fd/%n. If executable is static this is all you
have to do.

If it has a shebang, analyze that. If either the shebang or executable
is dynamic,
test if the linker is the GNU linker, and if it is have the linker
tell use what libraries the
executable needs. Then bind mount the linker, shebang (if there is one), and
libraries into the target.

Unmount these when the machine shuts down.

 I wonder if we can find a different way to support this, without adding
 high-level switches to nspawn itself.

 For example, couldn't extending --bind= a bit to also support bind
 mounting files (in contrast to just directories the way it currently
 does) already gets us 90% of the way? And then do the rest 10% by adding
 an example how to use this to bind mount static binaries from the host
 into the container to the example in the man page? Allowing bind
 mounting of files has been on the TODO list for a while anyway...

 Something like:

 # systemd-nspawn -D /srv/mycontainer 
 --bind=/usr/bin/populate-container:/tmp/populate-container 
 /tmp/populate-container

 This of course wouldn't check if the file executed is staticall linked,
 but the user should quickly get an error about missing .sos if it isn't?
No, the linker would be missing, and the user would get execvpe()
failed: No such file or directory,
which is confusing.

  assert_se(sigemptyset(mask) == 0);
 @@ -1164,7 +1195,7 @@ int main(int argc, char *argv[]) {
  gid_t gid = (gid_t) -1;
  unsigned n_env = 2;
  const char *envp[] = {
 -
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,
 +DEFAULT_PATH_SPLIT_USR,

 This bit looks like like something we really should do though. Could you
 isolate this out and resubmit, please?


 +#define DEFAULT_PATH_SPLIT_USR 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 +
  #ifdef HAVE_SPLIT_USR
 -#  define DEFAULT_PATH 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 +#  define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
  #else
  #  define DEFAULT_PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
  #endif
 @@ -51,6 +53,7 @@ int path_is_mount_point(const char *path, bool 
 allow_symlink);
  int path_is_read_only_fs(const char *path);
  int path_is_os_tree(const char *path);

 And this too, of course...

 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/2] nspawn: --populate to run static binaries on empty target directory

2013-12-03 Thread Shawn Landden
On Mon, Dec 2, 2013 at 9:41 AM, Shawn Landden sh...@churchofgit.com wrote:
 On Mon, Dec 2, 2013 at 8:27 AM, Lennart Poettering
 lenn...@poettering.net wrote:
 On Sat, 30.11.13 10:20, Shawn Landden (sh...@churchofgit.com) wrote:

 nspawn has been called chroot on steroids.

 Continue that tradition by supporting target directories that
 are not root directories.

 This patch handles the simple case: a static binary.

 Hmm, I am not sure how I feel about this. This appears a bit too
 specific for me, and given the requirement for static binaries this is
 also so limited.
 The next patch is the series adds support for dynamic libraries. This patch
 also doesn't need bind mounts, and it executes through /proc/self/fd/%n, but
 support for one-file scripts and dynamic libraries in the next patch does
 require bind mounts. I feel you don't really understand my patch. :/
 I'll sum up what I'm doing:

 If --populate is passed, analyze the executable, which opens it and set the
 exec path to /proc/self/fd/%n. If executable is static this is all you
 have to do.

 If it has a shebang, analyze that. If either the shebang or executable
 is dynamic,
 test if the linker is the GNU linker, and if it is have the linker
 tell use what libraries the
 executable needs. Then bind mount the linker, shebang (if there is one), and
 libraries into the target.

 Unmount these when the machine shuts down.

 I wonder if we can find a different way to support this, without adding
 high-level switches to nspawn itself.

 For example, couldn't extending --bind= a bit to also support bind
 mounting files (in contrast to just directories the way it currently
 does) already gets us 90% of the way? And then do the rest 10% by adding
 an example how to use this to bind mount static binaries from the host
 into the container to the example in the man page? Allowing bind
 mounting of files has been on the TODO list for a while anyway...
I'll add a bind mount file feature, and then rebase the second patch
on top of that.

 Something like:

 # systemd-nspawn -D /srv/mycontainer 
 --bind=/usr/bin/populate-container:/tmp/populate-container 
 /tmp/populate-container

 This of course wouldn't check if the file executed is staticall linked,
 but the user should quickly get an error about missing .sos if it isn't?
 No, the linker would be missing, and the user would get execvpe()
 failed: No such file or directory,
 which is confusing.

  assert_se(sigemptyset(mask) == 0);
 @@ -1164,7 +1195,7 @@ int main(int argc, char *argv[]) {
  gid_t gid = (gid_t) -1;
  unsigned n_env = 2;
  const char *envp[] = {
 -
 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,
 +DEFAULT_PATH_SPLIT_USR,

 This bit looks like like something we really should do though. Could you
 isolate this out and resubmit, please?


 +#define DEFAULT_PATH_SPLIT_USR 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 +
  #ifdef HAVE_SPLIT_USR
 -#  define DEFAULT_PATH 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 +#  define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
  #else
  #  define DEFAULT_PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
  #endif
 @@ -51,6 +53,7 @@ int path_is_mount_point(const char *path, bool 
 allow_symlink);
  int path_is_read_only_fs(const char *path);
  int path_is_os_tree(const char *path);

 And this too, of course...

 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] nspawn: fix buggy mount_binds, now works for bind-mounted files

2013-12-05 Thread Shawn Landden
---
 src/nspawn/nspawn.c | 42 ++
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index dd7337b..c1212c0 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -416,6 +416,7 @@ static int mount_all(const char *dest) {
 
 static int mount_binds(const char *dest, char **l, unsigned long flags) {
 char **x, **y;
+int r;
 
 STRV_FOREACH_PAIR(x, y, l) {
 _cleanup_free_ char *where = NULL;
@@ -426,31 +427,40 @@ static int mount_binds(const char *dest, char **l, 
unsigned long flags) {
 return -errno;
 }
 
-where = strjoin(dest, /, *y, NULL);
+where = strjoin(dest, *y, NULL);
 if (!where)
 return log_oom();
 
-if (stat(where, dest_st) == 0) {
+r = stat(where, dest_st);
+if (r == 0) {
 if ((source_st.st_mode  S_IFMT) != (dest_st.st_mode  
S_IFMT)) {
 log_error(The file types of %s and %s do not 
match. Refusing bind mount,
 *x, where);
 return -EINVAL;
 }
-} else {
-/* Create the mount point, but be conservative -- 
refuse to create block
- * and char devices. */
-if (S_ISDIR(source_st.st_mode))
-mkdir_p_label(where, 0755);
-else if (S_ISFIFO(source_st.st_mode))
-mkfifo(where, 0644);
-else if (S_ISSOCK(source_st.st_mode))
-mknod(where, 0644 | S_IFSOCK, 0);
-else if (S_ISREG(source_st.st_mode))
-touch(where);
-else {
-log_error(Refusing to create mountpoint for 
file: %s, *x);
-return -ENOTSUP;
+} else if (errno == ENOENT) {
+r = mkdir_parents_label(where, 0755);
+if (r  0) {
+log_error(Failed to bind mount %s: %s, *x, 
strerror(-r));
+return r;
 }
+} else {
+log_error(Failed to bind mount %s: %s, *x, 
strerror(errno));
+return -errno;
+}
+/* Create the mount point, but be conservative -- refuse to 
create block
+* and char devices. */
+if (S_ISDIR(source_st.st_mode))
+mkdir_label(where, 0755);
+else if (S_ISFIFO(source_st.st_mode))
+mkfifo(where, 0644);
+else if (S_ISSOCK(source_st.st_mode))
+mknod(where, 0644 | S_IFSOCK, 0);
+else if (S_ISREG(source_st.st_mode))
+touch(where);
+else {
+log_error(Refusing to create mountpoint for file: 
%s, *x);
+return -ENOTSUP;
 }
 
 if (mount(*x, where, bind, MS_BIND, NULL)  0) {
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] systemd-nspawn and kernel command line

2013-12-07 Thread Shawn Landden
On Sat, Dec 7, 2013 at 10:33 AM, Colin Guthrie gm...@colin.guthr.ie wrote:
 Hi,

 When playing with systemd-nspawn, is there a way to override the kernel
 command line seen inside the container. I mean it's probably not correct
 that the host systems /proc/cmdline leaks into the container.
No it is not, /proc/cmdline cannot be changed. What is your use case?
Perhaps this could be added to UTS namespaces?

 Cheers

 Col

 --

 Colin Guthrie
 gmane(at)colin.guthr.ie
 http://colin.guthr.ie/

 Day Job:
   Tribalogic Limited http://www.tribalogic.net/
 Open Source:
   Mageia Contributor http://www.mageia.org/
   PulseAudio Hacker http://www.pulseaudio.org/
   Trac Hacker http://trac.edgewall.org/

 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] systemd-nspawn and kernel command line

2013-12-07 Thread Shawn Landden
On Sat, Dec 7, 2013 at 11:03 AM, Colin Guthrie gm...@colin.guthr.ie wrote:
 'Twas brillig, and Shawn Landden at 07/12/13 18:57 did gyre and gimble:
 On Sat, Dec 7, 2013 at 10:33 AM, Colin Guthrie gm...@colin.guthr.ie wrote:
 Hi,

 When playing with systemd-nspawn, is there a way to override the kernel
 command line seen inside the container. I mean it's probably not correct
 that the host systems /proc/cmdline leaks into the container.

 No it is not, /proc/cmdline cannot be changed. What is your use case?
 Perhaps this could be added to UTS namespaces?

 Could you not bind mount over it with a temporary file? Might be kinda
 tricky to do tho' if it is possible.
I didn't think of this. This is totally possible, and should now work
in recent git.
(but not any released versions)
--bind=/foo/newcmdline:/proc/cmdline

where newcmdline is a regular file

 My main use case is that we have a rescue system which passes rescue
 on the command line of the host system.

 If I use this system to boot containers (which would typically be the
 system we are rescuing, then it reads this rescue is read in the
 container and starts rescue.target automatically rather than whatever
 default.target is. We'd probably want to specifically boot a
 multi-user.target by default and the best way to do that temporarily
 would be to provide a fake command line to the booted instance.

 Now we could change what we use to identify our rescue image, but it
 would seem to me that this shouldn't be needed and faking kernel command
 lines as seen by containers should be something that's possible.

 Cheers!

 Col





 --

 Colin Guthrie
 gmane(at)colin.guthr.ie
 http://colin.guthr.ie/

 Day Job:
   Tribalogic Limited http://www.tribalogic.net/
 Open Source:
   Mageia Contributor http://www.mageia.org/
   PulseAudio Hacker http://www.pulseaudio.org/
   Trac Hacker http://trac.edgewall.org/
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] test: rework run_qemu

2013-12-07 Thread Shawn Landden
On Sat, Dec 7, 2013 at 3:01 PM, Ronny Chevalier
chevalier.ro...@gmail.com wrote:
 It tries to find a suitable QEMU binary and will use KVM if present.
 We can now configure QEMU from outside with 4 variables :
   - $QEMU_BIN : path to QEMU's binary
   - $KERNEL_APPEND : arguments appended to kernel cmdline
   - $KERNEL_BIN : path to a kernel
 Default /boot/vmlinuz-$KERNEL_VER
   - $INITRD : path to an initramfs
 Default /boot/initramfs-${KERNEL_VER}.img
   - $QEMU_SMP : number of CPU simulated by QEMU.
 Default 1

 (from Alexander Graf's script: http://www.spinics.net/lists/kvm/msg72389.html)
 ---
  TODO|  1 -
  test/README.testsuite   | 19 ++--
  test/TEST-01-BASIC/test.sh  |  8 ++---
  test/TEST-02-CRYPTSETUP/test.sh |  8 ++---
  test/TEST-03-JOBS/test.sh   |  8 ++---
  test/test-functions | 65 
 +++--
  6 files changed, 78 insertions(+), 31 deletions(-)

 diff --git a/TODO b/TODO
 index 9698082..f493dbb 100644
 --- a/TODO
 +++ b/TODO
 @@ -168,7 +168,6 @@ Features:
  * test/:
- add 'set -e' to scripts in test/
- make stuff in test/ work with separate output dir
 -  - qemu wrapper script: http://www.spinics.net/lists/kvm/msg72389.html

  * systemctl delete x.snapshot leaves no trace in logs (at least at default 
 level).

 diff --git a/test/README.testsuite b/test/README.testsuite
 index 54d0eaa..2ae85a2 100644
 --- a/test/README.testsuite
 +++ b/test/README.testsuite
 @@ -25,11 +25,24 @@ $ make all
  $ cd test/TEST-01-BASIC
  $ sudo make clean setup run

 +QEMU
 +
 +
  If you want to log in the testsuite virtual machine, you can specify
 -additional kernel command line parameter with $DEBUGFAIL.
 +additional kernel command line parameter with $KERNEL_APPEND.

 -$ sudo make DEBUGFAIL=systemd.unit=multi-user.target clean setup run
 +$ sudo make KERNEL_APPEND=systemd.unit=multi-user.target clean setup run

  you can even skip the clean and setup if you want to run the machine 
 again.

 -$ sudo make DEBUGFAIL=systemd.unit=multi-user.target run
 +$ sudo make KERNEL_APPEND=systemd.unit=multi-user.target run
 +
 +You can specify a different kernel and initramfs with $KERNEL_BIN and 
 $INITRD.
 +(Fedora's default kernel path and initramfs are used by default)
 +
 +$ sudo make KERNEL_BIN=/boot/vmlinuz-foo INITRD=/boot/initramfs-bar clean 
 check
 +
 +A script will try to find your QEMU binary. If you want to specify a 
 different
 +one you can use $QEMU_BIN.
 +
 +$ sudo make QEMU_BIN=/path/to/qemu/qemu-kvm clean check
 diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh
 index aaf63f4..84ccf26 100755
 --- a/test/TEST-01-BASIC/test.sh
 +++ b/test/TEST-01-BASIC/test.sh
 @@ -5,9 +5,6 @@ TEST_DESCRIPTION=Basic systemd setup

  . $TEST_BASE_DIR/test-functions

 -# Uncomment this to debug failures
 -#DEBUGFAIL=systemd.unit=multi-user.target
 -
  check_result_qemu() {
  ret=1
  mkdir -p $TESTDIR/root
 @@ -23,11 +20,10 @@ check_result_qemu() {
  }

  test_run() {
 -if check_qemu ; then
 -run_qemu
 +if run_qemu; then
  check_result_qemu || return 1
  else
 -dwarn can't run qemu-kvm, skipping
 +dwarn can't run QEMU, skipping
  fi
  if check_nspawn; then
  run_nspawn
 diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
 index 86617df..d7e8776 100755
 --- a/test/TEST-02-CRYPTSETUP/test.sh
 +++ b/test/TEST-02-CRYPTSETUP/test.sh
 @@ -5,9 +5,6 @@ TEST_DESCRIPTION=cryptsetup systemd setup

  . $TEST_BASE_DIR/test-functions

 -# Uncomment this to debug failures
 -#DEBUGFAIL=systemd.unit=multi-user.target
 -
  check_result_qemu() {
  ret=1
  mkdir -p $TESTDIR/root
 @@ -28,11 +25,10 @@ check_result_qemu() {


  test_run() {
 -if check_qemu ; then
 -run_qemu
 +if run_qemu; then
  check_result_qemu || return 1
  else
 -dwarn can't run qemu-kvm, skipping
 +dwarn can't run QEMU, skipping
  fi
  return 0
  }
 diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh
 index 6303258..41e02e2 100755
 --- a/test/TEST-03-JOBS/test.sh
 +++ b/test/TEST-03-JOBS/test.sh
 @@ -5,9 +5,6 @@ TEST_DESCRIPTION=Job-related tests

  . $TEST_BASE_DIR/test-functions

 -# Uncomment this to debug failures
 -#DEBUGFAIL=systemd.unit=multi-user.target
 -
  check_result_qemu() {
  ret=1
  mkdir -p $TESTDIR/root
 @@ -23,11 +20,10 @@ check_result_qemu() {
  }

  test_run() {
 -if check_qemu ; then
 -run_qemu
 +if run_qemu; then
  check_result_qemu || return 1
  else
 -dwarn can't run qemu-kvm, skipping
 +dwarn can't run QEMU, skipping
  fi
  if check_nspawn; then
  run_nspawn
 diff --git a/test/test-functions b/test/test-functions
 index a184ed7..87d3a73 100644
 --- a/test/test-functions
 +++ b/test/test-functions
 @@ -10,12 +10,63 @@ KERNEL_MODS=/lib/modules/$KERNEL_VER/
  BASICTOOLS=sh bash 

Re: [systemd-devel] [PATCH 4/4] core: lazy distribute for Distribute pools

2013-12-08 Thread Shawn Landden
On Sun, Dec 8, 2013 at 7:50 PM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Mon, Nov 18, 2013 at 12:36:52AM +0100, Zbigniew Jędrzejewski-Szmek wrote:
 On Sun, Nov 17, 2013 at 02:57:56PM -0800, Shawn Landden wrote:
  On Sun, Nov 17, 2013 at 2:28 PM, Zbigniew Jędrzejewski-Szmek
  zbys...@in.waw.pl wrote:
   On Sun, Nov 17, 2013 at 08:46:46PM +0100, Lennart Poettering wrote:
   On Sat, 16.11.13 13:18, Shawn Landden (sh...@churchofgit.com) wrote:
 So, what's the status here? Are you sending a new series, or is this one
 supposed to be merged?
This one doesn't work. I have have a somewhat-working next patch, but
the way epoll_wait works it actually isn't
lazy at all, and would require EPOLLET to even do
one-spawn-per-connection (global connection), but we can't
do that with the current event loop. I ended up getting side-tracked
into adding mount-namespace to
lsof, cause i noticed that feature lacking while working on this

Anyways, a new series will come, and I am working on it.

 Zbyszek



-- 

---
Shawn Landden
+1 360 389 3001 (SMS preferred)
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] update README to not suggest that systemd works without procfs

2013-12-09 Thread Shawn Landden
---
 README | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/README b/README
index cc43953..f2a86c5 100644
--- a/README
+++ b/README
@@ -45,6 +45,7 @@ REQUIREMENTS:
   CONFIG_EPOLL
   CONFIG_NET
   CONFIG_SYSFS
+  CONFIG_PROC_FS
 
 Linux kernel = 3.8 for Smack support
 
@@ -75,9 +76,7 @@ REQUIREMENTS:
   CONFIG_TMPFS_XATTR
   CONFIG_SECCOMP
 
-For systemd-bootchart, a kernel with procfs support and
-several proc output options enabled is required:
-  CONFIG_PROC_FS
+For systemd-bootchar, several proc debug interfaces are required:
   CONFIG_SCHEDSTATS
   CONFIG_SCHED_DEBUG
 
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 2/2] epoll and signalfd has been moved into sd event loop

2013-12-09 Thread Shawn Landden
---
 src/core/manager.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/core/manager.c b/src/core/manager.c
index f06df54..56c10cf 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -22,9 +22,7 @@
 #include assert.h
 #include errno.h
 #include string.h
-#include sys/epoll.h
 #include signal.h
-#include sys/signalfd.h
 #include sys/wait.h
 #include unistd.h
 #include sys/poll.h
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 1/2] core: support Distribute=n to distribute to n workers

2013-12-09 Thread Shawn Landden
Until there are some use cases for Distribute= w/o
SO_REUSEPORT make it imply that. Otherwise we need
a new config_parse_distribute in load-fragment.c
and gain the same issues of config_parse_syscall,
where NoNewPrivs can be still set to false,
but only if set _after_ SystemCallFilter (only allowed
when root).

Because it takes a while for the service to start up, and
until then we spin in a fast epoll loop, this tends to
start up all the instances all at once. There are a number
of ways we can slow this instanciation down:
 1) Call accept() and pass an additional fd to the service
 2) Use EPOLLET: requires event to be prioritized and always
  dispatched.
 3) Disable and then reenable the event source every time we
 enqueue an instance.

IMHO #1 is not acceptable. For #2, perhaps the new event loop
infrastructure can support a special class for EPOLLET. I
am going to investigate #3 right after sending this patch.
---
 TODO  |  3 +-
 man/systemd.socket.xml| 11 ++
 src/core/dbus-socket.c|  2 +-
 src/core/load-fragment-gperf.gperf.m4 |  1 +
 src/core/socket.c | 64 +++
 src/core/socket.h |  3 ++
 6 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/TODO b/TODO
index 8f9aabc..15233cd 100644
--- a/TODO
+++ b/TODO
@@ -69,7 +69,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
+* 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()
 
@@ -187,7 +187,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..48a4b77 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -519,6 +519,17 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn up to
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+Useful with 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 74217df..68c95a0 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -40,7 +40,6 @@ static int property_get_listen(
 void *userdata,
 sd_bus_error *error) {
 
-
 Socket *s = SOCKET(userdata);
 SocketPort *p;
 int r;
@@ -116,6 +115,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
 SD_BUS_PROPERTY(MessageQueueMessageSize, x, bus_property_get_long, 
offsetof(Socket, mq_msgsize), 0),
 SD_BUS_PROPERTY(Result, s, property_get_result, offsetof(Socket, 
result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
 SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_bool, 
offsetof(Socket, reuse_port), 0),
+SD_BUS_PROPERTY(Distribute, u,  bus_property_get_unsigned, 
offsetof(Socket, distribute), 0),
 SD_BUS_PROPERTY(SmackLabel, s, NULL, offsetof(Socket, smack), 0),
 SD_BUS_PROPERTY(SmackLabelIPIn, s, NULL, offsetof(Socket, 
smack_ip_in), 0),
 SD_BUS_PROPERTY(SmackLabelIPOut, s, NULL, offsetof(Socket, 
smack_ip_out), 0),
diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4
index a5033b2..de82586 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -213,6 +213,7 @@ Socket.PassCredentials,  config_parse_bool, 
 0,
 Socket.PassSecurity, config_parse_bool,  0,
 offsetof(Socket, pass_sec)
 Socket.TCPCongestion,

[systemd-devel] [PATCH] core/manager: remove infinite loop

2013-12-10 Thread Shawn Landden
---
 src/core/manager.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/core/manager.c b/src/core/manager.c
index f06df54..c25343f 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2211,10 +2211,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) 
{
 }
 
 finish:
-if (ferror(f)) {
+if (ferror(f))
 r = -EIO;
-goto finish;
-}
 
 assert(m-n_reloading  0);
 m-n_reloading --;
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


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

2013-12-10 Thread Shawn Landden
Because it takes a while for the service to start up, and
until then we spin in a fast epoll loop, this tends to
start up all the instances all at once. There are a number
of ways we can slow this instanciation down:
 1) Call accept() and pass an additional fd to the service
 2) Use EPOLLET: requires event to be prioritized and always
  dispatched.
 3) Disable and then reenable the event source every time we
 enqueue an instance.

With Type=notify, we wait until a service tells us it is ready
before we listen again and thereby start up more instances.

What if someone want to use the templating namespace ('@')
with Distribute=?
---
 TODO  |  3 +-
 man/systemd.socket.xml| 15 +++-
 src/core/dbus-socket.c|  2 +-
 src/core/load-fragment-gperf.gperf.m4 |  3 +-
 src/core/service.c|  4 ++
 src/core/socket.c | 72 ---
 src/core/socket.h |  8 +++-
 7 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/TODO b/TODO
index 2fb9cd3..697d568 100644
--- a/TODO
+++ b/TODO
@@ -69,7 +69,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
+* 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()
 
@@ -187,7 +187,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..6799020 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -404,7 +404,8 @@
 designed for usage with
 
citerefentryrefentrytitleinetd/refentrytitlemanvolnum8/manvolnum/citerefentry
 to work unmodified with systemd socket
-activation./para/listitem
+activation. Incompatible with
+
varnameDistribute=/varname/para/listitem
 /varlistentry
 
 varlistentry
@@ -519,6 +520,18 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn up to
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+Useful with varnameReusePort=/varname 
above.
+Incompatible with 
varnameAccept=true/varname./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 74217df..68c95a0 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -40,7 +40,6 @@ static int property_get_listen(
 void *userdata,
 sd_bus_error *error) {
 
-
 Socket *s = SOCKET(userdata);
 SocketPort *p;
 int r;
@@ -116,6 +115,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
 SD_BUS_PROPERTY(MessageQueueMessageSize, x, bus_property_get_long, 
offsetof(Socket, mq_msgsize), 0),
 SD_BUS_PROPERTY(Result, s, property_get_result, offsetof(Socket, 
result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
 SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_bool, 
offsetof(Socket, reuse_port), 0),
+SD_BUS_PROPERTY(Distribute, u,  bus_property_get_unsigned, 
offsetof(Socket, distribute), 0),
 SD_BUS_PROPERTY(SmackLabel, s, NULL, offsetof(Socket, smack), 0),
 SD_BUS_PROPERTY(SmackLabelIPIn, s, NULL, offsetof(Socket, 
smack_ip_in), 0),
 SD_BUS_PROPERTY(SmackLabelIPOut, s, NULL, offsetof(Socket, 
smack_ip_out), 0),
diff --git a/src/core/load-fragment-gperf.gperf.m4 
b/src/core/load-fragment-gperf.gperf.m4

[systemd-devel] [PATCH] timedatectl: work with old timedated

2013-12-11 Thread Shawn Landden
Which does have TimeUSec. Should we specifically check for this method
instead of assuming time=0 means it doesn't exist?

Before:
shawn@debian-T61:~/git/systemd$ ./timedatectl
  Local time: Wed 1969-12-31 16:00:00 PST
  Universal time: Thu 1970-01-01 00:00:00 UTC
RTC time: n/a
Timezone: America/Los_Angeles (PST, -0800)
 NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
  DST active: no
 Last DST change: DST ended at
  Sun 1969-10-26 01:59:59 PDT
  Sun 1969-10-26 01:00:00 PST
 Next DST change: DST begins (the clock jumps one hour forward) at
  Sun 1970-04-26 01:59:59 PST
  Sun 1970-04-26 03:00:00 PDT

After:
shawn@debian-T61:~/git/systemd$ ./timedatectl
  Local time: Wed 2013-12-11 14:03:21 PST
  Universal time: Wed 2013-12-11 22:03:21 UTC
RTC time: n/a
Timezone: America/Los_Angeles (PST, -0800)
 NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
  DST active: no
 Last DST change: DST ended at
  Sun 2013-11-03 01:59:59 PDT
  Sun 2013-11-03 01:00:00 PST
 Next DST change: DST begins (the clock jumps one hour forward) at
  Sun 2014-03-09 01:59:59 PST
  Sun 2014-03-09 03:00:00 PDT
---
 src/timedate/timedatectl.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 9b81513..7dba8e9 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -106,14 +106,19 @@ static void print_status_info(const StatusInfo *i) {
 
 assert(i);
 
+if (i-time)
+sec = (time_t) (i-time / USEC_PER_SEC);
+else if (arg_transport == BUS_TRANSPORT_LOCAL)
+sec = time(NULL);
+else
+return (void)fprintf(stderr, Could not get time from 
timedated and not operating locally.\n\n);
+
 /* Enforce the values of /etc/localtime */
 if (getenv(TZ)) {
 fprintf(stderr, Warning: ignoring the TZ variable, reading 
the system's timezone setting only.\n\n);
 unsetenv(TZ);
 }
 
-sec = (time_t) (i-time / USEC_PER_SEC);
-
 zero(tm);
 assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S %Z, 
localtime_r(sec, tm))  0);
 char_array_0(a);
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] test-fileio: replace mktemp with mkstemp to avoid warnings

2013-12-11 Thread Shawn Landden
Thank you for this!

On Wed, Dec 11, 2013 at 5:55 PM, Thomas H.P. Andersen pho...@gmail.com wrote:
 On Thu, Dec 12, 2013 at 1:41 AM, Zbigniew Jędrzejewski-Szmek
 zbys...@in.waw.pl wrote:
 On Thu, Dec 12, 2013 at 12:32:43AM +0100, Thomas H.P. Andersen wrote:
 From: Thomas Hindoe Paaboel Andersen pho...@gmail.com

 This is a fairly useless thing to do but it makes the compilers
 and analyzers shut up about the use of mktemp.
 Please apply it. Spurious warnings are very annoying.
 Applied. Thanks.
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [HACK/RFC/PATCH] systemd-su: su on steroids

2013-12-11 Thread Shawn Landden
On Tue, Dec 10, 2013 at 3:18 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Mon, 02.12.13 21:47, David Herrmann (dh.herrm...@gmail.com) wrote:


 4h later, I present systemd-su:

 If you want to give it a try, run:
   systemd-su -u david /bin/sh

 It requires the systemd-suexec helper internally, so if you didn't install
 it, use something like this:
   SYSTEMD_SUEXEC=/home/david/dev/systemd/systemd-suexec ./systemd-su -u 
 david sh
 Otherwise, systemd-su cannot find the systemd-suexec binary.

 Hmm, if we allow that su - tells logind to create an entirely new
 session even when called from an existing one, do we still need
 systemd-su? That should be pretty close, no? That sounds easier to
 do...

 Additionally, I create an anonymous AF_UNIX socket in systemd-su which
 systemd-suexec connects to. I then pass file-descriptors to systemd-suexec
 which installes them as STDIN/OUT/ERR.
 I actually think it would be quite useful to extend the
 StartTransientUnit() dbus call to allow passing FDs. It would allow us to
 store FDs with active units, which would be useful for a lot of other
 concepts (like storing DRM framebuffer handles..).

 Hmm, so we thought about adding support for something like a per-service
 fd storage facility in systemd. This would be populated from the .socket
 units, but could also be passed in for transient units by the caller or
 even updated by the services themselves if they want to store additional
 fds in systemd. This would solve a number of issues for us, including
 one big one: currently if you restart systemd-journald you lose the
 per-service stdout/stderr connections because there's no way to save
 them.
We need to do this in order to integrate criu into systemd as well.

 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] timedatectl: work with old timedated

2013-12-12 Thread Shawn Landden
Which does have TimeUSec. Should we specifically check for this method
instead of assuming time=0 means it doesn't exist?

Before:
shawn@debian-T61:~/git/systemd$ ./timedatectl
  Local time: Wed 1969-12-31 16:00:00 PST
  Universal time: Thu 1970-01-01 00:00:00 UTC
RTC time: n/a
Timezone: America/Los_Angeles (PST, -0800)
 NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
  DST active: no
 Last DST change: DST ended at
  Sun 1969-10-26 01:59:59 PDT
  Sun 1969-10-26 01:00:00 PST
 Next DST change: DST begins (the clock jumps one hour forward) at
  Sun 1970-04-26 01:59:59 PST
  Sun 1970-04-26 03:00:00 PDT

After:
shawn@debian-T61:~/git/systemd$ ./timedatectl
  Local time: Wed 2013-12-11 14:03:21 PST
  Universal time: Wed 2013-12-11 22:03:21 UTC
RTC time: n/a
Timezone: America/Los_Angeles (PST, -0800)
 NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
  DST active: no
 Last DST change: DST ended at
  Sun 2013-11-03 01:59:59 PDT
  Sun 2013-11-03 01:00:00 PST
 Next DST change: DST begins (the clock jumps one hour forward) at
  Sun 2014-03-09 01:59:59 PST
  Sun 2014-03-09 03:00:00 PDT
---
 src/timedate/timedatectl.c | 43 ++-
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 9b81513..6b09559 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -98,6 +98,7 @@ static void print_status_info(const StatusInfo *i) {
 char s[32];
 struct tm tm;
 time_t sec;
+bool have_time = false;
 char *zc, *zn;
 time_t t, tc, tn;
 int dn;
@@ -109,20 +110,35 @@ static void print_status_info(const StatusInfo *i) {
 /* Enforce the values of /etc/localtime */
 if (getenv(TZ)) {
 fprintf(stderr, Warning: ignoring the TZ variable, reading 
the system's timezone setting only.\n\n);
+fflush(stderr);
 unsetenv(TZ);
 }
 
-sec = (time_t) (i-time / USEC_PER_SEC);
+if (i-time != 0) {
+sec = (time_t) (i-time / USEC_PER_SEC);
+have_time = true;
+} else if (arg_transport == BUS_TRANSPORT_LOCAL) {
+sec = time(NULL);
+have_time = true;
+} else {
+fprintf(stderr, Warning: could not get time from timedated 
and not operating locally.\n\n);
+fflush(stderr);
+}
 
-zero(tm);
-assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S %Z, 
localtime_r(sec, tm))  0);
-char_array_0(a);
-printf(  Local time: %s\n, a);
+if (have_time) {
+zero(tm);
+assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S %Z, 
localtime_r(sec, tm))  0);
+char_array_0(a);
+printf(  Local time: %s\n, a);
 
-zero(tm);
-assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S UTC, 
gmtime_r(sec, tm))  0);
-char_array_0(a);
-printf(  Universal time: %s\n, a);
+zero(tm);
+assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S UTC, 
gmtime_r(sec, tm))  0);
+char_array_0(a);
+printf(  Universal time: %s\n, a);
+} else {
+printf(  Local time: %s\n, n/a);
+printf(  Universal time: %s\n, n/a);
+}
 
 if (i-rtc_time  0) {
 time_t rtc_sec;
@@ -133,7 +149,7 @@ static void print_status_info(const StatusInfo *i) {
 char_array_0(a);
 printf(RTC time: %s\n, a);
 } else
-printf(RTC time: n/a\n);
+printf(RTC time: %s\n, n/a);
 
 zero(tm);
 assert_se(strftime(a, sizeof(a), %Z, %z, localtime_r(sec, tm))  
0);
@@ -151,8 +167,8 @@ static void print_status_info(const StatusInfo *i) {
  tc, zc, is_dstc,
  tn, dn, zn, is_dstn);
 if (r  0)
-printf(  DST active: n/a\n);
-else {
+printf(  DST active: %s\n, n/a);
+else if (have_time) {
 printf(  DST active: %s\n, yes_no(is_dstc));
 
 t = tc - 1;
@@ -183,7 +199,8 @@ static void print_status_info(const StatusInfo *i) {
 
 free(zc);
 free(zn);
-}
+} else
+printf(  DST active: %s\n, yes_no(is_dstc));
 
 if (i-rtc_local)
 fputs(\n ANSI_HIGHLIGHT_ON
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] timedatectl: work with old timedated

2013-12-12 Thread Shawn Landden
On Thu, Dec 12, 2013 at 11:02 AM, Lennart Poettering
lenn...@poettering.net wrote:
 On Thu, 12.12.13 10:00, Shawn Landden (sh...@churchofgit.com) wrote:


 Applied. Dropped the fflush(stderr) bits though as we that's not
 necessary for stderr, and not even for stdout if an \n was printed
 anyway...
ok, I was worried about the lack of synchronization between stderr and
stdout causing them to interlace.

 Thanks!


 diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
 index 9b81513..6b09559 100644
 --- a/src/timedate/timedatectl.c
 +++ b/src/timedate/timedatectl.c
 @@ -98,6 +98,7 @@ static void print_status_info(const StatusInfo *i) {
  char s[32];
  struct tm tm;
  time_t sec;
 +bool have_time = false;
  char *zc, *zn;
  time_t t, tc, tn;
  int dn;
 @@ -109,20 +110,35 @@ static void print_status_info(const StatusInfo *i) {
  /* Enforce the values of /etc/localtime */
  if (getenv(TZ)) {
  fprintf(stderr, Warning: ignoring the TZ variable, reading 
 the system's timezone setting only.\n\n);
 +fflush(stderr);
  unsetenv(TZ);
  }

 -sec = (time_t) (i-time / USEC_PER_SEC);
 +if (i-time != 0) {
 +sec = (time_t) (i-time / USEC_PER_SEC);
 +have_time = true;
 +} else if (arg_transport == BUS_TRANSPORT_LOCAL) {
 +sec = time(NULL);
 +have_time = true;
 +} else {
 +fprintf(stderr, Warning: could not get time from timedated 
 and not operating locally.\n\n);
 +fflush(stderr);
 +}

 -zero(tm);
 -assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S %Z, 
 localtime_r(sec, tm))  0);
 -char_array_0(a);
 -printf(  Local time: %s\n, a);
 +if (have_time) {
 +zero(tm);
 +assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S %Z, 
 localtime_r(sec, tm))  0);
 +char_array_0(a);
 +printf(  Local time: %s\n, a);

 -zero(tm);
 -assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S UTC, 
 gmtime_r(sec, tm))  0);
 -char_array_0(a);
 -printf(  Universal time: %s\n, a);
 +zero(tm);
 +assert_se(strftime(a, sizeof(a), %a %Y-%m-%d %H:%M:%S 
 UTC, gmtime_r(sec, tm))  0);
 +char_array_0(a);
 +printf(  Universal time: %s\n, a);
 +} else {
 +printf(  Local time: %s\n, n/a);
 +printf(  Universal time: %s\n, n/a);
 +}

  if (i-rtc_time  0) {
  time_t rtc_sec;
 @@ -133,7 +149,7 @@ static void print_status_info(const StatusInfo *i) {
  char_array_0(a);
  printf(RTC time: %s\n, a);
  } else
 -printf(RTC time: n/a\n);
 +printf(RTC time: %s\n, n/a);

  zero(tm);
  assert_se(strftime(a, sizeof(a), %Z, %z, localtime_r(sec, tm)) 
  0);
 @@ -151,8 +167,8 @@ static void print_status_info(const StatusInfo *i) {
   tc, zc, is_dstc,
   tn, dn, zn, is_dstn);
  if (r  0)
 -printf(  DST active: n/a\n);
 -else {
 +printf(  DST active: %s\n, n/a);
 +else if (have_time) {
  printf(  DST active: %s\n, yes_no(is_dstc));

  t = tc - 1;
 @@ -183,7 +199,8 @@ static void print_status_info(const StatusInfo *i) {

  free(zc);
  free(zn);
 -}
 +} else
 +printf(  DST active: %s\n, yes_no(is_dstc));

  if (i-rtc_local)
  fputs(\n ANSI_HIGHLIGHT_ON


 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


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

2013-12-12 Thread Shawn Landden
If Distribute=n, turns SO_REUSEPORT on, and spawns
n workers to handling incoming requests.

SO_REUSEPORT sockets on the same port must all be created
by the same uid, therefore using the option allows
other root programs (or programs of the same user
if running in --user mode) to hijack this port, even
after systemd reserves it.

This patch is currently not ready for merging because it is
possible to do quite a number of operations, and yet have no assurance
that we have accomplished anything, ending up in an
infinite loop respawning a service that never accept()s
the socket passed to it, and therefore leaving our copy
of the socket always in EPOLLIN status. To prevent this we need
to do one of:

 *) Call accept() and pass an additional fd to the service.
 *) Use EPOLLET: requires event to always dispatched when it comes in.
 *) Disable and then reenable the event source (requiring
 that we re-create the socket) every time we
 enqueue an instance, essentially emulating the behavior
 of EPOLLET.
---
 TODO  |  3 +-
 man/systemd.socket.xml| 15 ++-
 src/core/dbus-socket.c|  4 +-
 src/core/load-fragment-gperf.gperf.m4 |  3 +-
 src/core/socket.c | 76 ---
 src/core/socket.h |  5 ++-
 src/shared/conf-parser.c  | 32 +++
 src/shared/conf-parser.h  |  1 +
 8 files changed, 109 insertions(+), 30 deletions(-)

diff --git a/TODO b/TODO
index dad55c4..fbc2609 100644
--- a/TODO
+++ b/TODO
@@ -73,7 +73,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
+* tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
 
 * move config_parse_path_strv() out of conf-parser.c
 
@@ -187,7 +187,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..6799020 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -404,7 +404,8 @@
 designed for usage with
 
citerefentryrefentrytitleinetd/refentrytitlemanvolnum8/manvolnum/citerefentry
 to work unmodified with systemd socket
-activation./para/listitem
+activation. Incompatible with
+
varnameDistribute=/varname/para/listitem
 /varlistentry
 
 varlistentry
@@ -519,6 +520,18 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn up to
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+Useful with varnameReusePort=/varname 
above.
+Incompatible with 
varnameAccept=true/varname./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 74217df..036c9af 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -40,7 +40,6 @@ static int property_get_listen(
 void *userdata,
 sd_bus_error *error) {
 
-
 Socket *s = SOCKET(userdata);
 SocketPort *p;
 int r;
@@ -115,7 +114,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
 SD_BUS_PROPERTY(MessageQueueMaxMessages, x, bus_property_get_long, 
offsetof(Socket, mq_maxmsg), 0),
 SD_BUS_PROPERTY(MessageQueueMessageSize, x, bus_property_get_long, 
offsetof(Socket, mq_msgsize), 0),
 SD_BUS_PROPERTY(Result, s, property_get_result, offsetof(Socket, 
result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-SD_BUS_PROPERTY(ReusePort, b,  

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

2013-12-13 Thread Shawn Landden
Forgot to send my notes on the last review

On Fri, Dec 13, 2013 at 7:12 AM, Lennart Poettering
lenn...@poettering.net wrote:
 On Thu, 12.12.13 23:46, Shawn Landden (sh...@churchofgit.com) wrote:

 -Socket.ReusePort,config_parse_bool,  0, 
 offsetof(Socket, reuse_port)
 +Socket.ReusePort,config_parse_tristate, -1, 
 offsetof(Socket, reuse_port)
   ^

 Why -1 there? That should be there... The parse call doesn't make use of
 that, so it should be 0, really.
fixed, and i see your point, but i still don't know where the default
of -1 comes from...


 +if (s-reuse_port  0) {
 +if (s-distribute  0)
 +s-reuse_port = true;
 +else
 +s-reuse_port = false;
 +}
 +


 Nitpicking: I'd just write it like this:

 if (s-reuse_port  0)
 s-reuse_port = s-distribute  0;
thats better


 -if (s-n_connections = s-max_connections) {
 +if (s-n_connections = s-max_connections  
 !(s-distribute)) {

 Still too many ()
damn


 -if (se-state == SERVICE_RUNNING)
 -socket_set_state(s, SOCKET_RUNNING);
 +if (se-state == SERVICE_RUNNING) {
 +if (s-n_connections  s-distribute)
 +;
 +else
 +socket_set_state(s, SOCKET_RUNNING);
 +}

 Hmm, too simple, no? We wanted that logic, that we enter
 SOCKET_RUNNING as long as at least one service is still starting up or
 when we reached the limit. I only see the check for the latter here...
So before I checked for Type=notify in socket_enter_running and then
only spawned one service,
so that I could go back to SOCKET_LISTENING here, but without that
logic, I don't see
a need for any special logic here. Since we only get these
notifications for Type=notify,
we can't just unilaterally go to


 Still missing the bit where the socket is duplicated for propery
 SO_REUSEPORT usgae...
OK, so this is the way lwn covered it, but using fork() to replicate
the socket works just fine,
as the attached program demonstrates (also shows lazy reverse
exponential startup), and I
see nothing in the original reuseport patches that indicate that this
is a bad idea.

I'd do this if it was simple (because it gives the EPOLLET behavior I
am looking for), but
it requires some new fields in SocketPort to handle the CLOEXEC
switcharoos, as we will
have two of the same socket open at the same time, one spawned before
the connection came in
to give to the child, and another spawned right after the connection
came in, to hold onto for the
next connection. I'd really like to avoid that since SO_REUSEPORT does
not need it.


 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
ELF€	@@ @8@@@@@@ÀÀ@@@@ÔÔ ØØ`Ø`ÀÈ ðð`ð`àà@@DDPåtdÌÌ@Ì@44Qåtd/lib64/ld-linux-x86-64.so.2GNU GNUžXÂØd’ú÷0íšB’˜ža!^†

	P˜6=De[†ž /Ky€k*libc.so.6setuidsockethtonsepoll_waitforklistengetpidprintfmemsetbindsetsockoptepoll_ctlcloseepoll_create1acceptsleep__libc_start_mainwrite__gmon_start__GLIBC_2.9GLIBC_2.3.2GLIBC_2.2.5ii
­ri	·ui	ÃÐ`
ð`ø````` `(`0`	8`
@`H

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

2013-12-13 Thread Shawn Landden
If Distribute=n, turns SO_REUSEPORT on, and spawns
n workers to handling incoming requests.

SO_REUSEPORT sockets on the same port must all be created
by the same uid, therefore using the option allows
other root programs (or programs of the same user
if running in --user mode) to hijack this port, even
after systemd reserves it.

This patch is currently not ready for merging because if
the service never accept()s
the socket passed to it, we stay in EPOLLIN, looping
infinitely. To prevent this we need to do one of:

 *) Call accept() and pass an additional fd to the service.
 *) Use EPOLLET: requires event to always dispatched when it comes in.
 *) Disable and then reenable the event source (requiring
 that we re-create the socket) every time we
 enqueue an instance, essentially emulating the behavior
 of EPOLLET.
---
 TODO  |  3 +-
 man/systemd.socket.xml| 15 +++-
 src/core/dbus-socket.c|  4 +-
 src/core/load-fragment-gperf.gperf.m4 |  3 +-
 src/core/service.c|  4 +-
 src/core/socket.c | 70 +--
 src/core/socket.h |  5 ++-
 src/shared/conf-parser.c  | 32 
 src/shared/conf-parser.h  |  1 +
 9 files changed, 108 insertions(+), 29 deletions(-)

diff --git a/TODO b/TODO
index dad55c4..fbc2609 100644
--- a/TODO
+++ b/TODO
@@ -73,7 +73,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
+* tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
 
 * move config_parse_path_strv() out of conf-parser.c
 
@@ -187,7 +187,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..6799020 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -404,7 +404,8 @@
 designed for usage with
 
citerefentryrefentrytitleinetd/refentrytitlemanvolnum8/manvolnum/citerefentry
 to work unmodified with systemd socket
-activation./para/listitem
+activation. Incompatible with
+
varnameDistribute=/varname/para/listitem
 /varlistentry
 
 varlistentry
@@ -519,6 +520,18 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn up to
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+Useful with varnameReusePort=/varname 
above.
+Incompatible with 
varnameAccept=true/varname./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 74217df..036c9af 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -40,7 +40,6 @@ static int property_get_listen(
 void *userdata,
 sd_bus_error *error) {
 
-
 Socket *s = SOCKET(userdata);
 SocketPort *p;
 int r;
@@ -115,7 +114,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
 SD_BUS_PROPERTY(MessageQueueMaxMessages, x, bus_property_get_long, 
offsetof(Socket, mq_maxmsg), 0),
 SD_BUS_PROPERTY(MessageQueueMessageSize, x, bus_property_get_long, 
offsetof(Socket, mq_msgsize), 0),
 SD_BUS_PROPERTY(Result, s, property_get_result, offsetof(Socket, 
result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_bool, 
offsetof(Socket, reuse_port), 0),
+SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_tristate, 
offsetof(Socket, 

[systemd-devel] [PATCH] sd-event: we do not support EPOLLONESHOT correctly

2013-12-13 Thread Shawn Landden
If this event is not the highest priority, then it will not
be dispatched when the epoll triggers, and since we will
not get any more wakeups (due to the way EPOLLONESHOT works)
will never be dispatched.

Since we only handle one event per epoll_wait() wakeup,
and we dequeue a ONE_SHOT event when we dispatch it, we
do not have the problem described in epoll(7) of
multiple events can be generated upon receipt of multiple
chunks of data.
---
 src/libsystemd-bus/sd-event.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index 462dd41..1cf661e 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -447,9 +447,6 @@ static int source_io_register(
 ev.events = events;
 ev.data.ptr = s;
 
-if (enabled == SD_EVENT_ONESHOT)
-ev.events |= EPOLLONESHOT;
-
 if (s-io.registered)
 r = epoll_ctl(s-event-epoll_fd, EPOLL_CTL_MOD, s-io.fd, 
ev);
 else
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH 1/2] nspawn: --populate to run static binaries on empty target directory

2013-12-13 Thread Shawn Landden
On Tue, Dec 10, 2013 at 2:18 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Mon, 02.12.13 09:41, Shawn Landden (sh...@churchofgit.com) wrote:


 On Mon, Dec 2, 2013 at 8:27 AM, Lennart Poettering
 lenn...@poettering.net wrote:
  On Sat, 30.11.13 10:20, Shawn Landden (sh...@churchofgit.com) wrote:
 
  nspawn has been called chroot on steroids.
 
  Continue that tradition by supporting target directories that
  are not root directories.
 
  This patch handles the simple case: a static binary.
 
  Hmm, I am not sure how I feel about this. This appears a bit too
  specific for me, and given the requirement for static binaries this is
  also so limited.
 The next patch is the series adds support for dynamic libraries. This patch
 also doesn't need bind mounts, and it executes through /proc/self/fd/%n, but
 support for one-file scripts and dynamic libraries in the next patch does
 require bind mounts. I feel you don't really understand my patch. :/
 I'll sum up what I'm doing:

 If --populate is passed, analyze the executable, which opens it and set the
 exec path to /proc/self/fd/%n. If executable is static this is all you
 have to do.

 If it has a shebang, analyze that. If either the shebang or executable
 is dynamic,
 test if the linker is the GNU linker, and if it is have the linker
 tell use what libraries the
 executable needs. Then bind mount the linker, shebang (if there is one), and
 libraries into the target.

 But somethinglike this will never fully work,
Agreed.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] sd-event: we do not support EPOLLONESHOT correctly

2013-12-13 Thread Shawn Landden
On Fri, Dec 13, 2013 at 7:17 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Fri, 13.12.13 13:08, Shawn Landden (sh...@churchofgit.com) wrote:

 If this event is not the highest priority, then it will not be
 dispatched when the epoll triggers, and since we will not get any more
 wakeups (due to the way EPOLLONESHOT works) will never be dispatched.

 Hmm, so the way this is supposed to work is that as soon as epoll told
 us about some event once, we will set the event source to pending, and
 it stays pending until we have dispatched it, regardless if we ever
 get the event from epoll again or not. However, we currently will
 overwrite the revents field should we ever get it again with the new
 one. It probably makes more sense to OR it in, so that we don't forget
 readability if writability happens at a later point or vice versa, if
 you follow what I mean. I'll prep a fix for that.
good

 With that fixed is there something else to still fix?
Oh I missed how the pending code worked. Because of that I think I can
use EPOLLET
with sd-event, and will send a Distribute= patch that uses it. (already have it,
just wasn't sure if it was only working cause my test setup has near-0 load)

 Since we only handle one event per epoll_wait() wakeup,
 and we dequeue a ONE_SHOT event when we dispatch it, we
 do not have the problem described in epoll(7) of
 multiple events can be generated upon receipt of multiple
 chunks of data.

 Not sure I follow here? That part appears to be about EPOLLET?
That part explains why EPOLLET cannot be used to implement EPOLLONESHOT.
The reason is that even with EPOLLET, epoll_wait can generate multiple
events for the
same watch, if more than one connection came in.

 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


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

2013-12-13 Thread Shawn Landden
If Distribute=n, turns SO_REUSEPORT on, and spawns
n workers to handling incoming requests.

SO_REUSEPORT sockets on the same port must all be created
by the same uid, therefore using the option allows
other root programs (or programs of the same user
if running in --user mode) to hijack this port, even
after systemd reserves it.

We spawn workers at a rate approximentally reverse
exponentially proportianal to the number of incoming connections.
Faster based on the time for new workers to start accept()ing
and their load, or slower if systemd is under load.
---
 TODO  |  3 +-
 man/systemd.socket.xml| 15 +++-
 src/core/dbus-socket.c|  4 +--
 src/core/load-fragment-gperf.gperf.m4 |  3 +-
 src/core/service.c|  4 +--
 src/core/socket.c | 68 ++-
 src/core/socket.h |  5 ++-
 src/shared/conf-parser.c  | 32 +
 src/shared/conf-parser.h  |  1 +
 9 files changed, 101 insertions(+), 34 deletions(-)

diff --git a/TODO b/TODO
index 0b43888..2abe1b4 100644
--- a/TODO
+++ b/TODO
@@ -73,7 +73,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
+* tmpfiles: when applying ownership to /run/log/journal, also do this for the 
journal fails contained in it
 
 * move config_parse_path_strv() out of conf-parser.c
 
@@ -181,7 +181,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..6799020 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -404,7 +404,8 @@
 designed for usage with
 
citerefentryrefentrytitleinetd/refentrytitlemanvolnum8/manvolnum/citerefentry
 to work unmodified with systemd socket
-activation./para/listitem
+activation. Incompatible with
+
varnameDistribute=/varname/para/listitem
 /varlistentry
 
 varlistentry
@@ -519,6 +520,18 @@
 /varlistentry
 
 varlistentry
+termvarnameDistribute=/varname/term
+listitemparaTakes an integer
+value. Systemd will spawn up to
+given number of instances of service each
+listening to the same socket. Default is 0.
+Setting this requires corresponding service to
+be an instansiated service (name ends with 
literal@.service/literal).
+Useful with varnameReusePort=/varname 
above.
+Incompatible with 
varnameAccept=true/varname./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 74217df..036c9af 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -40,7 +40,6 @@ static int property_get_listen(
 void *userdata,
 sd_bus_error *error) {
 
-
 Socket *s = SOCKET(userdata);
 SocketPort *p;
 int r;
@@ -115,7 +114,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
 SD_BUS_PROPERTY(MessageQueueMaxMessages, x, bus_property_get_long, 
offsetof(Socket, mq_maxmsg), 0),
 SD_BUS_PROPERTY(MessageQueueMessageSize, x, bus_property_get_long, 
offsetof(Socket, mq_msgsize), 0),
 SD_BUS_PROPERTY(Result, s, property_get_result, offsetof(Socket, 
result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_bool, 
offsetof(Socket, reuse_port), 0),
+SD_BUS_PROPERTY(ReusePort, b,  bus_property_get_tristate, 
offsetof(Socket, reuse_port), 0),
+SD_BUS_PROPERTY(Distribute, u,  bus_property_get_unsigned, 
offsetof(Socket, distribute), 0),
 SD_BUS_PROPERTY(SmackLabel, s, NULL, offsetof(Socket, smack), 0),
 SD_BUS_PROPERTY(SmackLabelIPIn, s, NULL, offsetof(Socket, 
smack_ip_in), 0),
  

Re: [systemd-devel] [PATCH] sd-event: we do not support EPOLLONESHOT correctly

2013-12-13 Thread Shawn Landden
On Fri, Dec 13, 2013 at 8:04 PM, Shawn Landden sh...@churchofgit.com wrote:
 On Fri, Dec 13, 2013 at 7:17 PM, Lennart Poettering
 lenn...@poettering.net wrote:
 On Fri, 13.12.13 13:08, Shawn Landden (sh...@churchofgit.com) wrote:

 If this event is not the highest priority, then it will not be
 dispatched when the epoll triggers, and since we will not get any more
 wakeups (due to the way EPOLLONESHOT works) will never be dispatched.

 Hmm, so the way this is supposed to work is that as soon as epoll told
 us about some event once, we will set the event source to pending, and
 it stays pending until we have dispatched it, regardless if we ever
 get the event from epoll again or not. However, we currently will
 overwrite the revents field should we ever get it again with the new
 one. It probably makes more sense to OR it in, so that we don't forget
 readability if writability happens at a later point or vice versa, if
 you follow what I mean. I'll prep a fix for that.
 good

 With that fixed is there something else to still fix?
 Oh I missed how the pending code worked. Because of that I think I can
 use EPOLLET
 with sd-event, and will send a Distribute= patch that uses it. (already have 
 it,
 just wasn't sure if it was only working cause my test setup has near-0 load)
With either of these, can't we end up in a situation where we have
events pending
but are still blocking on epoll_wait()?

shouldn't we do something like

p = have_pending()

epoll_wait(foo, foo, foo, p ? timeout : 0);

do prioq stuff()
mark_pending()
dispatch_highest_prio()

to avoid this issue?

 Since we only handle one event per epoll_wait() wakeup,
 and we dequeue a ONE_SHOT event when we dispatch it, we
 do not have the problem described in epoll(7) of
 multiple events can be generated upon receipt of multiple
 chunks of data.

 Not sure I follow here? That part appears to be about EPOLLET?
 That part explains why EPOLLET cannot be used to implement EPOLLONESHOT.
 The reason is that even with EPOLLET, epoll_wait can generate multiple
 events for the
 same watch, if more than one connection came in.

 Lennart

 --
 Lennart Poettering, Red Hat
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] build: use -ftrapv for development

2013-12-14 Thread Shawn Landden
We want to find these bugs if they exist.
---
 autogen.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/autogen.sh b/autogen.sh
index d0a2f3f..9ffd724 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -54,10 +54,10 @@ args=$args \
 fi
 
 if [ x$1 = xc ]; then
-./configure CFLAGS='-g -O0' --enable-kdbus $args
+./configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
 make clean
 elif [ x$1 = xg ]; then
-./configure CFLAGS='-g -Og' --enable-kdbus $args
+./configure CFLAGS='-g -Og -ftrapv' --enable-kdbus $args
 make clean
 else
 echo
@@ -65,6 +65,6 @@ else
 echo Initialized build system. For a common configuration please run:
 echo 
 echo
-echo ./configure CFLAGS='-g -O0' --enable-kdbus $args
+echo ./configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
 echo
 fi
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] udev: fix printf specifiers

2013-12-14 Thread Shawn Landden
This keeps the same behavior, which is wierd.
---
 src/udev/udev-builtin-path_id.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index 7476330..7543a11 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -71,9 +71,9 @@ static int format_lun_number(struct udev_device *dev, char 
**path)
 
 /* address method 0, peripheral device addressing with bus id of zero 
*/
 if (lun  256)
-return path_prepend(path, lun-%d, lun);
+return path_prepend(path, lun-%hhu, (unsigned char) lun);
 /* handle all other lun addressing methods by using a variant of the 
original lun format */
-return path_prepend(path, lun-0x%04x%04x, (lun  0x), 
(lun  16)  0x);
+return path_prepend(path, lun-0x%04hx%04hx, (unsigned 
short)(lun  0x), (unsigned short)(lun  16)  0x);
 }
 
 static struct udev_device *skip_subsystem(struct udev_device *dev, const char 
*subsys)
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] udev: fix printf specifiers

2013-12-14 Thread Shawn Landden
On Sat, Dec 14, 2013 at 8:11 PM, Zbigniew Jędrzejewski-Szmek
zbys...@in.waw.pl wrote:
 On Sat, Dec 14, 2013 at 06:48:34PM -0800, Shawn Landden wrote:
 This keeps the same behavior, which is wierd.
 ---
  src/udev/udev-builtin-path_id.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

 diff --git a/src/udev/udev-builtin-path_id.c 
 b/src/udev/udev-builtin-path_id.c
 index 7476330..7543a11 100644
 --- a/src/udev/udev-builtin-path_id.c
 +++ b/src/udev/udev-builtin-path_id.c
 @@ -71,9 +71,9 @@ static int format_lun_number(struct udev_device *dev, char 
 **path)

  /* address method 0, peripheral device addressing with bus id of 
 zero */
  if (lun  256)
 -return path_prepend(path, lun-%d, lun);
 +return path_prepend(path, lun-%hhu, (unsigned char) lun);
  /* handle all other lun addressing methods by using a variant of 
 the original lun format */
 -return path_prepend(path, lun-0x%04x%04x, (lun  0x), 
 (lun  16)  0x);
 +return path_prepend(path, lun-0x%04hx%04hx, (unsigned 
 short)(lun  0x), (unsigned short)(lun  16)  0x);
  }
 Hm, nothing wrong with this approach, but I don't like all those casts.
I just decided to be explicit about what the code was doing because it
is confusing, and AFAICT
without any other justification, probably wrong.

it could have been fixed by simply removing the long above, as the
top comment says that it is only 32-bits wide.
(and the formatting only supports 32-bits too)

if you are going to put the least siginificant bytes first, wouldn't
you want to do so byte-wise, instead
of creating this mixed-endian monster?

 I pushed a simpler change which adds 'l' in appropriate places.

 Zbyszek
 ___
 systemd-devel mailing list
 systemd-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/systemd-devel
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] __thread -- thread_local for C11 compat

2013-12-15 Thread Shawn Landden
also make thread_local available w/o including threads.h
---
 src/libsystemd-bus/sd-bus.c | 4 ++--
 src/libsystemd-bus/sd-event.c   | 2 +-
 src/libsystemd-id128/sd-id128.c | 8 
 src/login/logind-inhibit.c  | 2 +-
 src/shared/capability.c | 4 ++--
 src/shared/cgroup-util.c| 2 +-
 src/shared/macro.h  | 8 
 src/shared/util.c   | 6 +++---
 src/shared/virt.c   | 8 
 9 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 4eaceef..64cd663 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -2815,13 +2815,13 @@ static int bus_default(int (*bus_open)(sd_bus **), 
sd_bus **default_bus, sd_bus
 }
 
 _public_ int sd_bus_default_system(sd_bus **ret) {
-static __thread sd_bus *default_system_bus = NULL;
+static thread_local sd_bus *default_system_bus = NULL;
 
 return bus_default(sd_bus_open_system, default_system_bus, ret);
 }
 
 _public_ int sd_bus_default_user(sd_bus **ret) {
-static __thread sd_bus *default_user_bus = NULL;
+static thread_local sd_bus *default_user_bus = NULL;
 
 return bus_default(sd_bus_open_user, default_user_bus, ret);
 }
diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index 06c84d7..727528b 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -2116,7 +2116,7 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, 
uint64_t *usec) {
 
 _public_ int sd_event_default(sd_event **ret) {
 
-static __thread sd_event *default_event = NULL;
+static thread_local sd_event *default_event = NULL;
 sd_event *e;
 int r;
 
diff --git a/src/libsystemd-id128/sd-id128.c b/src/libsystemd-id128/sd-id128.c
index 07d2415..9ee40ab 100644
--- a/src/libsystemd-id128/sd-id128.c
+++ b/src/libsystemd-id128/sd-id128.c
@@ -104,8 +104,8 @@ static sd_id128_t make_v4_uuid(sd_id128_t id) {
 }
 
 _public_ int sd_id128_get_machine(sd_id128_t *ret) {
-static __thread sd_id128_t saved_machine_id;
-static __thread bool saved_machine_id_valid = false;
+static thread_local sd_id128_t saved_machine_id;
+static thread_local bool saved_machine_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[33];
 ssize_t k;
@@ -153,8 +153,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
 }
 
 _public_ int sd_id128_get_boot(sd_id128_t *ret) {
-static __thread sd_id128_t saved_boot_id;
-static __thread bool saved_boot_id_valid = false;
+static thread_local sd_id128_t saved_boot_id;
+static thread_local bool saved_boot_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[36];
 ssize_t k;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index ec6a722..042586d 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -413,7 +413,7 @@ bool manager_is_inhibited(
 }
 
 const char *inhibit_what_to_string(InhibitWhat w) {
-static __thread char buffer[97];
+static thread_local char buffer[97];
 char *p;
 
 if (w  0 || w = _INHIBIT_WHAT_MAX)
diff --git a/src/shared/capability.c b/src/shared/capability.c
index 3219520..f34f6ba 100644
--- a/src/shared/capability.c
+++ b/src/shared/capability.c
@@ -55,8 +55,8 @@ int have_effective_cap(int value) {
 }
 
 unsigned long cap_last_cap(void) {
-static __thread unsigned long saved;
-static __thread bool valid = false;
+static thread_local unsigned long saved;
+static thread_local bool valid = false;
 unsigned long p;
 
 if (valid)
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 2c2ffc5..309f65d 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -480,7 +480,7 @@ static int join_path(const char *controller, const char 
*path, const char *suffi
 
 int cg_get_path(const char *controller, const char *path, const char *suffix, 
char **fs) {
 const char *p;
-static __thread bool good = false;
+static thread_local bool good = false;
 
 assert(fs);
 
diff --git a/src/shared/macro.h b/src/shared/macro.h
index fd3762e..903e8ee 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -27,6 +27,14 @@
 #include sys/uio.h
 #include inttypes.h
 
+#if __STDC_VERSION__ = 201112L  !defined(__STDC_NO_THREADS__)
+#else
+#  define _Thread_local __thread
+#endif
+
+/* make thread_local available w/o including threads.h */
+#define thread_local _Thread_local
+
 #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
 #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
 #define _sentinel_ __attribute__ ((sentinel))
diff --git a/src/shared/util.c b/src/shared/util.c
index 7c73074..0ce6f70 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -86,7 +86,7 @@ static volatile unsigned 

[systemd-devel] [PATCH] __thread -- thread_local for C11 compat

2013-12-15 Thread Shawn Landden
also make thread_local available w/o including threads.h
---
 src/libsystemd-bus/sd-bus.c |  4 ++--
 src/libsystemd-bus/sd-event.c   |  2 +-
 src/libsystemd-id128/sd-id128.c |  8 
 src/login/logind-inhibit.c  |  2 +-
 src/shared/capability.c |  4 ++--
 src/shared/cgroup-util.c|  2 +-
 src/shared/macro.h  | 10 ++
 src/shared/util.c   |  6 +++---
 src/shared/virt.c   |  8 
 9 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 4eaceef..64cd663 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -2815,13 +2815,13 @@ static int bus_default(int (*bus_open)(sd_bus **), 
sd_bus **default_bus, sd_bus
 }
 
 _public_ int sd_bus_default_system(sd_bus **ret) {
-static __thread sd_bus *default_system_bus = NULL;
+static thread_local sd_bus *default_system_bus = NULL;
 
 return bus_default(sd_bus_open_system, default_system_bus, ret);
 }
 
 _public_ int sd_bus_default_user(sd_bus **ret) {
-static __thread sd_bus *default_user_bus = NULL;
+static thread_local sd_bus *default_user_bus = NULL;
 
 return bus_default(sd_bus_open_user, default_user_bus, ret);
 }
diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index 06c84d7..727528b 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -2116,7 +2116,7 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, 
uint64_t *usec) {
 
 _public_ int sd_event_default(sd_event **ret) {
 
-static __thread sd_event *default_event = NULL;
+static thread_local sd_event *default_event = NULL;
 sd_event *e;
 int r;
 
diff --git a/src/libsystemd-id128/sd-id128.c b/src/libsystemd-id128/sd-id128.c
index 07d2415..9ee40ab 100644
--- a/src/libsystemd-id128/sd-id128.c
+++ b/src/libsystemd-id128/sd-id128.c
@@ -104,8 +104,8 @@ static sd_id128_t make_v4_uuid(sd_id128_t id) {
 }
 
 _public_ int sd_id128_get_machine(sd_id128_t *ret) {
-static __thread sd_id128_t saved_machine_id;
-static __thread bool saved_machine_id_valid = false;
+static thread_local sd_id128_t saved_machine_id;
+static thread_local bool saved_machine_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[33];
 ssize_t k;
@@ -153,8 +153,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
 }
 
 _public_ int sd_id128_get_boot(sd_id128_t *ret) {
-static __thread sd_id128_t saved_boot_id;
-static __thread bool saved_boot_id_valid = false;
+static thread_local sd_id128_t saved_boot_id;
+static thread_local bool saved_boot_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[36];
 ssize_t k;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index ec6a722..042586d 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -413,7 +413,7 @@ bool manager_is_inhibited(
 }
 
 const char *inhibit_what_to_string(InhibitWhat w) {
-static __thread char buffer[97];
+static thread_local char buffer[97];
 char *p;
 
 if (w  0 || w = _INHIBIT_WHAT_MAX)
diff --git a/src/shared/capability.c b/src/shared/capability.c
index 3219520..f34f6ba 100644
--- a/src/shared/capability.c
+++ b/src/shared/capability.c
@@ -55,8 +55,8 @@ int have_effective_cap(int value) {
 }
 
 unsigned long cap_last_cap(void) {
-static __thread unsigned long saved;
-static __thread bool valid = false;
+static thread_local unsigned long saved;
+static thread_local bool valid = false;
 unsigned long p;
 
 if (valid)
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 2c2ffc5..309f65d 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -480,7 +480,7 @@ static int join_path(const char *controller, const char 
*path, const char *suffi
 
 int cg_get_path(const char *controller, const char *path, const char *suffix, 
char **fs) {
 const char *p;
-static __thread bool good = false;
+static thread_local bool good = false;
 
 assert(fs);
 
diff --git a/src/shared/macro.h b/src/shared/macro.h
index fd3762e..c0597fa 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -27,6 +27,16 @@
 #include sys/uio.h
 #include inttypes.h
 
+#if __STDC_VERSION__ = 201112L  !defined(__STDC_NO_THREADS__)
+#else
+#  define _Thread_local __thread
+#endif
+
+/* make thread_local available w/o including threads.h */
+#ifndef thread_local
+# define thread_local _Thread_local
+#endif
+
 #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
 #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
 #define _sentinel_ __attribute__ ((sentinel))
diff --git a/src/shared/util.c b/src/shared/util.c
index 7c73074..0ce6f70 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -86,7 

Re: [systemd-devel] [PATCH] __thread -- thread_local for C11 compat

2013-12-15 Thread Shawn Landden
On Sun, Dec 15, 2013 at 1:56 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Sun, 15.12.13 13:19, Shawn Landden (sh...@churchofgit.com) wrote:

 also make thread_local available w/o including threads.h

 Hmm, that looks a bit too early, no? Does gcc even support this? glibc
gcc-4.9 supports _Thread_local
http://gcc.gnu.org/gcc-4.9/changes.html

switching -std=gnu99 to -std=gnu11 in Makefile I can compile
systemd w/o the clause that defines _Thread_local as __thread
and all tests pass.

Perhaps we should add
|| (__GNUC__ == 4  __GNUC_MINOR__ = 9)
to the check
 doesn't support threads.h afaics... I couldn't find anything in
 particular regarding C11 TLS support in gcc with google, any link you
 can recommend? Apparently C++11 support is somewhat more existant, but
 C11 support regarding threads appears to be very limited?

 My glibc certainly doesn't ship thread.h. Given that gcc __thread and C11
from C11 page 376:

3 The macros are
thread_local
which expands to _Thread_local;

this part of threads.h is pretty simple
 thread_local appear to have different semantics regarding initialization
 I am also a bit afraid of just defining one to the other already at this
 point in time...

 ---
  src/libsystemd-bus/sd-bus.c |  4 ++--
  src/libsystemd-bus/sd-event.c   |  2 +-
  src/libsystemd-id128/sd-id128.c |  8 
  src/login/logind-inhibit.c  |  2 +-
  src/shared/capability.c |  4 ++--
  src/shared/cgroup-util.c|  2 +-
  src/shared/macro.h  | 10 ++
  src/shared/util.c   |  6 +++---
  src/shared/virt.c   |  8 
  9 files changed, 28 insertions(+), 18 deletions(-)

 diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
 index 4eaceef..64cd663 100644
 --- a/src/libsystemd-bus/sd-bus.c
 +++ b/src/libsystemd-bus/sd-bus.c
 @@ -2815,13 +2815,13 @@ static int bus_default(int (*bus_open)(sd_bus **), 
 sd_bus **default_bus, sd_bus
  }

  _public_ int sd_bus_default_system(sd_bus **ret) {
 -static __thread sd_bus *default_system_bus = NULL;
 +static thread_local sd_bus *default_system_bus = NULL;

  return bus_default(sd_bus_open_system, default_system_bus, ret);
  }

  _public_ int sd_bus_default_user(sd_bus **ret) {
 -static __thread sd_bus *default_user_bus = NULL;
 +static thread_local sd_bus *default_user_bus = NULL;

  return bus_default(sd_bus_open_user, default_user_bus, ret);
  }
 diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
 index 06c84d7..727528b 100644
 --- a/src/libsystemd-bus/sd-event.c
 +++ b/src/libsystemd-bus/sd-event.c
 @@ -2116,7 +2116,7 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, 
 uint64_t *usec) {

  _public_ int sd_event_default(sd_event **ret) {

 -static __thread sd_event *default_event = NULL;
 +static thread_local sd_event *default_event = NULL;
  sd_event *e;
  int r;

 diff --git a/src/libsystemd-id128/sd-id128.c 
 b/src/libsystemd-id128/sd-id128.c
 index 07d2415..9ee40ab 100644
 --- a/src/libsystemd-id128/sd-id128.c
 +++ b/src/libsystemd-id128/sd-id128.c
 @@ -104,8 +104,8 @@ static sd_id128_t make_v4_uuid(sd_id128_t id) {
  }

  _public_ int sd_id128_get_machine(sd_id128_t *ret) {
 -static __thread sd_id128_t saved_machine_id;
 -static __thread bool saved_machine_id_valid = false;
 +static thread_local sd_id128_t saved_machine_id;
 +static thread_local bool saved_machine_id_valid = false;
  _cleanup_close_ int fd = -1;
  char buf[33];
  ssize_t k;
 @@ -153,8 +153,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
  }

  _public_ int sd_id128_get_boot(sd_id128_t *ret) {
 -static __thread sd_id128_t saved_boot_id;
 -static __thread bool saved_boot_id_valid = false;
 +static thread_local sd_id128_t saved_boot_id;
 +static thread_local bool saved_boot_id_valid = false;
  _cleanup_close_ int fd = -1;
  char buf[36];
  ssize_t k;
 diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
 index ec6a722..042586d 100644
 --- a/src/login/logind-inhibit.c
 +++ b/src/login/logind-inhibit.c
 @@ -413,7 +413,7 @@ bool manager_is_inhibited(
  }

  const char *inhibit_what_to_string(InhibitWhat w) {
 -static __thread char buffer[97];
 +static thread_local char buffer[97];
  char *p;

  if (w  0 || w = _INHIBIT_WHAT_MAX)
 diff --git a/src/shared/capability.c b/src/shared/capability.c
 index 3219520..f34f6ba 100644
 --- a/src/shared/capability.c
 +++ b/src/shared/capability.c
 @@ -55,8 +55,8 @@ int have_effective_cap(int value) {
  }

  unsigned long cap_last_cap(void) {
 -static __thread unsigned long saved;
 -static __thread bool valid = false;
 +static thread_local unsigned long saved;
 +static thread_local bool valid = false;
  unsigned long p;

  if (valid)
 diff --git a/src

Re: [systemd-devel] [PATCH] __thread -- thread_local for C11 compat

2013-12-15 Thread Shawn Landden
On Sun, Dec 15, 2013 at 3:16 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Sun, 15.12.13 14:56, Shawn Landden (sh...@churchofgit.com) wrote:

 On Sun, Dec 15, 2013 at 1:56 PM, Lennart Poettering
 lenn...@poettering.net wrote:
  On Sun, 15.12.13 13:19, Shawn Landden (sh...@churchofgit.com) wrote:
 
  also make thread_local available w/o including threads.h
 
  Hmm, that looks a bit too early, no? Does gcc even support this? glibc
 gcc-4.9 supports _Thread_local
 http://gcc.gnu.org/gcc-4.9/changes.html

 Ah, nice. I figure that should be good enough then. (That said, my
 Fedora 20 doesn't have gcc 4.9 yet, so I can't test this...)
debian has gcc-snapshot in sid

 switching -std=gnu99 to -std=gnu11 in Makefile I can compile
 systemd w/o the clause that defines _Thread_local as __thread
 and all tests pass.

 Perhaps we should add
 || (__GNUC__ == 4  __GNUC_MINOR__ = 9)
 to the check

 Hmm, checks for gcc versions are really only the last resorts. If there
 are feature test macros, we should use those, and should they break we
 an still resort to version checks.

  +#if __STDC_VERSION__ = 201112L  !defined(__STDC_NO_THREADS__)
  +#else
  +#  define _Thread_local __thread

 I don't really like the inverted if thing with nothing on the true
 branch and only a false branch I must say.

 Also, should we really take the deviation of filling in the c
 low-levelism _Thread_local here? I think I'd prefer this:
agreed

 #ifndef thread_local
 #if __STDC_VERSION__ = 201112L  !defined(__STDC_NO_THREADS__)
 #define thread_local _Thread_local
 #else
 #define thread_local __thread
 #endif

 With that in place we stay away from defining our own low-level
 _Thread_local, instead we only define the high-level thread_local, and
 do so either to the C11 language feature or the gcc extension...

 If that looks OK (and is tested!) I'd be happy to merge such a patch.

to actually use this we would have to add this patch:

diff --git a/configure.ac b/configure.ac
index f85e86e..5ead127 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,6 +113,7 @@ AS_IF([test x$enable_address_sanitizer = xyes], [
   ])

 CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
+-std=gnu11 \
 -pipe \
 -Wall \
 -Wextra \
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] __thread -- thread_local for C11 compat

2013-12-15 Thread Shawn Landden
Also make thread_local available w/o including threads.h.
(as the latter hasn't been implemented, but this part is trivial)
---
 src/libsystemd-bus/sd-bus.c |  4 ++--
 src/libsystemd-bus/sd-event.c   |  2 +-
 src/libsystemd-id128/sd-id128.c |  8 
 src/login/logind-inhibit.c  |  2 +-
 src/shared/capability.c |  4 ++--
 src/shared/cgroup-util.c|  2 +-
 src/shared/macro.h  | 11 +++
 src/shared/util.c   |  6 +++---
 src/shared/virt.c   |  8 
 9 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 4eaceef..64cd663 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -2815,13 +2815,13 @@ static int bus_default(int (*bus_open)(sd_bus **), 
sd_bus **default_bus, sd_bus
 }
 
 _public_ int sd_bus_default_system(sd_bus **ret) {
-static __thread sd_bus *default_system_bus = NULL;
+static thread_local sd_bus *default_system_bus = NULL;
 
 return bus_default(sd_bus_open_system, default_system_bus, ret);
 }
 
 _public_ int sd_bus_default_user(sd_bus **ret) {
-static __thread sd_bus *default_user_bus = NULL;
+static thread_local sd_bus *default_user_bus = NULL;
 
 return bus_default(sd_bus_open_user, default_user_bus, ret);
 }
diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index 06c84d7..727528b 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -2116,7 +2116,7 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, 
uint64_t *usec) {
 
 _public_ int sd_event_default(sd_event **ret) {
 
-static __thread sd_event *default_event = NULL;
+static thread_local sd_event *default_event = NULL;
 sd_event *e;
 int r;
 
diff --git a/src/libsystemd-id128/sd-id128.c b/src/libsystemd-id128/sd-id128.c
index 07d2415..9ee40ab 100644
--- a/src/libsystemd-id128/sd-id128.c
+++ b/src/libsystemd-id128/sd-id128.c
@@ -104,8 +104,8 @@ static sd_id128_t make_v4_uuid(sd_id128_t id) {
 }
 
 _public_ int sd_id128_get_machine(sd_id128_t *ret) {
-static __thread sd_id128_t saved_machine_id;
-static __thread bool saved_machine_id_valid = false;
+static thread_local sd_id128_t saved_machine_id;
+static thread_local bool saved_machine_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[33];
 ssize_t k;
@@ -153,8 +153,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
 }
 
 _public_ int sd_id128_get_boot(sd_id128_t *ret) {
-static __thread sd_id128_t saved_boot_id;
-static __thread bool saved_boot_id_valid = false;
+static thread_local sd_id128_t saved_boot_id;
+static thread_local bool saved_boot_id_valid = false;
 _cleanup_close_ int fd = -1;
 char buf[36];
 ssize_t k;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index ec6a722..042586d 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -413,7 +413,7 @@ bool manager_is_inhibited(
 }
 
 const char *inhibit_what_to_string(InhibitWhat w) {
-static __thread char buffer[97];
+static thread_local char buffer[97];
 char *p;
 
 if (w  0 || w = _INHIBIT_WHAT_MAX)
diff --git a/src/shared/capability.c b/src/shared/capability.c
index 3219520..f34f6ba 100644
--- a/src/shared/capability.c
+++ b/src/shared/capability.c
@@ -55,8 +55,8 @@ int have_effective_cap(int value) {
 }
 
 unsigned long cap_last_cap(void) {
-static __thread unsigned long saved;
-static __thread bool valid = false;
+static thread_local unsigned long saved;
+static thread_local bool valid = false;
 unsigned long p;
 
 if (valid)
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 2c2ffc5..309f65d 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -480,7 +480,7 @@ static int join_path(const char *controller, const char 
*path, const char *suffi
 
 int cg_get_path(const char *controller, const char *path, const char *suffix, 
char **fs) {
 const char *p;
-static __thread bool good = false;
+static thread_local bool good = false;
 
 assert(fs);
 
diff --git a/src/shared/macro.h b/src/shared/macro.h
index fd3762e..362d62b 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -27,6 +27,17 @@
 #include sys/uio.h
 #include inttypes.h
 
+#ifndef thread_local
+/* don't break on glibc  2.16 that doesn't define __STDC_NO_THREADS__
+ * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 */
+# if __STDC_VERSION__ = 201112L  !(defined(__STDC_NO_THREADS__) || \
+  (defined(__GNU_LIBRARY__)  __GLIBC__ 
== 2  __GLIBC_MINOR__  16))
+#  define thread_local _Thread_local
+# else
+#  define thread_local __thread
+# endif
+#endif
+
 #define _printf_(a,b) __attribute__ ((format 

[systemd-devel] [PATCH 1/2] util: no need for in_initrd() cache to be thread-local

2013-12-15 Thread Shawn Landden
the process only has one working directory, and a race is
harmless
---
 src/shared/util.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/shared/util.c b/src/shared/util.c
index b5ffaa1..7c73074 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2737,9 +2737,9 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool 
honour_sticky, struct
 
 _pure_ static int is_temporary_fs(struct statfs *s) {
 assert(s);
-return
-F_TYPE_EQUAL(s-f_type, TMPFS_MAGIC) ||
-F_TYPE_EQUAL(s-f_type, RAMFS_MAGIC);
+
+return F_TYPE_EQUAL(s-f_type, TMPFS_MAGIC) ||
+   F_TYPE_EQUAL(s-f_type, RAMFS_MAGIC);
 }
 
 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat 
*root_dev) {
@@ -5155,7 +5155,7 @@ bool is_valid_documentation_url(const char *url) {
 }
 
 bool in_initrd(void) {
-static __thread int saved = -1;
+static int saved = -1;
 struct statfs s;
 
 if (saved = 0)
-- 
1.8.5.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] _noreturn_ -- noreturn for C11 compat

2013-12-16 Thread Shawn Landden
also define noreturn w/o stdnoreturn.h
---
 src/core/main.c |  2 +-
 src/journal/test-journal-interleaving.c |  2 +-
 src/shared/log.c|  4 ++--
 src/shared/log.h|  4 ++--
 src/shared/macro.h  | 10 +-
 src/shared/pager.c  |  2 +-
 src/shared/util.c   |  2 +-
 src/shared/util.h   |  2 +-
 src/udev/collect/collect.c  |  2 +-
 9 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/src/core/main.c b/src/core/main.c
index 6c3d9bf..eb5413e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -112,7 +112,7 @@ static FILE* serialization = NULL;
 static void nop_handler(int sig) {
 }
 
-_noreturn_ static void crash(int sig) {
+noreturn static void crash(int sig) {
 
 if (getpid() != 1)
 /* Pass this on immediately, if this is not PID 1 */
diff --git a/src/journal/test-journal-interleaving.c 
b/src/journal/test-journal-interleaving.c
index af0d43e..5b74714 100644
--- a/src/journal/test-journal-interleaving.c
+++ b/src/journal/test-journal-interleaving.c
@@ -36,7 +36,7 @@
 
 static bool arg_keep = false;
 
-_noreturn_ static void log_assert_errno(const char *text, int eno, const char 
*file, int line, const char *func) {
+noreturn static void log_assert_errno(const char *text, int eno, const char 
*file, int line, const char *func) {
 log_meta(LOG_CRIT, file, line, func,
  '%s' failed at %s:%u (%s): %s.,
  text, file, line, func, strerror(eno));
diff --git a/src/shared/log.c b/src/shared/log.c
index 2404de8..2517f5d 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -702,12 +702,12 @@ static void log_assert(int level, const char *text, const 
char *file, int line,
 }
 #pragma GCC diagnostic pop
 
-_noreturn_ void log_assert_failed(const char *text, const char *file, int 
line, const char *func) {
+noreturn void log_assert_failed(const char *text, const char *file, int line, 
const char *func) {
 log_assert(LOG_CRIT, text, file, line, func, Assertion '%s' failed at 
%s:%u, function %s(). Aborting.);
 abort();
 }
 
-_noreturn_ void log_assert_failed_unreachable(const char *text, const char 
*file, int line, const char *func) {
+noreturn void log_assert_failed_unreachable(const char *text, const char 
*file, int line, const char *func) {
 log_assert(LOG_CRIT, text, file, line, func, Code should not be 
reached '%s' at %s:%u, function %s(). Aborting.);
 abort();
 }
diff --git a/src/shared/log.h b/src/shared/log.h
index de0e000..3dcfa11 100644
--- a/src/shared/log.h
+++ b/src/shared/log.h
@@ -124,13 +124,13 @@ int log_dump_internal(
 const char *func,
 char *buffer);
 
-_noreturn_ void log_assert_failed(
+noreturn void log_assert_failed(
 const char *text,
 const char *file,
 int line,
 const char *func);
 
-_noreturn_ void log_assert_failed_unreachable(
+noreturn void log_assert_failed_unreachable(
 const char *text,
 const char *file,
 int line,
diff --git a/src/shared/macro.h b/src/shared/macro.h
index 362d62b..51af289 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -38,10 +38,18 @@
 # endif
 #endif
 
+/* define noreturn without stdnoreturn.h */
+#ifndef noreturn
+# if __STDC_VERSION__ = 201112L
+#  define noreturn _Noreturn
+# else
+#  define noreturn __attribute__((noreturn))
+# endif
+#endif
+
 #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
 #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
 #define _sentinel_ __attribute__ ((sentinel))
-#define _noreturn_ __attribute__((noreturn))
 #define _unused_ __attribute__ ((unused))
 #define _destructor_ __attribute__ ((destructor))
 #define _pure_ __attribute__ ((pure))
diff --git a/src/shared/pager.c b/src/shared/pager.c
index 9fa6114..72a29f2 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -32,7 +32,7 @@
 
 static pid_t pager_pid = 0;
 
-_noreturn_ static void pager_fallback(void) {
+noreturn static void pager_fallback(void) {
 ssize_t n;
 
 do {
diff --git a/src/shared/util.c b/src/shared/util.c
index 0ce6f70..e1f92fd 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3469,7 +3469,7 @@ int wait_for_terminate_and_warn(const char *name, pid_t 
pid) {
 return -EPROTO;
 }
 
-_noreturn_ void freeze(void) {
+noreturn void freeze(void) {
 
 /* Make sure nobody waits for us on a socket anymore */
 close_all_fds(NULL, 0);
diff --git a/src/shared/util.h b/src/shared/util.h
index d5fa81c..d43aeff 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -417,7 +417,7 @@ char *normalize_env_assignment(const char *s);
 int wait_for_terminate(pid_t pid, siginfo_t *status);
 int wait_for_terminate_and_warn(const char *name, pid_t pid);
 
-_noreturn_ void freeze(void);

  1   2   3   >