Re: Reparenting processes?
On Sun 10 Jan 2021 at 16:57:43 -0500, Mouse wrote: > That made no sense to me either. Neither does the test that forbids > process group leaders from setsid()ing. That can at least partially be explained, at least if one rephrases it first as "session leaders are forbidden to setsid()". A process is a session leader if its session id is equal to its process id. This is similar for process groups. Now setsid() creates a new session AND a new process group, and the current process is to be the leader of both. A process that is already a session|group leader of any session|group cannot therefore become the leader of a new session|group. This reasoning works for the POSIX session, which has session ids. The old BSD did not have session ids so part of the reasoning doesn't work directly. But there may be still a prohibition there if a session leader is by necessity also always a process group leader. This indeed seems to be the case, since setsid() makes it so, and a group leader cannot give up its leadership. Now if the setsid() limitation was designed first, and then the ids were designed this way... or the ids were first, and the setsid() limitation was deemed acceptable... that we will have to guess. -Olaf. -- Olaf 'Rhialto' Seibert -- rhialto at falu dot nl ___ Anyone who is capable of getting themselves made President should on \X/ no account be allowed to do the job. --Douglas Adams, "THGTTG" signature.asc Description: PGP signature
output to closed control tty [was Re: Reparenting processes?]
> I'll be testing more with real hardware. I've now tried: 5.2/amd64 with com0 at acpi0 (UAR1, PNP0501-0): io 0x3f8-0x3ff irq 4 com0: ns16550a, working fifo 1.4T/sparc with zs0 at obio0 slot 0 offset 0x10 level 12 softpri 6 zstty1 at zs0 channel 1 In each case, I get EIO with nothing output to the port. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
> I think I have a USB serial port somewhere. I should try that under > 5.2 to see what happens. When pointed at /dev/ttyU0, ctty-test prints ctty-test: test write failed: Input/output error but, curiously, one CRLF does get emitted to /dev/ttyU0. It also leaves it in a peculiar state in which the next character written to it gets lost - or, at least, that's the best short description of what I saw. Specifically, I ran # ctty-test /dev/ttyU0 and I got the EIO indication (plus "exit 1" because of the "setsid broken for pgrp leaders" workaround) and a CRLF sent down the serial line. Then I ran serialconsole, a program of mine which is designed to talk to, well, serial consoles, but which can also be used as a way to just talk to a tty. Using that, I then typed "xyz" at it. The x disappeared; the y and z showed up as normal. Further typing appears to work normally. Apparently 5.2's ucom's write routine does not work right when the device is not actually open. Given how complex USB is, this does not surprise me; what surprises me is that _anything_ gets through, and the peculiar character-eating state it gets left in. It does make me glad I did that test on a machine for which a crash or hang would not have been more than a minor inconvenience; there clearly are issues with at least some serial port drivers under this circumstance. If someone can reproduce this under 9.1, perhaps filing a PR would be a good idea? I'll be testing more with real hardware. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
>> This makes me wonder if perhaps login sessions should have their >> stdin/stdout/stderr set up on /dev/tty instead of the actual ctty >> device. > Interesting. Need to think about that... One thing I can remark on already: tty(1) and ttyname(3) become less useful, at least as they are currently implemented. When I run $SHELL with stdin, stdout, and stderr connected to /dev/tty, then tty(1), which is basically just a thin wrapper around ttyname(3), prints /dev/tty on 1.4T, and does so on 5.2 except for ptys (the exception because of an apparent optimization attempt in ttyname(3)). I'm not sure whether I think tty(1) and/or ttyname(3) should drill through /dev/tty and find the real tty; I can see arguments each way. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
>> I've got the test program written. On 5.2/amd64 with /dev/ttyE1 as >> the test tty (no getty running on it, of course), output works just >> fine [...] > I tried it too, on 9.1 amd64, and that worked too. I did not expect > that. While trying to write down why I thought that, I got even more > confused for a while, because there is stuff going on both with > vnodes for the ctty, and pointers to its struct tty, and they are not > handled together. True. > I'm looking at current-ish source, but I suppose this hardly ever > changes. I agree, because the code you quote looks a whole lot like the corresponding 5.2 code, including the split of TIOCSCTTY's functionality between tty.c and vfs_vnops.c. > I wonder what happens if a USB serial port is the ctty and it gets > removed... probably a dangling pointer. I think I have a USB serial port somewhere. I should try that under 5.2 to see what happens. Some parts of the tty code likely date from before dynamic detach and thus may not handle it well > so you can conceivably set a FIFO or a block device or a random raw > disk also as controlling tty? If its ioctl routine accepts TIOCSCTTY, yes. I would almost say that accepting TIOCSCTTY is the defining characteristic of things capable of becoming cttys...though not quite, because without a struct tty, it gets a bit confused. I suppose something accepting TIOCSCTTY without setting s_ttyp simply counts as a driver bug > Why the code for TIOCSCTTY is split in two parts remains unclear. To put it mildly! :-) > Maybe the existence of this split explains why session leaders are > not allowed to relinquish their ctty using TIOCNOTTY That made no sense to me either. Neither does the test that forbids process group leaders from setsid()ing. > [Stevens] "Advanced Programming in the UNIX Environment" from Stevens > is more explanatory about sessions etc (but it also says that BSD has > no session IDs, but by now NetBSD clearly does have them). At the time, I think, BSD did not have them. My impression is that POSIX created them by fiat, though presumably it actually drew them from somewhere. I'm not sure whether I think sessions are a good thing or not. > "... the hang-up signal is sent to the controlling process (the > session leader)" Really? I thought tty-generated SIGHUPs were sent to all processes in the tty's pgrp, regardless of sessions. Perhaps I need to go read more code. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
On Sun 10 Jan 2021 at 10:25:10 -0500, Mouse wrote: > I've got the test program written. On 5.2/amd64 with /dev/ttyE1 as the > test tty (no getty running on it, of course), output works just fine > (this doesn't surprise me; I find it plausible that wscons tty > open/close are pretty much no-ops aside from possible permissions > checking on open). I tried it too, on 9.1 amd64, and that worked too. I did not expect that. While trying to write down why I thought that, I got even more confused for a while, because there is stuff going on both with vnodes for the ctty, and pointers to its struct tty, and they are not handled together. (I also tried on Linux Ubuntu 20.10 and that worked too... just needed a small change to compile) I'm looking at current-ish source, but I suppose this hardly ever changes. This in /sys/kern/tty_tty.c works with vnodes: #define cttyvp(p) ((p)->p_lflag & PL_CONTROLT ? (p)->p_session->s_ttyvp : NULL) static int cttywrite(dev_t dev, struct uio *uio, int flag) { struct vnode *ttyvp = cttyvp(curproc); int error; if (ttyvp == NULL) return (EIO); vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); error = VOP_WRITE(ttyvp, uio, flag, NOCRED); VOP_UNLOCK(ttyvp); return (error); } and of course my expectation was that this vnode pointer would be NULLed out somehow when the process closes the tty. In /sys/kern/tty.c, for TIOCSCTTY, there is no vnode pointer being set (s_ttyvp !) but only a struct tty * (s_ttyp !). I see no added reference count on the struct tty * for the tty that is about to become a ctty. I wonder what happens if a USB serial port is the ctty and it gets removed... probably a dangling pointer. case TIOCSCTTY: /* become controlling tty */ mutex_enter(_lock); mutex_spin_enter(_lock); /* Session ctty vnode pointer set in vnode layer. */ if (!SESS_LEADER(p) || ((p->p_session->s_ttyvp || tp->t_session) && (tp->t_session != p->p_session))) { mutex_spin_exit(_lock); mutex_exit(_lock); return (EPERM); } /* * `p_session' acquires a reference. * But note that if `t_session' is set at this point, * it must equal `p_session', in which case the session * already has the correct reference count. */ if (tp->t_session == NULL) { proc_sesshold(p->p_session); } tp->t_session = p->p_session; tp->t_pgrp = p->p_pgrp; p->p_session->s_ttyp = tp; // struct tty *tp p->p_lflag |= PL_CONTROLT; mutex_spin_exit(_lock); mutex_exit(_lock); break; strangely enough, I finally found the setting of p->p_session->s_ttyvp in kern/vfs_vnops.c: case VFIFO: case VCHR: case VBLK: error = VOP_IOCTL(vp, com, data, fp->f_flag, kauth_cred_get()); if (error == 0 && com == TIOCSCTTY) { vref(vp); mutex_enter(_lock); ovp = curproc->p_session->s_ttyvp; curproc->p_session->s_ttyvp = vp; mutex_exit(_lock); if (ovp != NULL) vrele(ovp); } return (error); so you can conceivably set a FIFO or a block device or a random raw disk also as controlling tty? At least it does reference counting here. Why the code for TIOCSCTTY is split in two parts remains unclear. I searched for other devices to handle the lower half of it and found none (it wouldn't make sense anyway). Neither is [4.3BSD] "The Design and Implementation of the 4.3BSD UNIX Operating System" illuminating; its chapter 9 on Terminal handling hardly mentions details about process groups, and sessions not at all. [FBSD] "The Design and Implementation of the FreeBSD Operating System (Version 5.2)" at least briefly describes sessions (section 10.5) but doesn't explain any of this either. Maybe the existence of this split explains why session leaders are not allowed to relinquish their ctty using TIOCNOTTY (because it messes with the current reference counting): kern/tty_tty.c: cttyioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { struct vnode *ttyvp = cttyvp(l->l_proc); ... if (cmd == TIOCNOTTY) { mutex_enter(_lock); if (!SESS_LEADER(l->l_proc)) { l->l_proc->p_lflag &= ~PL_CONTROLT; rv = 0; } else rv = EINVAL; mutex_exit(_lock); return (rv);
Re: Reparenting processes?
> The case I'm wondering about is: > - open real tty > - make it the control tty > - open /dev/tty > - close the real tty > - read/write the /dev/tty fd > It looks to me as though this could lead to the underlying tty driver > getting a read/write call when, according to its open/close calls, > it's not open. I've got the test program written. On 5.2/amd64 with /dev/ttyE1 as the test tty (no getty running on it, of course), output works just fine (this doesn't surprise me; I find it plausible that wscons tty open/close are pretty much no-ops aside from possible permissions checking on open). I'm going to test with real hardware on 5.2/amd64 and 1.4T/sparc, but those will not be happening as immediately. The test program is in ftp.rodents-montreal.org:/mouse/misc/ctty-test.c in case anyone wants to try it on other versions or other hardware. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
>> It actually occurs to me that this is a potential problem even >> today: what happens if all the processes in a session close the >> descriptors they have on the ctty, and there are no others lying >> around in other [...] > or similarly, if they TIOCNOTTY it (although tty(4) tells me it's > obsolete) That would be testing something else. The case where a process has no ctty is comparatively well understood. I'm wondering about the case where a process has a ctty but the real ctty device is not open. > I think sys/kern/tty_tty.c is the implementation of /dev/tty, and it > seems you get ENXIO. That's what I see for open on /dev/tty if there is no ctty. (I/O on /dev/tty when there's no ctty returns EIO in the code I have at hand.) The case I'm wondering about is: - open real tty - make it the control tty - open /dev/tty - close the real tty - read/write the /dev/tty fd It looks to me as though this could lead to the underlying tty driver getting a read/write call when, according to its open/close calls, it's not open. I suspect it's a case that has never been tested; indeed, until this discussion, the possibility had never occurred to me. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
On Sun 10 Jan 2021 at 09:44:18 -0500, Mouse wrote: > >> This makes me wonder if perhaps login sessions should have their > >> stdin/stdout/stderr set up on /dev/tty instead of the actual ctty > >> device. But if that's done, will the `real' ctty device even be > >> open? [...] > > It actually occurs to me that this is a potential problem even today: > what happens if all the processes in a session close the descriptors > they have on the ctty, and there are no others lying around in other or similarly, if they TIOCNOTTY it (although tty(4) tells me it's obsolete) > processes, and then one of those processes tries to access /dev/tty? > It would be an unusual session, true, but there's nothing preventing it > from happening as far as I can see. Would the underlying tty driver > explode upon getting I/O calls when it isn't open, or what? I think sys/kern/tty_tty.c is the implementation of /dev/tty, and it seems you get ENXIO. Also each read/write call goes to the *current* controlling tty, freshly looked up. > /~\ The ASCII Mouse -Olaf. -- Olaf 'Rhialto' Seibert -- rhialto at falu dot nl ___ Anyone who is capable of getting themselves made President should on \X/ no account be allowed to do the job. --Douglas Adams, "THGTTG" signature.asc Description: PGP signature
Re: Reparenting processes?
>> This makes me wonder if perhaps login sessions should have their >> stdin/stdout/stderr set up on /dev/tty instead of the actual ctty >> device. But if that's done, will the `real' ctty device even be >> open? [...] It actually occurs to me that this is a potential problem even today: what happens if all the processes in a session close the descriptors they have on the ctty, and there are no others lying around in other processes, and then one of those processes tries to access /dev/tty? It would be an unusual session, true, but there's nothing preventing it from happening as far as I can see. Would the underlying tty driver explode upon getting I/O calls when it isn't open, or what? I think I'll build a test program that does this: does setsid(), opens a tty (which would have to not be open by anything else, for the test to be useful), does TIOCSCTTY, opens /dev/tty, closes all its descriptors on the real tty, then accesses its /dev/tty descriptor /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
>> This makes me wonder if perhaps login sessions should have their >> stdin/stdout/stderr set up on /dev/tty instead of the actual ctty >> device. But if that's done, will the `real' ctty device even be >> open? [...] > Interesting. Need to think about that... All I've come up with so far is that maybe a session should hold an open on its ctty. It would address this issue, but would it produce others? None come to mind offhand, but then, I didn't think of the file descriptor issues until I got halfway through implementing reparenting /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
On Sat, Jan 09, 2021 at 08:33:27AM -0500, Mouse wrote: > Waking up this thread from about a month ago > > [...] > > This makes me wonder if perhaps login sessions should have their > stdin/stdout/stderr set up on /dev/tty instead of the actual ctty > device. But if that's done, will the `real' ctty device even be open? > I think /dev/tty doesn't keep an open on the underlying tty device, nor > can I see any easy way for it to do so, since /dev/tty itself doesn't > get a close call until no process in the whole system, not just no > process with that ctty, has a descriptor open on /dev/tty. > > I'm not convinced there is a single right answer. I'm writing to ask > if anyone here has any thoughts to share on these issues. Interesting. Need to think about that... -- David A. Holland dholl...@netbsd.org
Re: Reparenting processes?
Waking up this thread from about a month ago >>> [...process reparenting...] >> [...auto-reparenting to init...] > [...] most of the code I want already exists. > The pieces that don't are things like dealing with control ttys and > sessions [...] Yesterday and today, I picked this up and started to write code. I've got most of it, I think. But there's a piece that prompts me to write back here. Dealing with most of it is easy. The reparenting proper is already done, both for ptrace and for orphans moving to init. Switching the process's pgrp to a new session isn't that hard, and that automatically switches controlling tty (since a process's ctty is obtained by chasing through p->p_pgrp->pg_session->s_tty{,v}p). The hard part is file descriptors. Most processes typically have a few file descriptors (usually 0, 1, 2) open on their controlling tty. But they aren't open on /dev/tty; they're open on /dev/tty01, /dev/ttya, /dev/ttyE2, /dev/ttyp4, or whatever, so just changing ctty won't move them. Leaving them connected to the old tty, which is no longer the process's session's ctty, seems wrong; if nothing else, generated output will go to the wrong tty (or cause an "incorrect" SIGTTOU). I can, perhaps, drill down through the data structures and switch them to the new ctty, but then there's a problem: what if a fd on the old ctty was opened not because it was the login tty inherited from however the login session was created, but was opened explicitly (either by the shell or by the process)? (The case where the new session has no ctty I'm willing to EINVAL on; my movating use cases always have cttys.) This makes me wonder if perhaps login sessions should have their stdin/stdout/stderr set up on /dev/tty instead of the actual ctty device. But if that's done, will the `real' ctty device even be open? I think /dev/tty doesn't keep an open on the underlying tty device, nor can I see any easy way for it to do so, since /dev/tty itself doesn't get a close call until no process in the whole system, not just no process with that ctty, has a descriptor open on /dev/tty. I'm not convinced there is a single right answer. I'm writing to ask if anyone here has any thoughts to share on these issues. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
On Tue, Dec 8, 2020 at 16:06 bch wrote: > > > On Tue, Dec 8, 2020 at 15:36 bch wrote: > >> >> >> On Tue, Dec 8, 2020 at 13:05 Mouse wrote: >> >>> >> [...process reparenting...] >>> > Isn't what you want to do very similar to what happens when a process >>> > goes into background and the parent dies? >>> >>> Yes. Between that and the partial reparenting that happens at debugger >>> attach, most of the code I want already exists. >>> >>> The pieces that don't are things like dealing with control ttys and >>> sessions (reparenting orphaned processes to init deals with those, but >>> only in the form of setting them to a suitable "cleared" state; I would >>> want something more). >> >> >> >> ISTR NetBSD shipped (ships? I can’t find it on cursory glance) a >> slimmed-down process controller (“slimmed-down” vs tmux or screen w their >> myriad options and features) process handler - I want to say “detach”, but >> I’m not certain. >> > > Or “window”? What I’m remembering was definitely for a console, though, > and super basic. > Apologies for replying to my own msgs. The software I was thinking of is window(1), which for NetBSD 7 was taken out of base and moved to pkgsrc/misc/window, according to src/doc/CHANGES.prev -bch > >> -bch >> >> >>> >>> /~\ The ASCII Mouse >>> \ / Ribbon Campaign >>> X Against HTMLmo...@rodents-montreal.org >>> / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B >>> >>
Re: Reparenting processes?
On Tue, Dec 8, 2020 at 15:36 bch wrote: > > > On Tue, Dec 8, 2020 at 13:05 Mouse wrote: > >> >> [...process reparenting...] >> > Isn't what you want to do very similar to what happens when a process >> > goes into background and the parent dies? >> >> Yes. Between that and the partial reparenting that happens at debugger >> attach, most of the code I want already exists. >> >> The pieces that don't are things like dealing with control ttys and >> sessions (reparenting orphaned processes to init deals with those, but >> only in the form of setting them to a suitable "cleared" state; I would >> want something more). > > > > ISTR NetBSD shipped (ships? I can’t find it on cursory glance) a > slimmed-down process controller (“slimmed-down” vs tmux or screen w their > myriad options and features) process handler - I want to say “detach”, but > I’m not certain. > Or “window”? What I’m remembering was definitely for a console, though, and super basic. > -bch > > >> >> /~\ The ASCII Mouse >> \ / Ribbon Campaign >> X Against HTMLmo...@rodents-montreal.org >> / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B >> >
Re: Reparenting processes?
On Tue, Dec 8, 2020 at 13:05 Mouse wrote: > >> [...process reparenting...] > > Isn't what you want to do very similar to what happens when a process > > goes into background and the parent dies? > > Yes. Between that and the partial reparenting that happens at debugger > attach, most of the code I want already exists. > > The pieces that don't are things like dealing with control ttys and > sessions (reparenting orphaned processes to init deals with those, but > only in the form of setting them to a suitable "cleared" state; I would > want something more). ISTR NetBSD shipped (ships? I can’t find it on cursory glance) a slimmed-down process controller (“slimmed-down” vs tmux or screen w their myriad options and features) process handler - I want to say “detach”, but I’m not certain. -bch > > /~\ The ASCII Mouse > \ / Ribbon Campaign > X Against HTMLmo...@rodents-montreal.org > / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B >
Re: Reparenting processes?
>> [...process reparenting...] > Isn't what you want to do very similar to what happens when a process > goes into background and the parent dies? Yes. Between that and the partial reparenting that happens at debugger attach, most of the code I want already exists. The pieces that don't are things like dealing with control ttys and sessions (reparenting orphaned processes to init deals with those, but only in the form of setting them to a suitable "cleared" state; I would want something more). /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
hello. Isn't what you want to do very similar to what happens when a process goes into background and the parent dies? I.e. its parent gets reassigned to init, pid 1. That's a special case, but it seems like you could create a syscall that does that work and as long as the target parent is the same uid as the calling process, you should be able to re-use a lot of the code that does that inheritance for backrounded processes. Then, when the new parent does a wait, it just gets the pid of the newly transfered child, assuming the child exits at some point. Just a thought. -Brian On Dec 8, 2:36pm, Mouse wrote: } Subject: Re: Reparenting processes? } > One complication I can think of: what happens to the original parent process$ } } If the original parent is not in a wait() at the time, I don't see this } as an issue; the child just evaporates. (See below.) } } If the original parent is in a wait(), and this is either its last } child or it is specifically being waited for (either by pid or pgid), } I'm not sure. I'd have to think about that. Possibly a new wait } status (WIFREPARENTED?). Possibly it just turns into whatever would } have happened if the wait*() had been done immediately after the } reparenting. Possibly something else. } } The new parent learning about the new child is not something I've been } worried about, because what I've been imagining requires active } collaboration between the old and new parents for the move to happen at } all, meaning that each parent is expecting the change and can update } whatever internal data structures it needs to. } } Yes, post-reparenting, the new parent can wait for the child just like } any other child it (then) has. } } /~\ The ASCII Mouse } \ / Ribbon Campaign } X Against HTML mo...@rodents-montreal.org } / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B >-- End of excerpt from Mouse
Re: Reparenting processes?
> One complication I can think of: what happens to the original parent process$ If the original parent is not in a wait() at the time, I don't see this as an issue; the child just evaporates. (See below.) If the original parent is in a wait(), and this is either its last child or it is specifically being waited for (either by pid or pgid), I'm not sure. I'd have to think about that. Possibly a new wait status (WIFREPARENTED?). Possibly it just turns into whatever would have happened if the wait*() had been done immediately after the reparenting. Possibly something else. The new parent learning about the new child is not something I've been worried about, because what I've been imagining requires active collaboration between the old and new parents for the move to happen at all, meaning that each parent is expecting the change and can update whatever internal data structures it needs to. Yes, post-reparenting, the new parent can wait for the child just like any other child it (then) has. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
> On Dec 8, 2020, at 8:01 AM, i...@netbsd.org wrote: > > > [EXTERNAL EMAIL] > > On Mon, Dec 07, 2020 at 08:54:33PM -0500, Mouse wrote: >> I've been thinking about building a way to move a job between shells, >> in particular between one window, ssh session, whatever, and another. > > Yes, I've somehow missed the VMS virtual terminals, that can detach > their job from the real terminal and be reattached by a login process, > instead of creating a new job. I didn't know that VMS had this, but certainly you can find that feature in the DEC PDP-11 operating system RSTS/E. And that may have been borrowed from older OSs like TSS-8 or TOPS-10. One complication I can think of: what happens to the original parent process wait for child exit syscall, if the child detaches? I assume it returns; does it return with a new completion value that means "the process isn't actually done but it detached"? Similarly, how does the new parent learn about the new child, and can it then wait for it? paul
Re: Reparenting processes?
On 2020-12-08 14:36, Mouse wrote: I've been thinking about building a way to move a job between shells, in particular between one window, ssh session, whatever, and another. Yes, I've somehow missed the VMS virtual terminals, that can detach their job from the real terminal and be reattached by a login process, instead of creating a new job. That must have come in after I stopped using VMS (mid-'80s); I'm pretty sure the VMS I used didn't have it. It actually don't have anything to do with virtual terminals, but the mechanism did exist already then. Jobs could be detached and reattached again, including at login. But it was/is a little obscure in VMS. It is much more prominent, and easy to deal with in TOPS-20. (Now back to on topic... :-) ) Johnny -- Johnny Billquist || "I'm on a bus || on a psychedelic trip email: b...@softjar.se || Reading murder books pdp is alive! || tryin' to stay hip" - B. Idol
Re: Reparenting processes?
>> I've been thinking about building a way to move a job between >> shells, in particular between one window, ssh session, whatever, and >> another. > Yes, I've somehow missed the VMS virtual terminals, that can detach > their job from the real terminal and be reattached by a login > process, instead of creating a new job. That must have come in after I stopped using VMS (mid-'80s); I'm pretty sure the VMS I used didn't have it. > (screen and tmux have lessened this desire to a high degree.) Not surprising. :-) >> But the real bugaboo in my mind is reparenting processes. > Why do you need this? I think that (get|set)pg(rp|id)() and > tcgetpgrp()/tcsetpgrp() should be enough to do job manipulation. Reparenting is semi-necessary in order for wait*() to work right. Also, if you can move a stopped setuid job, the carveout for sending SIGCONT to any descendant needs to apply. And the job's control tty needs to change so it can interact with the tty expected by the new shell. It probably should change session, too. >> The other is: is there any security property that such a facility >> would break badly? > One that I can think of: if you are able to change your parent to one > of your indirect children, functions traversing the process tree > would either not find you (and your decendants) or run in an infinite > loop. Certainly; I was expecting to forbid parenting loops. (This is one of the respects in which ptrace()'s reparenting is only partial; debuggers can attach to their process-tree ancestors just fine.) > The other interesting question: what happens to a process that was > seperated by its child but still knows the id and plans some > operation on it? For my use cases, that is a non-issue; I expect this to happen only with the cooperation and collaboration of both parents. The old parent can operate on the former child after the move only to the extent that it could operate on a similar child forked by the new parent. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: Reparenting processes?
On Mon, Dec 07, 2020 at 08:54:33PM -0500, Mouse wrote: > I've been thinking about building a way to move a job between shells, > in particular between one window, ssh session, whatever, and another. Yes, I've somehow missed the VMS virtual terminals, that can detach their job from the real terminal and be reattached by a login process, instead of creating a new job. (screen and tmux have lessened this desire to a high degree.) > Obviously, this will involve much hackery of existing facilities. For > example, it involves switching controlling terminals. I expect I can > manage most of it without too much trouble - though that's said without > having actually tried it. > > But the real bugaboo in my mind is reparenting processes. Why do you need this? I think that (get|set)pg(rp|id)() and tcgetpgrp()/tcsetpgrp() should be enough to do job manipulation. > The other is: is there any security property that such a facility would > break badly? One that I can think of: if you are able to change your parent to one of your indirect children, functions traversing the process tree would either not find you (and your decendants) or run in an infinite loop. (Needs traversing the new parent's parent chain up, make sure the moving process is not there, (and maybe for good measure, that we arrive at 1), all with a lock held.) The other interesting question: what happens to a process that was seperated by its child but still knows the id and plans some operation on it? -is
Re: Reparenting processes?
hello. Dependning on why you're doing this and what you're running, I wonder if either screen(1) using the detach feature will do what you want, or if tmux(1) using a similar detach feature will do what you want. They don't actually reparent, but do allow you to log out of one shell and then log into another and reattach the session you had running before you logged out initially. -Brian On Dec 7, 8:54pm, Mouse wrote: } Subject: Reparenting processes? } I've been thinking about building a way to move a job between shells, } in particular between one window, ssh session, whatever, and another. } } Obviously, this will involve much hackery of existing facilities. For } example, it involves switching controlling terminals. I expect I can } manage most of it without too much trouble - though that's said without } having actually tried it. } } But the real bugaboo in my mind is reparenting processes. } } I'm writing here to ask two questions. } } One is: does anyone have experience trying this, or otherwise have any } reports on attempts to do this, to share? I'd be interested in any. } } The other is: is there any security property that such a facility would } break badly? (There are lots of minor things that might break, such as } potentially changing terminal type, but that's basically no different } from telling the terminal emulator to change emulation on the fly, } which my terminal emulator has been capable of for decades. I haven't } come up with any major security issues yet, but that means little.) } } I'm willing to require - indeed, I expect to _want_ to require - that } the two parents (old and new) be cooperating in this endeavour. I'm } willing to require that all three processes be running with the same } root, though it'd be nice if that weren't necessary. It would address } some, though not all, of the desired use cases if all three processes } have to be running with the same UID. It would even be of _some_ use } if it required cooperation from root in some form (a fourth process, } maybe?). } } As far as I can tell, reparenting currently is limited to (1) init } inheriting orphans and (2) sharply limited partial reparenting due to } ptrace(). } } /~\ The ASCII Mouse } \ / Ribbon Campaign } X Against HTML mo...@rodents-montreal.org } / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B >-- End of excerpt from Mouse
Re: Reparenting processes?
On Mon, Dec 7, 2020 at 8:55 PM Mouse wrote: > > I've been thinking about building a way to move a job between shells, > in particular between one window, ssh session, whatever, and another. > > Obviously, this will involve much hackery of existing facilities. For > example, it involves switching controlling terminals. I expect I can > manage most of it without too much trouble - though that's said without > having actually tried it. > > But the real bugaboo in my mind is reparenting processes. > > I'm writing here to ask two questions. > > One is: does anyone have experience trying this, or otherwise have any > reports on attempts to do this, to share? I'd be interested in any. > > The other is: is there any security property that such a facility would > break badly? (There are lots of minor things that might break, such as > potentially changing terminal type, but that's basically no different > from telling the terminal emulator to change emulation on the fly, > which my terminal emulator has been capable of for decades. I haven't > come up with any major security issues yet, but that means little.) > > I'm willing to require - indeed, I expect to _want_ to require - that > the two parents (old and new) be cooperating in this endeavour. I'm > willing to require that all three processes be running with the same > root, though it'd be nice if that weren't necessary. It would address > some, though not all, of the desired use cases if all three processes > have to be running with the same UID. It would even be of _some_ use > if it required cooperation from root in some form (a fourth process, > maybe?). > > As far as I can tell, reparenting currently is limited to (1) init > inheriting orphans and (2) sharply limited partial reparenting due to > ptrace(). Is there a reason screen or tmux don't work for you?
Reparenting processes?
I've been thinking about building a way to move a job between shells, in particular between one window, ssh session, whatever, and another. Obviously, this will involve much hackery of existing facilities. For example, it involves switching controlling terminals. I expect I can manage most of it without too much trouble - though that's said without having actually tried it. But the real bugaboo in my mind is reparenting processes. I'm writing here to ask two questions. One is: does anyone have experience trying this, or otherwise have any reports on attempts to do this, to share? I'd be interested in any. The other is: is there any security property that such a facility would break badly? (There are lots of minor things that might break, such as potentially changing terminal type, but that's basically no different from telling the terminal emulator to change emulation on the fly, which my terminal emulator has been capable of for decades. I haven't come up with any major security issues yet, but that means little.) I'm willing to require - indeed, I expect to _want_ to require - that the two parents (old and new) be cooperating in this endeavour. I'm willing to require that all three processes be running with the same root, though it'd be nice if that weren't necessary. It would address some, though not all, of the desired use cases if all three processes have to be running with the same UID. It would even be of _some_ use if it required cooperation from root in some form (a fourth process, maybe?). As far as I can tell, reparenting currently is limited to (1) init inheriting orphans and (2) sharply limited partial reparenting due to ptrace(). /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B