/srv/irclogs.ubuntu.com/2009/07/13/#upstart.txt

=== h\h is now known as haraldh
rjbell4Keybuk: I was wondering if you could elaborate, as ion mentioned yesterday.13:19
Keybukrjbell4: what's up?13:19
rjbell4I asked the following yesterday: Is there any support in upstart for monitoring multiple child processes?  I've found "expect fork" and "expect daemon", which seem to monitor a single child or grandchild, but what if there are several child processes, and if any of them fail then I want to take action?13:19
Keybukthat's planned13:21
Keybukthough obviously within certain limits13:21
Keybuksince you'd need to know beforehand how many children to expect13:21
Keybukhow long it typically takes for that number of children to appear13:21
Keybukand wouldn't want to die if they double-fork()d along the way13:21
Keybuketc.13:21
ionrjbell4: Please describe your exact use case.13:22
rjbell4Keybuk: Okay, but not yet implemented, I gather?13:22
ionWhen i said 0.10 yesterday, i meant the-next-major-version-still-in-planning.13:23
Keybukcorrect13:23
Keybukrjbell4: but without more details, I'm not sure that what's planned will actually do what you want13:23
rjbell4ion: We have replaced init with upstart on our product, and one of the services we run forks a few different processes to do related-but-separate tasks.  If any of those processes fails (segfaults, whatever), the whole thing should be restarted.13:24
Keybukhow would you tell Upstart, in advance, what those related-but-separate tasks were?13:24
Keybukwhat can Upstart use to distinguish them?13:25
Keybukdoes the parent process that spawned them remain, or does that terminate?13:25
Keybukdo any of the processes daemonise, or fork?13:25
rjbell4I was actually intrigued by the "read-a-pid-a-file" approach, as I thought if the service had support, that might be a cheap way to support telling Upstart which processes to monitor.  But that support appears to have been removed.13:26
Keybukare the spawned processes the same executable, or are they exec() of other executables?13:26
Keybukrjbell4: right, it's not very reliable13:26
rjbell4It might suffice to tell upstart to monitor the 3 children of the process that it kicks off, rather that just looking for 1 with "expect fork".  I'm not positive it would work, but I think it might.13:26
Keybukcan you answer the other questions above?13:27
rjbell4Keybuk: In this case, I think the parent terminates, and the children keep running.  I'd have to check to be certain, but I believe that's correct.  It's possible that they *should* daemonize (by forking again), but don't.13:28
ionIf one of the children dies, what should happen to the other children?13:29
Keybukthe problem there is that you're spawning more then three new processes then13:29
Keybukso how does Upstart know it's terminating because it's daemonising13:30
Keybukor terminating because of an error?13:30
rjbell4ion: I suspect that should be handled however a "stop" would normally be handled13:30
rjbell4Keybuk: How is that different from 'expect daemon'?  For example, couldn't there be an 'expect 3 daemons'-like functionality?  I might be missing the problem.13:32
rjbell4Oh, BTW, good job with upstart.  I'm actually considering what some colleagues have done with Upstart and wondering if it couldn't be done better / easier.13:33
Keybukbecause that just follows one line of processes13:33
Keybukyou need the mechanism to follow multiple children13:33
Keybukand know when it's reached the stable end13:33
KeybukI'm thinking, from the information you've given, that it's not a hard problem13:33
KeybukI assume that if these children were to exit(0) that'd be ok?13:33
rjbell4Keybuk: I'd actually expect that to happen only as a result of a stop event.  If they terminated any earlier it should be with an error.  Terminating earlier with a 0 exit status "should never happen", so I wouldn't presume to describe what the result should be.13:36
rjbell4Keybuk: re: hard problem.  I suspect it's just extra work to track things.  For the "expect 3 daemons" case, you trace the primary process until it forks, then continue to trace the child process as it forks 3 times, each time adding the child process to the list of processes to monitor for that service.13:37
rjbell4I suppose an argument could be made that this crosses some line and something else should be monitoring more complex models like this, but Upstart just seems to be in the right place to do this.13:39
Keybukno, you're not following13:39
Keybukthe problem is how do you keep count of the forks13:40
Keybuka - b - c13:40
Keybuk     +- d13:40
Keybuk     +- e13:40
Keybuk     +- f13:40
Keybukthat's 5 forks, not 3 ;)13:40
ionHow about this: keep track of *all* children. Whenever one of them exits with a zero exit status and it wasn’t the last process, just remove it from the child list and continue as usual. If one of the dies with a non-zero exit status or due to a signal, consider that an error and kill the other processes (if any). When the last process exits with a zero exit status, consider that a non-error exit.13:43
Keybukion: that's exactly what I was thinking ;-)13:43
rjbell4Keybuk: Right, you're not just keeping track of the forks, but which process forks.  You ptrace a until it forks, then you continue to trace b until it forks 3 times (in this case, for c and d and e, but not f, because you only told Upstart to trace three children)13:44
Keybukion: that fits with the general model I was going for with netlink13:44
rjbell4Keybuk, ion: Sounds reasonable, but since the mechanism is ptrace, that unfortunately rules out running a debugging on any of those processes, right?13:44
Keybukrather than having "the main process" we're in the "running" state with N processes13:44
ionSubstitute zero exit status with the value in “normal exit”13:44
rjbell4^debugging^debugger13:44
Keybukrjbell4: the mechanism is not going to be ptrace for long13:45
Keybukptrace doesn't work13:45
Keybukion: right - normal exit usually only implies 0 if it's a task13:45
rjbell4Keybuk: Oh, well that probably colors my responses then.13:45
Keybukbut it makes sense that normal exit implies 0 if it's a task *or* there are other processes still running13:45
rjbell4Keybuk: You guys know what you are doing better than I do (obviously); I'm just providing feedback from a consumer. :-)13:46
Keybukrjbell4: I think we can definitely make this work for you13:46
rjbell4Keybuk: Out of curiosity, what's the new mechanism planned to be?13:46
Keybukrjbell4: using a Linux feature called the "proc connector"13:47
Keybukit's a netlink socket from which you receive messages for all fork(), exec(), setsid(), setuid(), etc. calls13:47
rjbell4Keybuk: Interesting, thanks for the info.13:49
Keybukptrace has an annoying race condition13:50
Keybukwhen you get the TRAP for fork(), this actually happens in the parent *after* the child process is spawned13:50
Keybukthe child STOPs of course13:50
Keybukbut Upstart ignores that, because it didn't know the pid13:51
ionSay, Upstart receives a message from the proc connector saying ”process 1234 exited with status 1”. While Upstart begins to process that message, 1234’s child, 1235 already exited with exit status 1 and a new, unrelated process happened to start with pid 1235. Upstart happily kills 1235 and then continues to read further messages from proc connector (”process 1235 exited with status 1” etc). Is this remotely possible? (I haven’t looked at how proc ...13:57
ion... connector behaves yet.)13:57
ionkeybuk: Highlight14:09
Keybukhmm14:53
Keybukah14:53
Keybukno, you're forgetting one key detail14:53
Keybukpids aren't reused until you wait() and clean them up14:53
Keybukif the process is a direct child of Upstart, or a daemon that has been reparented to Upstart14:53
Keybuk(pulls up the notes he made about this on his iPhone)14:53
Keybukright14:54
Keybukreceiving a "process 1234 exited" from the proc connector *before* the SIGCHLD means we store a flag14:54
Keybuklikewise receiving a SIGCHLD for process 1234 before we see the proc connector entry means we store the flag14:54
Keybukthen on the opposite one, we actually take action14:54
Keybukin other words, a child of init is not considered dead until we've been told about it *and* seen the body14:55
Keybukat that point, all of its children are implicitly reparented to init14:55
Keybukso again, init would receive SIGCHLD on them as well as the proc connector event14:55
Keybukso provided we wait for the notification and the body, we're safe14:55
Keybuknow there's a race as you say, if the children aren't reparented14:56
Keybukif the tree is14:56
Keybuka14:56
Keybuk `-b14:56
Keybuk `-c14:56
Keybuka is our child, we get SIGCHLD14:56
Keybukbut b isn't, it's a's child14:56
Keybukin that case, I'm not sure that it's up to upstart to supervise b15:08
Keybukthat's b's job ;)15:08
Keybukerr, a's job15:09
Keybukbut if a dies, proc connector means we know about b and c15:09
Keybukso know they're reparented to us15:09
Keybukso Upstart *will* supervise them both15:09
sadmac2Keybuk: is it possible to get information about b from proc connector before a dies?15:10
Keybuksadmac2: yes, proc connector tells us everything15:10
Keybukwe will know that a forked b15:10
Keybukthe exception is if either b or c call setsid(), to put themselves out of a's session15:11
Keybukthe only reason a process would call setsid() is if it *needs* to be the leader of a session15:12
Keybukbecause it wishes to control a tty15:12
Keybuke.g. ssh15:12
Keybukin which case, we deliberately abandon it15:12
Keybukbecause when a (sshd) dies, we don't want to just supervise b and c (ssh-login scott) in their place15:13
Keybukwe want to consider a dying a bad thing15:13
Keybukand we don't want to kill b or c either15:13
sadmac2Keybuk: yes, I was happy when you figured out those bits15:15
sadmac2Keybuk: here's a question: how do things like gnome-session work in upstart-of-tommorow? We don't really want another per-user session manager duplicating most of our effort, do we?15:16
Keybukit's quite easy to just have upstart be the session manager15:17
Keybukthe question turns out to be whether we want pid #1 to be that session manager,15:17
Keybukwhether we want a middle-man session manager running as the user,15:17
sadmac2Keybuk: my thought was gnome-session isn't a process anymore. Its just a taskless state that all the session services depend on15:17
Keybuk  (but everything still gets reparented to #1 anyway)15:17
Keybukor whether we actually want a mini-init for user sessions15:17
Keybuksuch that any user session daemon actually gets reparented to the user session manager15:17
Keybukand make the process trees look pretty15:17
sadmac2Keybuk: can we actually manipulate the reparenting behavior right now?15:18
Keybuknot without a patch Lennart sent to lkml15:19
Keybukhttp://lkml.org/lkml/2009/5/28/43015:19
ionkeybuk: Alright15:20
* sadmac2 now cringes every time exit.c is patched15:20
Keybuklol, why?15:21
sadmac2Keybuk: its like playing Jenga15:21
Keybukit's just the kernel15:21
sadmac2I really do have to find time to just rewrite that whole file15:22
Keybukone of the simpler parts reall15:22
ionhttp://www.youtube.com/watch?v=F9BmTmMEOhQ15:22
sadmac2Keybuk: its particularly poorly written IMHO. if (some return value) { // we have a spinlock } else { //we gave up the spinlock awhile ago } is never a good thing to see15:23
sadmac2ugly code is worse than broken code. Bugs are easier to fix than hideous.15:24
sadmac2Keybuk: so in order to take 0.6 in Fedora, we need to not regress on the state transfer thing.15:30
Keybukdoes the patch apply?15:31
sadmac2Keybuk: and since 0.6 is hopefully forward compatible, that means we need a solution that you've had some architectural say in.15:31
sadmac2Keybuk: the patch might nearly apply (I'd imagine it needs some heavy reworking) but if you're going to do it differently when you do it, its probably best that we do it your way.15:33
ionkeybuk: Btw, now that jobs are in /etc/init without any 0.6 namespacing, how do you plan to have 0.10 handle 0.6 jobs cleanly? :-) I’m still advocating a separate parser for 0.6 jobs that outputs 0.10 job objects.15:35
=== Keybuk_ is now known as Keybuk
sadmac2Keybuk: what's the last thing you got before you dropped?15:36
Keybukion: there's not that much difference in the syntax15:36
Keybuksadmac2: can't remember, what was the last thing I said? :)15:36
sadmac2Keybuk: does the patch apply?15:36
Keybukhaven't tried15:36
sadmac2Keybuk: no, you were asking me15:36
sadmac2:)15:36
sadmac210:35 < sadmac2> Keybuk: so in order to take 0.6 in Fedora, we need to not regress on the state transfer thing.15:37
sadmac210:35 < Keybuk> does the patch apply?15:37
sadmac210:35 < sadmac2> Keybuk: and since 0.6 is hopefully forward compatible, that means we need a solution that you've had some architectural say in.15:37
sadmac210:38 < sadmac2> Keybuk: the patch might nearly apply (I'd imagine it needs some heavy reworking) but if you're going to do it differently when you do it, its probably best that we  do it your way.15:37
sadmac2Keybuk: ^^ that's what lead up to you dropping15:37
Keybuksadmac2: the problem is I don't have a preferred way of doing it yet15:59
Keybukand I glanced through your patch, and I don't see how it can possibly work15:59
Keybukyou don't transfer most of the state15:59
sadmac2Keybuk: its enough. It does depend on the configs lining up.15:59
sadmac2Keybuk: it fixed our broken TTYs anyway16:00
Keybukit isn't enough though16:00
Keybukwhat if a job is mid-starting?16:00
sadmac2Keybuk: bear in mind that I didn't write this. Just reformatted it :)16:00
sadmac2Keybuk: what are we missing for that. We have the state and the pid. The new process should get the signal and move it forward.16:01
Keybukthe event queue?16:01
Keybukthe attached events?16:01
Keybukif there's a "start" command running, you don't transfer the D-Bus message structure from one instance to the other16:02
Keybuk(let along the d-bus connections)16:02
sadmac2Keybuk: yes. that is true...16:02
sadmac2Keybuk: wouldn't it be better to just stop taking input and flush all those out?16:04
sadmac2well, the way blocking is done now you still need the event queue16:04
sadmac2no that won't work yet..16:05
Keybukthe problem is you need to be in a state where all services are running or waiting16:05
Keybukand all tasks are waiting16:05
Keybukit may not be possible to be in that state16:05
sadmac2yeah. I saw it captured the other states but didn't look at what it needed to advance out of them...16:06
sadmac2time to stop trusting patches from strangers16:06
sadmac2Keybuk: wb16:10
ionInstead of /etc/init/dbus-reconnect.conf, why not do telinit q in /etc/init.d/dbus, and then in /etc/init/dbus.conf whenever it’s moved over?16:14
Keybukion: this was a simpler hack16:15
=== robbiew is now known as robbiew-afk
=== robbiew-afk is now known as robbiew

Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!