1

I'm thinking of implementing a high available strategy by forking a process whenever certain signal is triggered. However, I'd like that new process not to be child of the process that executed the fork, but perhaps a child of some other process. This is important, since I need to ensure that this new fork does not die just because the other process did.

I was looking at the differences between fork, ecev, execs, clone, etc here: The difference between fork(), vfork(), exec() and clone()

But still, I'm trying to find a way to clone a running process and get a fork on the go. Any ideas?

Using fork:

process_one
    |
    |
    * ----->forked_process

I'd like the forked_process to be a child of another process, but process_one.

New solution (not sure how to implement it)

Using fork:

process_one
    |
    |
    * -clones-->forked_process

and then

another_process
    |
    |
    * -child-->forked_process
Tony Tannous
  • 14,154
  • 10
  • 50
  • 86
blasrodri
  • 448
  • 5
  • 16
  • 1
    The child process does NOT die if its parent terminate first. – Tony Tannous Jul 10 '20 at 15:33
  • What if parent terminates abnormally? Plus, can the parent keep running normally once it forked a child? – blasrodri Jul 10 '20 at 15:35
  • 1
    The parent and child process are seperated after fork – Tony Tannous Jul 10 '20 at 15:35
  • thanks! And what about this? There are limits to what you can do in the child process. To be totally safe you should restrict yourself to only executing async- signal safe operations until such time as one of the exec functions is called. All APIs, including global data symbols, in any framework or library should be assumed to be unsafe after a fork() unless explicitly documented to be safe or async-signal safe. If you need to use these frameworks in the child process, you must exec. In this situation it is reasonable to exec yourself. What does it mean? – blasrodri Jul 10 '20 at 15:36
  • 1
    The classic approach is a "double fork". You fork once. That child forks a second child and immediately exits. The "grandchild" is then inherited by init. (Or whatever that process is now called.) – William Pursell Jul 10 '20 at 15:41
  • Why is this approach beneficial? – blasrodri Jul 10 '20 at 15:58
  • after a new process is created, parent and child lifes are completely independent. nothing conditions the life of a child because its parent could die. that should be a handicap, so why to implement such a thing? the only relationship that rests after fork is that the parent will accumulate the child times and accounting info when it dies... and that the exit code of the child goes to the parent... (and of course that the parent and the children of it each knows the others) – Luis Colorado Jul 12 '20 at 00:49

1 Answers1

1

You said:

I'm thinking of implementing a high available strategy by forking a process whenever certain signal is triggered.

You had better not to fork() a new process inside a signal handler, as the signal handler executes as an interrupt in user mode, after a system call. This will make your fork() call more difficult to interpret it's return value in the main code. It is possible to do it, but will complicate unnecessary your code.

However, I'd like that new process not to be child of the process that executed the fork, but perhaps a child of some other process.

The request you make is completely impossible to satisfy. fork() just creates a child process in the paren that executed the fork() system cal. That new child process is a child of it, and is in the same state of execution as the parent process was when it called the fork() call (the one that started the fork()) and the child process can only be distinguished from the parent by the return value of fork(), which is 0 for the child, and is the new process id of the child, in the parent. This makes completely impossible to select a parent (or to select which process you want the child to be the parent) as always the parent is the process that starts the call, and the child is the process that receives a return value of the call. I'm sorry but parent adoption is only handled automatically by the kernel, which makes the process with id 1 (this is init or systemd, depending on the system) to adopt automatically a child process when it's parent exit(2)s.

This is important, since I need to ensure that this new fork does not die just because the other process did.

There's no reason that links together the fork() or the parent/child relationship between processes, with the fact that one process has to die because because its parent did. No dying process makes another to die. When a parent process dies, the now orphan process is made a child of the process with id 1. No reason to die. Every process has a parent (always) and every process dies only when a signal is sent to it, or because it explicitly made an exit(2) system call. Process lifes are independent from each other and the death of a process never conditions the life of another.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31