Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 00dd316

Browse files
committed
runv: implement pause and resume
Implement the pause and resume commands of OCI. According to the spec, pause suspends all processes in the container, and resume resumes them. Signed-off-by: Antonios Motakis <antonios.motakis@huawei.com>
1 parent 9483623 commit 00dd316

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ func main() {
159159
stateCommand,
160160
manageCommand,
161161
shimCommand,
162+
pauseCommand,
163+
resumeCommand,
162164
containerd.ContainerdCommand,
163165
}
164166
if err := app.Run(os.Args); err != nil {

pause.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"path/filepath"
6+
7+
"github.com/hyperhq/runv/containerd/api/grpc/types"
8+
"github.com/hyperhq/runv/lib/linuxsignal"
9+
"github.com/urfave/cli"
10+
netcontext "golang.org/x/net/context"
11+
)
12+
13+
var pauseCommand = cli.Command{
14+
Name: "pause",
15+
Usage: "suspend all processes in the container",
16+
ArgsUsage: `<container-id>`,
17+
Action: func(context *cli.Context) error {
18+
container := context.Args().First()
19+
if container == "" {
20+
return cli.NewExitError(fmt.Sprintf("container id cannot be empty"), -1)
21+
}
22+
23+
c, err := getClient(filepath.Join(context.GlobalString("root"), container, "namespace/namespaced.sock"))
24+
if err != nil {
25+
return cli.NewExitError(fmt.Sprintf("failed to get client: %v", err), -1)
26+
}
27+
28+
plist, err := getProcessList(c, container)
29+
if err != nil {
30+
return cli.NewExitError(fmt.Sprintf("can't get process list, %v", err), -1)
31+
}
32+
33+
for _, p := range plist {
34+
if _, err := c.Signal(netcontext.Background(), &types.SignalRequest{
35+
Id: container,
36+
Pid: p,
37+
Signal: uint32(linuxsignal.SIGSTOP),
38+
}); err != nil {
39+
return cli.NewExitError(fmt.Sprintf("suspend signal failed, %v", err), -1)
40+
}
41+
}
42+
43+
return nil
44+
},
45+
}
46+
47+
var resumeCommand = cli.Command{
48+
Name: "resume",
49+
Usage: "resume all processes in the container",
50+
ArgsUsage: `<container-id>`,
51+
Action: func(context *cli.Context) error {
52+
container := context.Args().First()
53+
if container == "" {
54+
return cli.NewExitError(fmt.Sprintf("container id cannot be empty"), -1)
55+
}
56+
57+
c, err := getClient(filepath.Join(context.GlobalString("root"), container, "namespace/namespaced.sock"))
58+
if err != nil {
59+
return cli.NewExitError(fmt.Sprintf("failed to get client: %v", err), -1)
60+
}
61+
62+
plist, err := getProcessList(c, container)
63+
if err != nil {
64+
return cli.NewExitError(fmt.Sprintf("can't get process list, %v", err), -1)
65+
}
66+
67+
for _, p := range plist {
68+
if _, err := c.Signal(netcontext.Background(), &types.SignalRequest{
69+
Id: container,
70+
Pid: p,
71+
Signal: uint32(linuxsignal.SIGCONT),
72+
}); err != nil {
73+
return cli.NewExitError(fmt.Sprintf("resume signal failed, %v", err), -1)
74+
}
75+
}
76+
77+
return nil
78+
},
79+
}

0 commit comments

Comments
 (0)