Reputation: 957
Last days i am kinda struggling with forking a process and kill the parent from the forked one(child)
I don't know why but it seems not to kill the parent at all. first i tough it where the open connections that keeps the process running because of the graceful shutdown process, But its not that issue.
if i send SIGTERM to the parent from the terminal it worked perfect, but when the child send SIGTERM it does not stop, force quitting is no option cause of graceful shutdown.
edit * the processes are still in the process list. Maybe that is for parent to track its children?
Some code that does the fork, maybe i do something wrong here
func (s *Server) Upgrade() error {
tl := s.listener.(*listener)
addr := s.listener.Addr()
name := fmt.Sprintf("%s:%s->", addr.Network(), addr.String())
os.Setenv("PROX_NAME", name)
fl, err := tl.File()
if err != nil {
return fmt.Errorf("Failed to extract file desciptor, %v", err)
}
fd := fl.Fd()
argv0, err := exec.LookPath(os.Args[0])
if err != nil {
return fmt.Errorf("Failed to execute lookpath, %v", err)
}
noCloseOnExec(fd)
files := make([]*os.File, fd+1)
files[syscall.Stdin] = os.Stdin
files[syscall.Stdout] = os.Stdout
files[syscall.Stderr] = os.Stderr
files[fd] = os.NewFile(fd, name)
wd, err := os.Getwd()
if err != nil {
return err
}
os.Setenv("GPROXY_FD", fmt.Sprintf("%d", fd))
os.Setenv("GPROXY_PID", fmt.Sprintf("%d", syscall.Getpid()))
args := []string{"gproxy", "-debug", "start"}
_, err = os.StartProcess(argv0, args, &os.ProcAttr{
Dir: wd,
Env: os.Environ(),
Files: files,
})
return err
}
the termination of the parent
func termParentProcess() error {
pid := syscall.Getppid()
return syscall.Kill(pid, syscall.SIGTERM)
}
Upvotes: 0
Views: 2042
Reputation: 957
The problem my parent process wont terminate on a TERM signal is because of a inner for loop that wont break. I fixed the for loop and let the main function return. If in Go the main returns the program exits. sorry for bothering you guys with a big mistake of myself
Upvotes: 1
Reputation: 99195
Long story short, you can't fork, there's a very old and ongoing issue for it here.
You could use something like https://github.com/icattlecoder/godaemon but the parent will have to terminate itself not the child.
var isChild = flag.Bool("child", false, "parent pid")
func main() {
flag.Parse()
var s string
if !*isChild { //parent
fmt.Println("forking")
files := make([]*os.File, 3)
files[syscall.Stdin] = os.Stdin
files[syscall.Stdout] = os.Stdout
files[syscall.Stderr] = os.Stderr
fmt.Println(os.StartProcess(os.Args[0], append(os.Args, "-child"), &os.ProcAttr{
Dir: "/tmp",
Env: os.Environ(),
Files: files,
}))
fmt.Scan(&s) // block
} else {
ppid := os.Getppid()
fmt.Println("ppid", ppid, "kill:", syscall.Kill(ppid, syscall.SIGTERM))
time.Sleep(5 * time.Second)
fmt.Println("child dying")
}
}
Upvotes: 2