Signed-off-by: Brian Goff <cpuguy83@gmail.com>
| ... | ... |
@@ -43,7 +43,7 @@ import ( |
| 43 | 43 |
const InitProcessName = "init" |
| 44 | 44 |
|
| 45 | 45 |
type container struct {
|
| 46 |
- sync.Mutex |
|
| 46 |
+ mu sync.Mutex |
|
| 47 | 47 |
|
| 48 | 48 |
bundleDir string |
| 49 | 49 |
ctr containerd.Container |
| ... | ... |
@@ -52,6 +52,54 @@ type container struct {
|
| 52 | 52 |
oomKilled bool |
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 |
+func (c *container) setTask(t containerd.Task) {
|
|
| 56 |
+ c.mu.Lock() |
|
| 57 |
+ c.task = t |
|
| 58 |
+ c.mu.Unlock() |
|
| 59 |
+} |
|
| 60 |
+ |
|
| 61 |
+func (c *container) getTask() containerd.Task {
|
|
| 62 |
+ c.mu.Lock() |
|
| 63 |
+ t := c.task |
|
| 64 |
+ c.mu.Unlock() |
|
| 65 |
+ return t |
|
| 66 |
+} |
|
| 67 |
+ |
|
| 68 |
+func (c *container) addProcess(id string, p containerd.Process) {
|
|
| 69 |
+ c.mu.Lock() |
|
| 70 |
+ if c.execs == nil {
|
|
| 71 |
+ c.execs = make(map[string]containerd.Process) |
|
| 72 |
+ } |
|
| 73 |
+ c.execs[id] = p |
|
| 74 |
+ c.mu.Unlock() |
|
| 75 |
+} |
|
| 76 |
+ |
|
| 77 |
+func (c *container) deleteProcess(id string) {
|
|
| 78 |
+ c.mu.Lock() |
|
| 79 |
+ delete(c.execs, id) |
|
| 80 |
+ c.mu.Unlock() |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 83 |
+func (c *container) getProcess(id string) containerd.Process {
|
|
| 84 |
+ c.mu.Lock() |
|
| 85 |
+ p := c.execs[id] |
|
| 86 |
+ c.mu.Unlock() |
|
| 87 |
+ return p |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+func (c *container) setOOMKilled(killed bool) {
|
|
| 91 |
+ c.mu.Lock() |
|
| 92 |
+ c.oomKilled = killed |
|
| 93 |
+ c.mu.Unlock() |
|
| 94 |
+} |
|
| 95 |
+ |
|
| 96 |
+func (c *container) getOOMKilled() bool {
|
|
| 97 |
+ c.mu.Lock() |
|
| 98 |
+ killed := c.oomKilled |
|
| 99 |
+ c.mu.Unlock() |
|
| 100 |
+ return killed |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 55 | 103 |
type client struct {
|
| 56 | 104 |
sync.RWMutex // protects containers map |
| 57 | 105 |
|
| ... | ... |
@@ -161,10 +209,10 @@ func (c *client) Create(ctx context.Context, id string, ociSpec *specs.Spec, run |
| 161 | 161 |
// Start create and start a task for the specified containerd id |
| 162 | 162 |
func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin bool, attachStdio StdioCallback) (int, error) {
|
| 163 | 163 |
ctr := c.getContainer(id) |
| 164 |
- switch {
|
|
| 165 |
- case ctr == nil: |
|
| 164 |
+ if ctr == nil {
|
|
| 166 | 165 |
return -1, errors.WithStack(newNotFoundError("no such container"))
|
| 167 |
- case ctr.task != nil: |
|
| 166 |
+ } |
|
| 167 |
+ if t := ctr.getTask(); t != nil {
|
|
| 168 | 168 |
return -1, errors.WithStack(newConflictError("container already started"))
|
| 169 | 169 |
} |
| 170 | 170 |
|
| ... | ... |
@@ -228,9 +276,7 @@ func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin |
| 228 | 228 |
return -1, err |
| 229 | 229 |
} |
| 230 | 230 |
|
| 231 |
- c.Lock() |
|
| 232 |
- c.containers[id].task = t |
|
| 233 |
- c.Unlock() |
|
| 231 |
+ ctr.setTask(t) |
|
| 234 | 232 |
|
| 235 | 233 |
// Signal c.createIO that it can call CloseIO |
| 236 | 234 |
close(stdinCloseSync) |
| ... | ... |
@@ -240,9 +286,7 @@ func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin |
| 240 | 240 |
c.logger.WithError(err).WithField("container", id).
|
| 241 | 241 |
Error("failed to delete task after fail start")
|
| 242 | 242 |
} |
| 243 |
- c.Lock() |
|
| 244 |
- c.containers[id].task = nil |
|
| 245 |
- c.Unlock() |
|
| 243 |
+ ctr.setTask(nil) |
|
| 246 | 244 |
return -1, err |
| 247 | 245 |
} |
| 248 | 246 |
|
| ... | ... |
@@ -251,12 +295,15 @@ func (c *client) Start(ctx context.Context, id, checkpointDir string, withStdin |
| 251 | 251 |
|
| 252 | 252 |
func (c *client) Exec(ctx context.Context, containerID, processID string, spec *specs.Process, withStdin bool, attachStdio StdioCallback) (int, error) {
|
| 253 | 253 |
ctr := c.getContainer(containerID) |
| 254 |
- switch {
|
|
| 255 |
- case ctr == nil: |
|
| 254 |
+ if ctr == nil {
|
|
| 256 | 255 |
return -1, errors.WithStack(newNotFoundError("no such container"))
|
| 257 |
- case ctr.task == nil: |
|
| 256 |
+ } |
|
| 257 |
+ t := ctr.getTask() |
|
| 258 |
+ if t == nil {
|
|
| 258 | 259 |
return -1, errors.WithStack(newInvalidParameterError("container is not running"))
|
| 259 |
- case ctr.execs != nil && ctr.execs[processID] != nil: |
|
| 260 |
+ } |
|
| 261 |
+ |
|
| 262 |
+ if p := ctr.getProcess(processID); p != nil {
|
|
| 260 | 263 |
return -1, errors.WithStack(newConflictError("id already in use"))
|
| 261 | 264 |
} |
| 262 | 265 |
|
| ... | ... |
@@ -279,7 +326,7 @@ func (c *client) Exec(ctx context.Context, containerID, processID string, spec * |
| 279 | 279 |
} |
| 280 | 280 |
}() |
| 281 | 281 |
|
| 282 |
- p, err = ctr.task.Exec(ctx, processID, spec, func(id string) (cio.IO, error) {
|
|
| 282 |
+ p, err = t.Exec(ctx, processID, spec, func(id string) (cio.IO, error) {
|
|
| 283 | 283 |
rio, err = c.createIO(fifos, containerID, processID, stdinCloseSync, attachStdio) |
| 284 | 284 |
return rio, err |
| 285 | 285 |
}) |
| ... | ... |
@@ -292,21 +339,14 @@ func (c *client) Exec(ctx context.Context, containerID, processID string, spec * |
| 292 | 292 |
return -1, err |
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 |
- ctr.Lock() |
|
| 296 |
- if ctr.execs == nil {
|
|
| 297 |
- ctr.execs = make(map[string]containerd.Process) |
|
| 298 |
- } |
|
| 299 |
- ctr.execs[processID] = p |
|
| 300 |
- ctr.Unlock() |
|
| 295 |
+ ctr.addProcess(processID, p) |
|
| 301 | 296 |
|
| 302 | 297 |
// Signal c.createIO that it can call CloseIO |
| 303 | 298 |
close(stdinCloseSync) |
| 304 | 299 |
|
| 305 | 300 |
if err = p.Start(ctx); err != nil {
|
| 306 | 301 |
p.Delete(context.Background()) |
| 307 |
- ctr.Lock() |
|
| 308 |
- delete(ctr.execs, processID) |
|
| 309 |
- ctr.Unlock() |
|
| 302 |
+ ctr.deleteProcess(processID) |
|
| 310 | 303 |
return -1, err |
| 311 | 304 |
} |
| 312 | 305 |
|
| ... | ... |
@@ -432,12 +472,9 @@ func (c *client) DeleteTask(ctx context.Context, containerID string) (uint32, ti |
| 432 | 432 |
return 255, time.Now(), nil |
| 433 | 433 |
} |
| 434 | 434 |
|
| 435 |
- c.Lock() |
|
| 436 |
- if ctr, ok := c.containers[containerID]; ok {
|
|
| 437 |
- ctr.task = nil |
|
| 435 |
+ if ctr := c.getContainer(containerID); ctr != nil {
|
|
| 436 |
+ ctr.setTask(nil) |
|
| 438 | 437 |
} |
| 439 |
- c.Unlock() |
|
| 440 |
- |
|
| 441 | 438 |
return status.ExitCode(), status.ExitTime(), nil |
| 442 | 439 |
} |
| 443 | 440 |
|
| ... | ... |
@@ -471,7 +508,12 @@ func (c *client) Status(ctx context.Context, containerID string) (Status, error) |
| 471 | 471 |
return StatusUnknown, errors.WithStack(newNotFoundError("no such container"))
|
| 472 | 472 |
} |
| 473 | 473 |
|
| 474 |
- s, err := ctr.task.Status(ctx) |
|
| 474 |
+ t := ctr.getTask() |
|
| 475 |
+ if t == nil {
|
|
| 476 |
+ return StatusUnknown, errors.WithStack(newNotFoundError("no such task"))
|
|
| 477 |
+ } |
|
| 478 |
+ |
|
| 479 |
+ s, err := t.Status(ctx) |
|
| 475 | 480 |
if err != nil {
|
| 476 | 481 |
return StatusUnknown, err |
| 477 | 482 |
} |
| ... | ... |
@@ -547,26 +589,22 @@ func (c *client) removeContainer(id string) {
|
| 547 | 547 |
|
| 548 | 548 |
func (c *client) getProcess(containerID, processID string) (containerd.Process, error) {
|
| 549 | 549 |
ctr := c.getContainer(containerID) |
| 550 |
- switch {
|
|
| 551 |
- case ctr == nil: |
|
| 550 |
+ if ctr == nil {
|
|
| 552 | 551 |
return nil, errors.WithStack(newNotFoundError("no such container"))
|
| 553 |
- case ctr.task == nil: |
|
| 552 |
+ } |
|
| 553 |
+ |
|
| 554 |
+ t := ctr.getTask() |
|
| 555 |
+ if t == nil {
|
|
| 554 | 556 |
return nil, errors.WithStack(newNotFoundError("container is not running"))
|
| 555 |
- case processID == InitProcessName: |
|
| 556 |
- return ctr.task, nil |
|
| 557 |
- default: |
|
| 558 |
- ctr.Lock() |
|
| 559 |
- defer ctr.Unlock() |
|
| 560 |
- if ctr.execs == nil {
|
|
| 561 |
- return nil, errors.WithStack(newNotFoundError("no execs"))
|
|
| 562 |
- } |
|
| 557 |
+ } |
|
| 558 |
+ if processID == InitProcessName {
|
|
| 559 |
+ return t, nil |
|
| 563 | 560 |
} |
| 564 | 561 |
|
| 565 |
- p := ctr.execs[processID] |
|
| 562 |
+ p := ctr.getProcess(processID) |
|
| 566 | 563 |
if p == nil {
|
| 567 | 564 |
return nil, errors.WithStack(newNotFoundError("no such exec"))
|
| 568 | 565 |
} |
| 569 |
- |
|
| 570 | 566 |
return p, nil |
| 571 | 567 |
} |
| 572 | 568 |
|
| ... | ... |
@@ -624,12 +662,7 @@ func (c *client) processEvent(ctr *container, et EventType, ei EventInfo) {
|
| 624 | 624 |
} |
| 625 | 625 |
|
| 626 | 626 |
if et == EventExit && ei.ProcessID != ei.ContainerID {
|
| 627 |
- var p containerd.Process |
|
| 628 |
- ctr.Lock() |
|
| 629 |
- if ctr.execs != nil {
|
|
| 630 |
- p = ctr.execs[ei.ProcessID] |
|
| 631 |
- } |
|
| 632 |
- ctr.Unlock() |
|
| 627 |
+ p := ctr.getProcess(ei.ProcessID) |
|
| 633 | 628 |
if p == nil {
|
| 634 | 629 |
c.logger.WithError(errors.New("no such process")).
|
| 635 | 630 |
WithFields(logrus.Fields{
|
| ... | ... |
@@ -645,9 +678,8 @@ func (c *client) processEvent(ctr *container, et EventType, ei EventInfo) {
|
| 645 | 645 |
"process": ei.ProcessID, |
| 646 | 646 |
}).Warn("failed to delete process")
|
| 647 | 647 |
} |
| 648 |
- c.Lock() |
|
| 649 |
- delete(ctr.execs, ei.ProcessID) |
|
| 650 |
- c.Unlock() |
|
| 648 |
+ ctr.deleteProcess(ei.ProcessID) |
|
| 649 |
+ |
|
| 651 | 650 |
ctr := c.getContainer(ei.ContainerID) |
| 652 | 651 |
if ctr == nil {
|
| 653 | 652 |
c.logger.WithFields(logrus.Fields{
|
| ... | ... |
@@ -784,10 +816,10 @@ func (c *client) processEventStream(ctx context.Context) {
|
| 784 | 784 |
} |
| 785 | 785 |
|
| 786 | 786 |
if oomKilled {
|
| 787 |
- ctr.oomKilled = true |
|
| 787 |
+ ctr.setOOMKilled(true) |
|
| 788 | 788 |
oomKilled = false |
| 789 | 789 |
} |
| 790 |
- ei.OOMKilled = ctr.oomKilled |
|
| 790 |
+ ei.OOMKilled = ctr.getOOMKilled() |
|
| 791 | 791 |
|
| 792 | 792 |
c.processEvent(ctr, et, ei) |
| 793 | 793 |
} |