如何将net.Listener()的FD传递给子进程安全? [英] How to pass net.Listener()'s FD to child process safely?

查看:427
本文介绍了如何将net.Listener()的FD传递给子进程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个作为TCP服务器的主进程,主进程调用Fork(),将其传递给它net.Listener()的FD到子进程。然后子进程可以使用net.Filelistener()继承这个FD。



我通过很多开源代码研究了这个问题,并做了一些实验。但不幸的是,现在这些解决方案都不能满足我的需求,因为它们不是便携式的,您还需要许多低级别的工作,这些工作是危险的。

如果有任何解决方案可以通过网络.Listener()的FD给子进程SAFELY,我很高兴知道。



我现在试过的:


  1. 环境值不可移植,会导致许多FD出现混乱,不安全,因为可以从外部更改。

  2. $ b
  3. Dup FD&清除 FD_CLOEXEC 然后执行/ fork,可移植但不受Go API支持, syscall.NoCloseOnExec()开发团队被拒绝了,因为他们希望保持系统清洁。


  4. 设置 SO_REUSEADDR 立即移植,在此之前关闭父母的听众。失败,不可移植,不受Go API支持,也不安全。

  5. c>,不知道如何从子进程获得继承的FD,我需要一个配置文件来保存FD&名字呢?这个解决方案也有一个bug,请阅读exec的文档以获取更多细节。 这个问题的简单测试用例(解决方案4):

    https://github.com/reckhou/go-fd-pass-test



    还包括OS X& amp; 2上的两个可执行文件; Linux操作系统。我试过Go 1.1& Go 1.1.1,但这个问题仍然存在。

    解决方案

    最简单的方法是将侦听器传递给exec的ExtraFiles字段。 Cmd。



    父母的例子:

      var l * net。 TCPListener 
    cmd:= exec.Command(...)
    f,err:= l.File()
    cmd.ExtraFiles = [] * os.File {f}

    孩子的例子:

      l,err:= net.FileListener(os.NewFile(3,listener))

    您可能还想概括这一点,并让孩子接受PROGRAMNAME_LISTENER_FD作为环境变量。然后,在开始孩子之前,父母会将环境变量设置为3.


    I've been stucked with this issue for hours:

    I have a main process served as a TCP server, the main process call Fork(), pass its net.Listener()'s FD to child process. Then child process can use net.Filelistener() to inherit this FD.

    I have researched this issue through many open-sourced codes, also did some experiments. But unfortunately none of these solutions satisfy me for now since they are not portable, you also need many low-level jobs which are dangerous.

    If there's any solution to pass net.Listener()'s FD to child process SAFELY, I'd be glad to know.

    What I've tried for now:

    1. Environment values, not portable, will cause chaos with many FDs, not safe since can be changed from outside.

    2. Dup FD & Clear FD_CLOEXEC then exec/fork, portable but not supported by Go API, a syscall.NoCloseOnExec() change submitted to dev team was rejected since they want to keep syscall clean.

    3. Set SO_REUSEADDR so child process can listen to port instantly, close parent's listener before that. Failed, not portable, not supported by Go API, also unsafe.

    4. exec.Command.ExtraFiles(), have no idea how to get inherited FDs from child process, do I need a config file to save FD & names? This solution also have a bug, read exec's document for more detail.

    All right guys, I've written a simple test case of this issue(with solution 4):

    https://github.com/reckhou/go-fd-pass-test

    Also include 2 executables on OS X & Linux. I tried Go 1.1 & Go 1.1.1 but this issue still remains.

    解决方案

    The easiest way is to pass the listener in the ExtraFiles field of exec.Cmd.

    Example of parent:

    var l *net.TCPListener
    cmd := exec.Command(...)
    f, err := l.File()
    cmd.ExtraFiles = []*os.File{f}
    

    Example of child:

    l, err := net.FileListener(os.NewFile(3, "listener"))
    

    You may also want to generalize this and have the child accept PROGRAMNAME_LISTENER_FD as an environment variable. Then the parent would set the environment variable to 3 before starting the child.

    这篇关于如何将net.Listener()的FD传递给子进程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆