runc: improve canceling

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2018-08-03 10:00:54 -07:00
parent 765f1b64b9
commit f8dd602282
3 changed files with 52 additions and 26 deletions

View File

@ -78,11 +78,16 @@ func (w containerdExecutor) Exec(ctx context.Context, meta executor.Meta, root c
lm.Unmount() lm.Unmount()
} }
hostNetworkEnabled := false hostNetworkEnabled := true
iface, err := w.networkProvider.NewInterface() var iface network.Interface
if err != nil || iface == nil { if w.networkProvider != nil {
iface, err = w.networkProvider.NewInterface()
if err == nil && iface != nil {
hostNetworkEnabled = false
}
}
if hostNetworkEnabled {
logrus.Info("enabling HostNetworking") logrus.Info("enabling HostNetworking")
hostNetworkEnabled = true
} }
opts := []containerdoci.SpecOpts{oci.WithUIDGID(uid, gid, sgids)} opts := []containerdoci.SpecOpts{oci.WithUIDGID(uid, gid, sgids)}

View File

@ -106,6 +106,23 @@ func New(opt Opt, networkProvider network.Provider) (executor.Executor, error) {
} }
func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.Mountable, mounts []executor.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error { func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.Mountable, mounts []executor.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
hostNetworkEnabled := true
var iface network.Interface
if w.networkProvider != nil {
var err error
iface, err = w.networkProvider.NewInterface()
if err == nil && iface != nil {
hostNetworkEnabled = false
}
}
if hostNetworkEnabled {
logrus.Info("enabling HostNetworking")
}
defer func() {
if iface != nil {
w.networkProvider.Release(iface)
}
}()
resolvConf, err := oci.GetResolvConf(ctx, w.root) resolvConf, err := oci.GetResolvConf(ctx, w.root)
if err != nil { if err != nil {
@ -158,13 +175,6 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
} }
defer f.Close() defer f.Close()
hostNetworkEnabled := false
iface, err := w.networkProvider.NewInterface()
if err != nil || iface == nil {
logrus.Info("enabling HostNetworking")
hostNetworkEnabled = true
}
opts := []containerdoci.SpecOpts{oci.WithUIDGID(uid, gid, sgids)} opts := []containerdoci.SpecOpts{oci.WithUIDGID(uid, gid, sgids)}
if system.SeccompSupported() { if system.SeccompSupported() {
opts = append(opts, seccomp.WithDefaultProfile()) opts = append(opts, seccomp.WithDefaultProfile())
@ -204,8 +214,6 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
return err return err
} }
f.Sync()
forwardIO, err := newForwardIO(stdin, stdout, stderr) forwardIO, err := newForwardIO(stdin, stdout, stderr)
if err != nil { if err != nil {
return errors.Wrap(err, "creating new forwarding IO") return errors.Wrap(err, "creating new forwarding IO")
@ -216,14 +224,23 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
defer os.RemoveAll(pidFilePath) defer os.RemoveAll(pidFilePath)
logrus.Debugf("> creating %s %v", id, meta.Args) logrus.Debugf("> creating %s %v", id, meta.Args)
if err := w.runc.Create(ctx, id, bundle, &runc.CreateOpts{ err = w.runc.Create(ctx, id, bundle, &runc.CreateOpts{
PidFile: pidFilePath, PidFile: pidFilePath,
IO: forwardIO, IO: forwardIO,
}); err != nil { })
if err != nil {
return err return err
} }
forwardIO.release() forwardIO.release()
defer func() {
go func() {
if err := w.runc.Delete(context.TODO(), id, &runc.DeleteOpts{}); err != nil {
logrus.Errorf("failed to delete %s: %+v", id, err)
}
}()
}()
dt, err := ioutil.ReadFile(pidFilePath) dt, err := ioutil.ReadFile(pidFilePath)
if err != nil { if err != nil {
return err return err
@ -233,21 +250,25 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
return err return err
} }
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-done:
case <-ctx.Done():
syscall.Kill(-pid, syscall.SIGKILL)
}
}()
if iface != nil { if iface != nil {
if err := iface.Set(pid); err != nil { if err := iface.Set(pid); err != nil {
return errors.Wrap(err, "could not set the network") return errors.Wrap(err, "could not set the network")
} }
}
defer func() { defer func() {
if iface != nil {
iface.Remove(pid) iface.Remove(pid)
w.networkProvider.Release(iface)
}
if err := w.runc.Delete(context.TODO(), id, &runc.DeleteOpts{}); err != nil {
logrus.Errorf("failed to delete %s: %+v", id, err)
}
}() }()
}
err = w.runc.Start(ctx, id) err = w.runc.Start(ctx, id)
if err != nil { if err != nil {

View File

@ -112,7 +112,7 @@ func TestRuncWorker(t *testing.T) {
root, err := w.CacheManager.New(ctx, snap) root, err := w.CacheManager.New(ctx, snap)
require.NoError(t, err) require.NoError(t, err)
err = w.Executor.Exec(ctx, meta, root, nil, nil, nil, nil) err = w.Executor.Exec(ctx, meta, root, nil, nil, nil, &nopCloser{stderr})
require.NoError(t, err) require.NoError(t, err)
meta = executor.Meta{ meta = executor.Meta{