github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/nsenter/README.md (about)

     1  ## nsenter
     2  
     3  The `nsenter` package registers a special init constructor that is called before 
     4  the Go runtime has a chance to boot.  This provides us the ability to `setns` on 
     5  existing namespaces and avoid the issues that the Go runtime has with multiple 
     6  threads.  This constructor will be called if this package is registered, 
     7  imported, in your go application.
     8  
     9  The `nsenter` package will `import "C"` and it uses [cgo](https://golang.org/cmd/cgo/)
    10  package. In cgo, if the import of "C" is immediately preceded by a comment, that comment, 
    11  called the preamble, is used as a header when compiling the C parts of the package.
    12  So every time we  import package `nsenter`, the C code function `nsexec()` would be 
    13  called. And package `nsenter` is now only imported in `main_unix.go`, so every time
    14  before we call `cmd.Start` on linux, that C code would run.
    15  
    16  Because `nsexec()` must be run before the Go runtime in order to use the
    17  Linux kernel namespace, you must `import` this library into a package if
    18  you plan to use `libcontainer` directly. Otherwise Go will not execute
    19  the `nsexec()` constructor, which means that the re-exec will not cause
    20  the namespaces to be joined. You can import it like this:
    21  
    22  ```go
    23  import _ "github.com/opencontainers/runc/libcontainer/nsenter"
    24  ```
    25  
    26  `nsexec()` will first get the file descriptor number for the init pipe
    27  from the environment variable `_LIBCONTAINER_INITPIPE` (which was opened
    28  by the parent and kept open across the fork-exec of the `nsexec()` init
    29  process). The init pipe is used to read bootstrap data (namespace paths,
    30  clone flags, uid and gid mappings, and the console path) from the parent
    31  process. `nsexec()` will then call `setns(2)` to join the namespaces
    32  provided in the bootstrap data (if available), `clone(2)` a child process
    33  with the provided clone flags, update the user and group ID mappings, do
    34  some further miscellaneous setup steps, and then send the PID of the
    35  child process to the parent of the `nsexec()` "caller". Finally,
    36  the parent `nsexec()` will exit and the child `nsexec()` process will
    37  return to allow the Go runtime take over.
    38  
    39  NOTE: We do both `setns(2)` and `clone(2)` even if we don't have any
    40  CLONE_NEW* clone flags because we must fork a new process in order to
    41  enter the PID namespace.
    42  
    43  
    44