James Hunt has proposed merging lp:~jamesodhunt/upstart/bug-901038 into lp:upstart.
Requested reviews: Upstart Reviewers (upstart-reviewers) Related bugs: Bug #901038 in upstart (Ubuntu): "packages fail to install: Failed to connect to socket /com/ubuntu/upstart: Connection refused" https://bugs.launchpad.net/ubuntu/+source/upstart/+bug/901038 For more details, see: https://code.launchpad.net/~jamesodhunt/upstart/bug-901038/+merge/231705 -- https://code.launchpad.net/~jamesodhunt/upstart/bug-901038/+merge/231705 Your team Upstart Reviewers is requested to review the proposed merge of lp:~jamesodhunt/upstart/bug-901038 into lp:upstart.
=== modified file 'ChangeLog' --- ChangeLog 2014-08-14 11:19:43 +0000 +++ ChangeLog 2014-08-21 11:02:59 +0000 @@ -1,3 +1,10 @@ +2014-08-21 James Hunt <james.h...@ubuntu.com> + + * util/telinit.c: restart_upstart(): + - Revert to synchronous behaviour coupled with unavoidable + poll to ensure telinit only returns once a re-exec has + completed (LP: #901038). + 2014-08-14 James Hunt <james.h...@ubuntu.com> * init/control.c: Disallow modifying system jobs via SetEnv, === modified file 'util/telinit.c' --- util/telinit.c 2014-03-10 13:43:50 +0000 +++ util/telinit.c 2014-08-21 11:02:59 +0000 @@ -160,27 +160,81 @@ int restart_upstart (void) { - nih_local NihDBusProxy *upstart = NULL; - DBusPendingCall *ret; + nih_local NihDBusProxy *upstart = NULL; + NihError *err; + int ret; upstart = upstart_open (NULL); if (! upstart) return -1; - /* Fire and forget: - * - * Ask Upstart to restart itself using the async interface to - * avoid the client-side complaining if and when it detects that - * Upstart has severed all connections to perform the re-exec. - */ - ret = upstart_restart (upstart, NULL, NULL, NULL, 0); - dbus_connection_flush(upstart->connection); - - /* We don't care about the return code, but we have to keep - * the compiler happy. - */ - if (ret != (DBusPendingCall *)TRUE) - return 0; + /* Ask Upstart to restart itself. + * + * Since it is not possible to serialise a D-Bus connection, + * Upstart is forced to sever all D-Bus client connections, + * including this one. + * + * Further, since the user expects telinit to block _until the + * re-exec has finished and Upstart is accepting connections + * once again_, the only solution is to wait for the forced + * disconnect, then poll until it is possible to create a new + * connection. + * + * Note that we don't (can't) care about the return code since + * it's not reliable: + * + * - either the re-exec request completed and D-Bus returned zero + * before Upstart started the re-exec. + * + * - or the re-exec request completed but upstart started the + * re-exec (severing all D-Bus connections) before D-Bus got a + * chance to finish cleanly meaning we receive a return of -1. + * + * We cannot know exactly what happened so have to allow for + * both scenarios. Note the implicit assumption that the re-exec + * request itself was accepted. If this assumption is incorrect + * (should not be possible), the worst case scenario is that + * upstart does not re-exec and then we quickly drop out of the + * reconnect block since it never went offline. + */ + ret = upstart_restart_sync (NULL, upstart); + + if (getenv ("UPSTART_TELINIT_U_NO_WAIT")) { + /* Get-out-of-jail-free card - should never be required, but + * paranoia never hurt anyone and we strive to provide + * backwards-compatibility where possible. + */ + return ret; + } + + if (ret < 0) { + err = nih_error_get (); + nih_free (err); + } + + nih_free (upstart); + + nih_debug ("Waiting for upstart to finish re-exec"); + + /* We believe Upstart is now in the process of + * re-exec'ing so attempt forever to reconnect. + * + * This sounds dangerous but there is no other option, + * and a connection must be possible unless the system + * is completely broken. + */ + while (TRUE) { + + upstart = upstart_open (NULL); + if (upstart) + break; + + err = nih_error_get (); + nih_free (err); + + /* Avoid DoS'ing the system whilst we wait */ + usleep (100000); + } return 0; }
-- upstart-devel mailing list upstart-devel@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel