[systemd-devel] Why does nspawn check if in a user session?

2017-09-13 Thread Luke Shumaker
Hi all,

I have another question about `systemd-nspawn` internals.

When sanity-checking argv, it does:

if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 
0) {
log_error("--keep-unit --register=yes may not be used when 
invoked from a user session.");
return -EINVAL;
}

  (the `&& arg_register` bit was added in 234)

Why does nspawn care if it is in a user session?

My best guess is that it doesn't want to share its cgroup with any
other processes, and it is using user session membership as a sloppy
proxy for that.  If that's the case, wouldn't it be more correct and
robust to check for other processes in
"/sys/fs/cgroup/.../cgroup.procs"?

-- 
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] Why does nspawn need two child processes?

2017-05-31 Thread Luke Shumaker
Hi all,

I have a question about `systemd-nspawn` internals.

When creating the child process, it does something like:

  parent
|
clone(MOUNT)
|  `,
|  outer_child()
|   |
|   clone(rest)
|   |  `,
|returninner_child()
|  ,---'|
  wait()|
| exec()
|  |||
| exit()
|  ,'
  wait()

where in the first `clone()` it unshares the mount namespace, and in
the second `clone()` it unshares all of the other namespaces (except
for the cgroup namespace).

Initially, I was confused by the awkward dance with having two
children; I couldn't imagine a reason why it is necessary to do this
with a separate `inner_child` and `outer_child`; why can't everything
be done in a single child process?:

  parent
|
clone(MOUNT)
|  `,
|child()
|   |
|  unshare(rest)
|   |
| exec()
|  |||
| exit()
|  ,'
  wait()

It has used the current two-child approach since user-namespace
support was first completed in 03cfe0d5, which only has the brief
commit message "nspawn: finish user namespace support"; so there
aren't too many clues to be found in the commit log.

Part of the answer lies in the behavior of `unshare(CLONE_NEWPID)`.
Unlike all of the other namespaces that may be unshared, calling
`unshare(CLONE_NEWPID)` doesn't actually unshare the PID namespace in
*this* process, it says to unshare the PID namespace at the next
`fork()`/`clone()` call.  So even if we changed `systemd-nspawn` to
the `clone(MOUNT)/unshare(rest)` model, it would still have to
`clone()` (or plain `fork()` at that point) a second, inner, child
process.

So then, I'm left wondering why unsharing the PID namespace can't be
moved up to the initial `clone()`, allowing everything else to be
`unshare`(2)ed in the initial child process:

  parent
|
clone(MOUNT|PID)
|  `,
|child()
|   |
|  unshare(rest)
|   |
| exec()
|  |||
| exit()
|  ,'
  wait()

So my question becomes: what has to be done *after* unsharing the
mount namespace, but *before* unsharing the PID namespace?

-- 
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] time-sync.target

2017-05-31 Thread Luke Shumaker
On Wed, 31 May 2017 04:33:09 -0400,
Pietro Paolini wrote:
> Thanks! Unfortunately it is not an option to install the Go runtime
> system on the board I am working with, is there a place where I can
> find docs about writing my own wrapper in C ?

Go is a compiled language, there is no separate runtime to install.
It's also easy to cross-compile Go programs.  However, Go binaries
tend to have a minimum size of about 1.5MB, so I can appreciate not
wanting to add another ~4MB for two tiny programs.

Each of the programs is pretty simple.  If you know C, the Go should
be pretty simple to read; I think the weirdest bit to a C programmer
is that "go fn()" runs "fn()" in a separate thread.

The systemd-timesyncd-wait program is super-simple.  It recieves a
socket from systemd, waits for some data to come in on it, then exits.
Most of the Go version is re-implementing libsystemd's
sd_listen_fds().  Without actually testing it, I think a C
implementation is as simple as:

#include 
#include 
#include 

#include 

int main() {
int r;
char dat[4096];

r = sd_listen_fds(0);
if (r != 1)
error(1, 0, "expected 1 fd, got %d\n", r);

for (;;) {
r = read(SD_LISTEN_FDS_START, dat, sizeof(dat));
if (r < 0)
error(127, errno, "read");
if (r > 0)
return 0;
}
}

The systemd-timesyncd-wrap program is a bit more complicated.  It
looks the socket used by sd_notify(), and intercepts it.  So look at
the socket pointed to by $NOTIFY_SOCKET, create an identical socket,
and then run the real systemd-timesyncd with $NOTIFY_SOCKET set to the
copy (also, you should set $WATCHDOG_PID to the PID of the real
systemd-timesyncd, but that turned out to be tricky in Go, and wasn't
too important, so I just unset it).  We listen on the copy, and simply
forward all messages to the original socket; with the exception that
if the message has a line that starts with "STATUS=Synchronized", then
we *also* send a message to systemd-timesyncd-wait via
"/run/timesyncd/time-sync.sock".  The tricky part is that messages
sent on $NOTIFY_SOCKET may have out-of-band control message (cmsg)
data associated with them, and we have to forward this too.  Control
messages are poorly documented in both C and Go.  To receive them,
look manager.c:manager_dispatch_notify_fd(), and to send them, look at
libsystemd's sd_pid_notify_with_fds().

If you're writing C anyway, it may be easier to patch
systemd-timesyncd to send the additional message when it sends the
"STATUS=Syncronized..." message, rather than wrapping it.

-- 
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] time-sync.target

2017-05-30 Thread Luke Shumaker
On Tue, 30 May 2017 11:57:00 -0400,
Pietro Paolini wrote:
> Hi everybody,
> 
> I am trying to configure my systemd to run my service *after* the
> timesyncd service is synchronized with the NTP server, unfortunately
> adding the "After=time-sycd.target" does not work as I can't see any
> change in the behavior - my service is started immediately anyway.
> 
> Reading here https://github.com/systemd/systemd/issues/5097 it looks
> like there is a problem with that target but I am not sure where to
> start from, is it feasible to patch the systemd-timesyncd daemon to
> correct the behavior ?

Yes, this is a problem with timesyncd, and it should eventually be
patched.

The problem with patching it is that without re-thinking something, it
is impossible to have it block time-sync.target without also risking
systemd-timesyncd.service from timing out.

The only solution that I can think of is to have a second helper
process that can't time out that waits for a signal from timesyncd;
and have that process block time-sync.target.  But, the systemd team
hasn't yet decided if this solution is acceptable to them.

So, anyway, I went ahead wrote such a helper program, and a wrapper
for timesyncd that handles sending the signal.

> As alternative I could write my wrapper around the daemon as done in
> the link reporting the issue, both ways I will need to read
> something enlightening on the matter, would you be able to point me
> into the right direction ?

You should be able to install and use the wrapper that I wrote.
There's nothing specific to my use-case about it.  If you install it,
then the "time-sync.target" should "just work" correctly with
timesyncd.

Of course, in the long-term it would be preferable to patch timesyncd,
instead of having to install separate wrapper to fix the behavior.
But for today, it works.

-- 
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Using systemd --user to manage graphical sessions?

2016-05-11 Thread Luke Shumaker
On Wed, 11 May 2016 12:13:45 -0400,
Martin Pitt wrote:
> Or is someone actually using systemd --user for graphical sessions
> already and found a trick that I missed?

I am!  For several months now (and before that, I was still using
systemd --user for graphical stuff, but not consistently/coherently).

My configuration: https://lukeshu.com/git/dotfiles/tree/.config
Crappy write-up: https://lukeshu.com/blog/x11-systemd.html

One thing to note is that I don't use a DE, and have minimal
bus-activated services.

The big difference between what I do and what you wrote is that I
don't tie the DISPLAY name to the XDG_SESSION_ID (actually, the
session ID isn't even set in the graphical session).

The short version of how I have it work:

My ~/.xinitrc (AKA: script that starts the initial X11 clients)
contains:

_DISPLAY="$(systemd-escape -- "$DISPLAY")"
mkfifo "${XDG_RUNTIME_DIR}/x11-wm@${_DISPLAY}"
cat < "${XDG_RUNTIME_DIR}/x11-wm@${_DISPLAY}" &
systemctl --user start "X11@${_DISPLAY}.target" &
wait
systemctl --user stop "X11@${_DISPLAY}.target"

Which basically says: start X11@:0.target, wait for something to open
"${XDG_RUNTIME_DIR}/x11-wm@${_DISPLAY}" for writing and then close it,
then stop X11@:0.target.  Then I have my window manager configured to
open/close the file when I want to quit X11/log out (really, I have it
open at start, then just exit on quit; implicitly closing it).

Then, each of the whatever@${DISPLAY}.service files contains:

[Unit]
After=X11@%i.target
Requisite=X11@%i.target
[Service]
Environment=DISPLAY=%I

Now, when I launch a program from the window manager, I have it launch
with `systemd-run --user --scope -- sh -c "COMMAND HERE"`, so that
systemd can tell the difference between it and the window manager.  I
imagine that this would be problematic with less configurable window
managers.

As I type this, I have two graphical logins to the same user.  One on
a real screen, and the other with a fake screen via `vncserver` (of
course, managed as a systemd user unit :-) ).

The only problem I have with this setup is that dunst (my desktop
notification daemon) isn't happy running multiple instances on
different displays.  I think it's because it isn't happy sharing the
dbus, but I haven't spent even 1 minute debugging it yet.

-- 
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] cg_path_get_user_unit(): Did not correctly parse user-unit templates.

2015-02-03 Thread Luke Shumaker
It ran either skip_session() or skip_user_manager(), then ran skip_slices()
iff skip_session() ran.  It needs to run skip_slices() in either case.

Included is a test case demonstrating why.
---
 src/shared/cgroup-util.c| 19 ---
 src/test/test-cgroup-util.c |  1 +
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 0d3cc53..1c5af69 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1251,17 +1251,14 @@ int cg_path_get_user_unit(const char *path, char 
**unit) {
 /* Skip slices, if there are any */
 e = skip_slices(path);
 
-/* Skip the session scope... */
-t = skip_session(e);
-if (t)
-/* ... and skip more slices if there's one */
-e = skip_slices(t);
-else {
-/* ... or require a user manager unit to be there */
-e = skip_user_manager(e);
-if (!e)
-return -ENOENT;
-}
+/* Skip the session scope or user manager... */
+(t = skip_session(e)) || (t = skip_user_manager(e));
+
+if (!t)
+return -ENOENT;
+
+/* ... and skip more slices if there are any */
+e = skip_slices(t);
 
 return cg_path_decode_unit(e, unit);
 }
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 58eb744..67eeeb5 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -93,6 +93,7 @@ static void test_path_get_user_unit(void) {
 check_p_g_u_u(/meh.service, -ENOENT, NULL);
 check_p_g_u_u(/session-3.scope/_cpu.service, 0, cpu.service);
 
check_p_g_u_u(/user.slice/user-1000.slice/user@1000.service/server.service, 
0, server.service);
+
check_p_g_u_u(/user.slice/user-1000.slice/user@1000.service/foobar.slice/foobar@pie.service,
 0, foobar@pie.service);
 
check_p_g_u_u(/user.slice/user-1000.slice/user@.service/server.service, 
-ENOENT, NULL);
 }
 
-- 
2.2.2

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


Re: [systemd-devel] [PATCH] cg_path_get_user_unit(): Did not correctly parse user-unit templates.

2015-02-03 Thread Luke Shumaker
At Wed, 4 Feb 2015 01:52:36 +0100,
Lennart Poettering wrote:
  +/* Skip the session scope or user manager... */
  +(t = skip_session(e)) || (t = skip_user_manager(e));
 
 Hmpf, I really don't like this ()||() magic I must say.
 
 Any chance you can rework this to just use normal
 
 t = skip_session(e);
 if (!t)
 t = skip_user_manager(...)
 
 THis is really an excercise in making code easily readable, not an
 excercsie to show superior C skills ;-)

Sure.  I thought the || version was easier to read; that it showed the
intent better.  Though it may be that it's similar to a Ruby idiom,
and I've been working with some Ruby recently.

--
Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCHv2] cg_path_get_user_unit(): Did not correctly parse user-unit templates.

2015-02-03 Thread Luke Shumaker
It ran either skip_session() or skip_user_manager(), then ran skip_slices()
iff skip_session() ran.  It needs to run skip_slices() in either case.

Included is a test case demonstrating why.
---
 src/shared/cgroup-util.c| 18 --
 src/test/test-cgroup-util.c |  1 +
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 0d3cc53..d34e1fa 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1251,17 +1251,15 @@ int cg_path_get_user_unit(const char *path, char 
**unit) {
 /* Skip slices, if there are any */
 e = skip_slices(path);
 
-/* Skip the session scope... */
+/* Skip the session scope or user manager... */
 t = skip_session(e);
-if (t)
-/* ... and skip more slices if there's one */
-e = skip_slices(t);
-else {
-/* ... or require a user manager unit to be there */
-e = skip_user_manager(e);
-if (!e)
-return -ENOENT;
-}
+if (!t)
+t = skip_user_manager(e);
+if (!t)
+return -ENOENT;
+
+/* ... and skip more slices if there are any */
+e = skip_slices(t);
 
 return cg_path_decode_unit(e, unit);
 }
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 58eb744..67eeeb5 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -93,6 +93,7 @@ static void test_path_get_user_unit(void) {
 check_p_g_u_u(/meh.service, -ENOENT, NULL);
 check_p_g_u_u(/session-3.scope/_cpu.service, 0, cpu.service);
 
check_p_g_u_u(/user.slice/user-1000.slice/user@1000.service/server.service, 
0, server.service);
+
check_p_g_u_u(/user.slice/user-1000.slice/user@1000.service/foobar.slice/foobar@pie.service,
 0, foobar@pie.service);
 
check_p_g_u_u(/user.slice/user-1000.slice/user@.service/server.service, 
-ENOENT, NULL);
 }
 
-- 
2.2.2

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


Re: [systemd-devel] [PATCH] nspawn: When exiting with an error, make the error code meaningful.

2014-06-29 Thread Luke Shumaker
At Sun, 29 Jun 2014 12:31:13 +0100,
Djalal Harouni wrote:
 On Sat, Jun 28, 2014 at 12:09:56PM -0400, Luke Shumaker wrote:
  This is accomplished by having wait_for_container() return a positive error
  code when we would like that error code to make its way to the user.  This
  is at odds with the CODING_STYLE rule that error codes should be returned
  as negative values.
 This is not odd, we already do that!
 
 When I did convert to wait_for_container(), I remember I checked all
 calls to wait_for_terminate() to see what others do, and there was the:
 src/shared/util.c:wait_for_terminate_and_warn()
 
 Which also returns the positive 'status.si_status' code to caller, and it
 is used in all places...

I missed that wait_for_terminate_and_warn() also did that!

With that in consideration, shouldn't the check of the return value
from wait_for_terminate_and_warn() at src/quotacheck/quotacheck.c:110
be '== 0' instead of '= 0'?

 So if you are able to send a v2 of this patch, here are some comments:

I'm putting one together now; thanks for the feedback!

  + * Return values:
  + *  0 : The container was terminated by a signal, or failed for an
  + *   unknown reason.  No change is made to the container argument.
 wait_for_container() failed to get the state of the container, the
 container was terminated by a signal or failed for an unknown reason.

You mean wait_for_terminate()?

 A minor thing:
 
 in wait_for_container() could you add please a log_warning() if
 wait_for_terminate() fails, as it is done in
 wait_for_terminate_and_warn().

Yeah, I'll add it as a separate commit.

 Thank you for the report and the patch!

Thank you for taking the time to review it!

Happy hacking,
~ Luke Shumaker
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH v2 2/3] nspawn: Fix regression with exit status

2014-06-29 Thread Luke Shumaker
Commit 113cea8 introduced a bug that caused the exit code of systemd-nspawn
to not reflect the exit code of the program executed in the container.
---
 src/nspawn/nspawn.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 0a8dc0c..be0e6b5 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2645,12 +2645,21 @@ static int change_uid_gid(char **_home) {
 }
 
 /*
- * Return 0 in case the container is being rebooted, has been shut
- * down or exited successfully. On failures a negative value is
- * returned.
+ * Return values:
+ *  0 : wait_for_terminate() failed to get the state of the
+ *   container, the container was terminated by a signal, or
+ *   failed for an unknown reason.  No change is made to the
+ *   container argument.
+ *  0 : The program executed in the container terminated with an
+ *   error.  The exit code of the program executed in the
+ *   container is returned.  No change is made to the container
+ *   argument.
+ *   0 : The container is being rebooted, has been shut down or exited
+ *   successfully.  The container argument has been set to either
+ *   CONTAINER_TERMINATED or CONTAINER_REBOOTED.
  *
- * The status of the container CONTAINER_TERMINATED or
- * CONTAINER_REBOOTED will be saved in the container argument
+ * That is, success is indicated by a return value of zero, and an
+ * error is indicated by a non-zero value.
  */
 static int wait_for_container(pid_t pid, ContainerStatus *container) {
 int r;
@@ -2672,7 +2681,6 @@ static int wait_for_container(pid_t pid, ContainerStatus 
*container) {
 } else {
 log_error(Container %s failed with error code %i.,
   arg_machine, status.si_status);
-r = -1;
 }
 break;
 
@@ -3299,8 +3307,12 @@ check_container_status:
 r = wait_for_container(pid, container_status);
 pid = 0;
 
-if (r  0) {
-r = EXIT_FAILURE;
+if (r != 0) {
+/* If r  0, explicitly set to EXIT_FAILURE,
+ * otherwise return the exit code of the
+ * containered process. */
+if (r  0)
+r = EXIT_FAILURE;
 break;
 } else if (container_status == CONTAINER_TERMINATED)
 break;
-- 
2.0.1

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


[systemd-devel] [PATCH v2 3/3] nspawn: log a warning on failure from wait_for_terminate()

2014-06-29 Thread Luke Shumaker
This is at the suggestion of Djalal Harouni on the mailing list, and
reflects the behavior of shared/util.c:wait_for_terminate_and_warn().
---
 src/nspawn/nspawn.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index be0e6b5..8fb72d6 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2666,8 +2666,10 @@ static int wait_for_container(pid_t pid, ContainerStatus 
*container) {
 siginfo_t status;
 
 r = wait_for_terminate(pid, status);
-if (r  0)
+if (r  0) {
+log_warning(Failed to wait for container: %s, strerror(-r));
 return r;
+}
 
 switch (status.si_code) {
 case CLD_EXITED:
-- 
2.0.1

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


[systemd-devel] [PATCH] nspawn: When exiting with an error, make the error code meaningful.

2014-06-28 Thread Luke Shumaker
This is accomplished by having the return value of wait_for_container be
interpreted as a negative version of the exit status code.
---
 src/nspawn/nspawn.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 0a8dc0c..0c89c40 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2662,7 +2662,7 @@ static int wait_for_container(pid_t pid, ContainerStatus 
*container) {
 
 switch (status.si_code) {
 case CLD_EXITED:
-r = status.si_status;
+r = -status.si_status;
 if (r == 0) {
 if (!arg_quiet)
 log_debug(Container %s exited successfully.,
@@ -2672,7 +2672,6 @@ static int wait_for_container(pid_t pid, ContainerStatus 
*container) {
 } else {
 log_error(Container %s failed with error code %i.,
   arg_machine, status.si_status);
-r = -1;
 }
 break;
 
@@ -2699,13 +2698,13 @@ static int wait_for_container(pid_t pid, 
ContainerStatus *container) {
 case CLD_DUMPED:
 log_error(Container %s terminated by signal %s.,
   arg_machine, signal_to_string(status.si_status));
-r = -1;
+r = -EXIT_FAILURE;
 break;
 
 default:
 log_error(Container %s failed due to unknown reason.,
   arg_machine);
-r = -1;
+r = -EXIT_FAILURE;
 break;
 }
 
@@ -3296,11 +3295,10 @@ check_container_status:
 /* Redundant, but better safe than sorry */
 kill(pid, SIGKILL);
 
-r = wait_for_container(pid, container_status);
+r = -wait_for_container(pid, container_status);
 pid = 0;
 
-if (r  0) {
-r = EXIT_FAILURE;
+if (r  0) {
 break;
 } else if (container_status == CONTAINER_TERMINATED)
 break;
-- 
2.0.1

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


[systemd-devel] nspawn: When exiting with an error, make the exit code meaningful.

2014-06-28 Thread Luke Shumaker
These two patches both do the same thing, in slightly different ways.
They fix a regression intruduced in commit 113cea8 (present in v213
and 214) where the exit status of nspawn does not reflect the exit
status of the containered process.

Happy hacking,
~ Luke Shumaker

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


[systemd-devel] [PATCH] nspawn: When exiting with an error, make the error code meaningful.

2014-06-28 Thread Luke Shumaker
This is accomplished by having wait_for_container() return a positive error
code when we would like that error code to make its way to the user.  This
is at odds with the CODING_STYLE rule that error codes should be returned
as negative values.
---
 src/nspawn/nspawn.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 0a8dc0c..42f939b 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2645,12 +2645,17 @@ static int change_uid_gid(char **_home) {
 }
 
 /*
- * Return 0 in case the container is being rebooted, has been shut
- * down or exited successfully. On failures a negative value is
- * returned.
+ * Return values:
+ *  0 : The container was terminated by a signal, or failed for an
+ *   unknown reason.  No change is made to the container argument.
+ *  0 : The container terminated with an error code, which is the
+ *   return value.  No change is made to the container argument.
+ *   0 : The container is being rebooted, has been shut down or exited
+ *   successfully.  The container argument has been set to either
+ *   CONTAINER_TERMINATED or CONTAINER_REBOOTED.
  *
- * The status of the container CONTAINER_TERMINATED or
- * CONTAINER_REBOOTED will be saved in the container argument
+ * That is, success is indicated by a return value of zero, and an
+ * error is indicated by a non-zero value.
  */
 static int wait_for_container(pid_t pid, ContainerStatus *container) {
 int r;
@@ -2672,7 +2677,6 @@ static int wait_for_container(pid_t pid, ContainerStatus 
*container) {
 } else {
 log_error(Container %s failed with error code %i.,
   arg_machine, status.si_status);
-r = -1;
 }
 break;
 
@@ -3299,8 +3303,9 @@ check_container_status:
 r = wait_for_container(pid, container_status);
 pid = 0;
 
-if (r  0) {
-r = EXIT_FAILURE;
+if (r != 0) {
+if (r  0)
+r = EXIT_FAILURE;
 break;
 } else if (container_status == CONTAINER_TERMINATED)
 break;
-- 
2.0.1

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


[systemd-devel] [PATCH 1/2] ptyfwd: Set the size of the PTY base on the size of stdout, not stdin.

2013-11-23 Thread Luke Shumaker
---
 src/shared/ptyfwd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 7225b93..85a0ddc 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -305,7 +305,7 @@ static int process_pty_loop(int master, sigset_t *mask, 
pid_t kill_pid, int sign
 struct winsize ws;
 
 /* The window size changed, let's 
forward that. */
-if (ioctl(STDIN_FILENO, TIOCGWINSZ, 
ws) = 0)
+if (ioctl(STDOUT_FILENO, TIOCGWINSZ, 
ws) = 0)
 ioctl(master, TIOCSWINSZ, ws);
 
 } else if (sfsi.ssi_signo == SIGTERM  
kill_pid  0  signo  0  !tried_orderly_shutdown) {
@@ -346,7 +346,7 @@ int process_pty(int master, sigset_t *mask, pid_t kill_pid, 
int signo) {
 struct winsize ws;
 int r;
 
-if (ioctl(STDIN_FILENO, TIOCGWINSZ, ws) = 0)
+if (ioctl(STDOUT_FILENO, TIOCGWINSZ, ws) = 0)
 ioctl(master, TIOCSWINSZ, ws);
 
 if (tcgetattr(STDIN_FILENO, saved_attr) = 0) {
-- 
1.8.4.2

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


[systemd-devel] nspawn (ptyfwd): Correctly handle output redirection

2013-11-23 Thread Luke Shumaker
At Tue, 5 Nov 2013 19:59:46 +0100,
Lennart Poettering wrote:
 On Mon, 04.11.13 11:05, Luke T. Shumaker (luke...@sbcglobal.net) wrote:
  A couple of weeks ago, I reported a bug that systemd-nspawn does not
  correctly handle I/O redirection[1].
  
  I described in detail the several smaller bugs that lead up to both
  stdin and stdout redirection being broken, and uploaded a patch that
  fixes stdout redirection.  That patch is attached here.  Stdin
  redirection is more involved to fix.
 
 Hmm, can you rebase on current git please?

Sorry it took so long, I've been unable to devote much time to this.

Happy hacking,
~ Luke Shumaker

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


[systemd-devel] [PATCH 2/2] ptyfwd: Don't set the output prop of stdin, nor the input props of stdout.

2013-11-23 Thread Luke Shumaker
It was calling cfmakeraw(3) on the properties for STDIN_FILENO; cfmakeraw
sets both input and output properties.  If (and only if) stdin and stdout
are the same device is this correct.  Otherwise, we must change only the
input properties of stdin, and only the output properties of stdout.
---
 src/shared/ptyfwd.c | 35 +++
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 85a0ddc..72aa59e 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -341,29 +341,40 @@ static int process_pty_loop(int master, sigset_t *mask, 
pid_t kill_pid, int sign
 }
 
 int process_pty(int master, sigset_t *mask, pid_t kill_pid, int signo) {
-struct termios saved_attr;
-bool saved = false;
+struct termios saved_stdin_attr, raw_stdin_attr;
+struct termios saved_stdout_attr, raw_stdout_attr;
+bool saved_stdin = false;
+bool saved_stdout = false;
 struct winsize ws;
 int r;
 
 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, ws) = 0)
 ioctl(master, TIOCSWINSZ, ws);
 
-if (tcgetattr(STDIN_FILENO, saved_attr) = 0) {
-struct termios raw_attr;
-saved = true;
+if (tcgetattr(STDIN_FILENO, saved_stdin_attr) = 0) {
+saved_stdin = true;
 
-raw_attr = saved_attr;
-cfmakeraw(raw_attr);
-raw_attr.c_lflag = ~ECHO;
-
-tcsetattr(STDIN_FILENO, TCSANOW, raw_attr);
+raw_stdin_attr = saved_stdin_attr;
+cfmakeraw(raw_stdin_attr);
+raw_stdin_attr.c_oflag = saved_stdin_attr.c_oflag;
+tcsetattr(STDIN_FILENO, TCSANOW, raw_stdin_attr);
+}
+if (tcgetattr(STDOUT_FILENO, saved_stdout_attr) = 0) {
+saved_stdout = true;
+
+raw_stdout_attr = saved_stdout_attr;
+cfmakeraw(raw_stdout_attr);
+raw_stdout_attr.c_iflag = saved_stdout_attr.c_iflag;
+raw_stdout_attr.c_lflag = saved_stdout_attr.c_lflag;
+tcsetattr(STDOUT_FILENO, TCSANOW, raw_stdout_attr);
 }
 
 r = process_pty_loop(master, mask, kill_pid, signo);
 
-if (saved)
-tcsetattr(STDIN_FILENO, TCSANOW, saved_attr);
+if (saved_stdout)
+tcsetattr(STDOUT_FILENO, TCSANOW, saved_stdout_attr);
+if (saved_stdin)
+tcsetattr(STDIN_FILENO, TCSANOW, saved_stdin_attr);
 
 return r;
 
-- 
1.8.4.2

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