Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move iTerm-server daemon to per-user namespace. Issue 4147 #381

Merged
merged 2 commits into from Jan 30, 2019

Conversation

pradorocchi
Copy link
Contributor

This PR fixes issue 4147

Copy link

@ooglek ooglek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Learned a bunch about macOS, thanks! Pointed out a few spelling/grammar changes. Woot


Issue 4147 happens because the forked daemon is running in the Aqua session namespace. So
when the user logout or a GUI crash happens, the forked daemon remains isolated in a lost
per-session namespace. It partially looses it's IPC capabilities to comunicate with other
Copy link

@ooglek ooglek Jan 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partially loses its ability ... to communicate ...

namespace that already exists [the current one], or any new 'per-session' namespaces that
may in future be (re)created below it.

Important is to mention that it's availability is to serve just the same user (the same UID).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that its availability ...

Important is to mention that it's availability is to serve just the same user (the same UID).
This is what we want, because all other BSD preparations here is done to create the
iTerm-Server to serve just that given user who started it. If another user is logged-in via
GUI via fast user switching, this other user will have it's own Per-User session, and will
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have its own ...

This is what we want, because all other BSD preparations here is done to create the
iTerm-Server to serve just that given user who started it. If another user is logged-in via
GUI via fast user switching, this other user will have it's own Per-User session, and will
have below it his Aqua per-session GUI belonging to it's UID, and his programs running there,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to its UID ...

iTerm-Server to serve just that given user who started it. If another user is logged-in via
GUI via fast user switching, this other user will have it's own Per-User session, and will
have below it his Aqua per-session GUI belonging to it's UID, and his programs running there,
including his own iTerm-Server daemons forked just for it's UID use.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for its UID ...

is never destroyed by GUI logout or crashes. And it will exist until there is at least one
daemon or service running on it, for that given user. [* from Apples documentation]

That's the exact namespace where Launchd places daemons for a given user.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Great writeup and docs!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!!

return; /* All Done! now return, as we are ready to begin forking! */
}
// Never reach. Unless if we had failed to get the parent bootstrap port, which according
// to Apple's documentation never happens. But I already saw rare wierd system situations
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw weird system ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the spelling/grammar changes!
My natural language is Portuguese (I'm from Brazil), some (sometimes a lot of) mistakes happens, :)

// to Apple's documentation never happens. But I already saw rare wierd system situations
// where it may happen.
// Almost impossible, but if it happens, for sure is a BUG. So log it just in case.
FDLog(LOG_ERR,"BUG: Error getting parent BS port! Please report this msg and code: '%x'", kr);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of defensive error logging

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me too, learned the importance of that on my last 9 years working as developer on the asterisk telephony platform. There are a lot of similar BUG situations on that code, and naturally I created this function the way I'm accustomed to do.

Thank you for your appreciation!

@gnachman
Copy link
Owner

This is a fantastic PR! Thank you!

@gnachman gnachman merged commit 85cf962 into gnachman:master Jan 30, 2019
@pradorocchi
Copy link
Contributor Author

This is a fantastic PR! Thank you!

Thank you for creating iTerm2 @gnachman, you deserve the best congratulations!

@pradorocchi
Copy link
Contributor Author

If you want to TEST what kind of session you are, I wrote this simple code that will show the current session you are. I needed to do it during the validation/debug phase of my PR. Here is a simplified version of it.

compile using:
gcc which_namespace.c -o which_namespace

CODE: which_namespace.c

#include <stdio.h>
#include <unistd.h>
#include <vproc.h>

typedef void * vproc_err_t;
typedef struct vproc_s * vproc_t;
typedef enum {
    VPROC_GSK_ZERO,
    VPROC_GSK_LAST_EXIT_STATUS,
    VPROC_GSK_GLOBAL_ON_DEMAND,
    VPROC_GSK_MGR_UID,
    VPROC_GSK_MGR_PID,
    VPROC_GSK_IS_MANAGED,
    VPROC_GSK_MGR_NAME,
    VPROC_GSK_BASIC_KEEPALIVE,
} vproc_gsk_t;

vproc_err_t vproc_swap_integer(vproc_t vp, vproc_gsk_t key, int64_t *inval, int64_t *outval);
vproc_err_t vproc_swap_string(vproc_t vp, vproc_gsk_t key, const char *instr, char **outstr);

int main() {
    int64_t lduid;
    char *manager_name = NULL;

    if (vproc_swap_integer(NULL, VPROC_GSK_MGR_UID, 0, &lduid) != 0) {
        printf("err: vproc_swap_integer -> UID \n"); }

    if (vproc_swap_string(NULL, VPROC_GSK_MGR_NAME, NULL, &manager_name) != 0) {
        printf("err: vproc_swap_string -> SessionName \n"); }

    printf("========================================================\n");
    printf("The Current Boostrap Session Namespace I am running is: \n" );
    printf("--------------------------------------------------------\n");
    printf("  * ManagerSessionUserID: ........ '%lld'\n",lduid);
    printf("  * ManagerSessionName: .......... '%s'\n", manager_name);
    printf("--------------------------------------------------------\n");

    return 0;
}

.

You can use it to test iTerm2 before and after this PR patch.

This is the output before:

prado@MacPro ~/testwork    
> $ ./which_namespace
========================================================
The Current Boostrap Session Namespace I am running is:
--------------------------------------------------------
  * ManagerSessionUserID: ........ '501'
  * ManagerSessionName: .......... 'Aqua'
--------------------------------------------------------

This is the output after this PR patch.

prado@MacPro ~/testwork    
> $ ./which_namespace
========================================================
The Current Boostrap Session Namespace I am running is:
--------------------------------------------------------
  * ManagerSessionUserID: ........ '501'
  * ManagerSessionName: .......... 'Background'
--------------------------------------------------------

@gnachman
Copy link
Owner

Awesome! How did you figure this out?

@pradorocchi
Copy link
Contributor Author

Here is all the information sources I used to achieve this PR

.

Apple Excellent technical note about the intrinsic mechanism of BSD + Mach kernel portions
https://developer.apple.com/library/archive/technotes/tn2083/_index.html

Apple Libc source code
https://opensource.apple.com/source/Libc/Libc-1272.200.26/

MacOS launchctl source code
https://github.com/PureDarwin/XPC/blob/master/src/launchctl/launchctl.c

MacOS 10.14 kernel fork() source code
http://newosxbook.com/src.jl?tree=xnu&file=/bsd/kern/kern_fork.c

Additional researches looking for use cases at :

MacOS 10.14.0 Kernel source code
http://newosxbook.com/src.jl?tree=xnu-4903.221.2

Various system packages source code for Mojave 10.14.1 that deals with process execution
https://opensource.apple.com/release/macos-10141.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants