@@ -2102,16 +2102,34 @@ func encodeIDMapping(idMap []configs.IDMap) ([]byte, error) {
21022102 return data .Bytes (), nil
21032103}
21042104
2105+ // netlinkError is an error wrapper type for use by custom netlink message
2106+ // types. Panics with errors are wrapped in netlinkError so that the recover
2107+ // in bootstrapData can distinguish intentional panics.
2108+ type netlinkError struct { error }
2109+
21052110// bootstrapData encodes the necessary data in netlink binary format
21062111// as a io.Reader.
21072112// Consumer can write the data to a bootstrap program
21082113// such as one that uses nsenter package to bootstrap the container's
21092114// init process correctly, i.e. with correct namespaces, uid/gid
21102115// mapping etc.
2111- func (c * linuxContainer ) bootstrapData (cloneFlags uintptr , nsMaps map [configs.NamespaceType ]string , it initType ) (io.Reader , error ) {
2116+ func (c * linuxContainer ) bootstrapData (cloneFlags uintptr , nsMaps map [configs.NamespaceType ]string , it initType ) (_ io.Reader , Err error ) {
21122117 // create the netlink message
21132118 r := nl .NewNetlinkRequest (int (InitMsg ), 0 )
21142119
2120+ // Our custom messages cannot bubble up an error using returns, instead
2121+ // they will panic with the specific error type, netlinkError. In that
2122+ // case, recover from the panic and return that as an error.
2123+ defer func () {
2124+ if r := recover (); r != nil {
2125+ if e , ok := r .(netlinkError ); ok {
2126+ Err = e .error
2127+ } else {
2128+ panic (r )
2129+ }
2130+ }
2131+ }()
2132+
21152133 // write cloneFlags
21162134 r .AddData (& Int32msg {
21172135 Type : CloneFlagsAttr ,
0 commit comments