Repository: firecracker-microvm/firecracker-containerd
Pull request #460 (2020-11-20 11:57:18)

Add PauseVM and ResumeVM support
The goal of this PR is to implement support for PauseVM and ResumeVM.

Authored by @plamenmpetrov and @ustiugov 

We are open to feedback and would be glad to finalize and contribute this code to upstream.

*Issue #, if available:*
#448 
*Description of changes:*
* Update firecracker-go-sdk to a version which supports PauseVM and ResumeVM.
* Update build procedure for `tc-redirect-tap`, which is no longer part of the Go SDK
* Implement calls to PauseVM and ResumeVM

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.


kzys: Looks good to me! Can you add an integration test that pauses and resumes a VM?
ustiugov: it seems that the buildkite failure is not related to the patch. how can I re-run the test?
kzys: Let me take a look. Right now only maintainers can restart tests.
ustiugov: @kzys we added the necessary tests, could you please take another look?
kzys: Looks good to me. I think the build errors are related to #475, not your changes.
kzys: I've merged #475. Can you rebase this PR against master? This should fix GitHub Actions failures at least.

Patch:
diff --git a/Makefile b/Makefile
index 1f16988..b082b34 100644
--- a/Makefile
+++ b/Makefile
@@ -240,7 +240,7 @@ $(FIREWALL_BIN):
 
 TC_REDIRECT_TAP_BIN?=$(BINPATH)/tc-redirect-tap
 $(TC_REDIRECT_TAP_BIN):
-	GOBIN=$(dir $@) go install github.com/firecracker-microvm/firecracker-go-sdk/cni/cmd/tc-redirect-tap
+	GOBIN=$(dir $@) go install github.com/awslabs/tc-redirect-tap/cmd/tc-redirect-tap
 
 TEST_BRIDGED_TAP_BIN?=$(BINPATH)/test-bridged-tap
 $(TEST_BRIDGED_TAP_BIN): $(shell find internal/cmd/test-bridged-tap -name *.go) $(GOMOD) $(GOSUM)
diff --git a/firecracker-control/local.go b/firecracker-control/local.go
index 89dbd77..01e337d 100644
--- a/firecracker-control/local.go
+++ b/firecracker-control/local.go
@@ -252,6 +252,42 @@ func (s *local) StopVM(requestCtx context.Context, req *proto.StopVMRequest) (*e
 	return resp, multierror.Append(shimErr, waitErr).ErrorOrNil()
 }
 
+// PauseVM pauses a VM
+func (s *local) PauseVM(ctx context.Context, req *proto.PauseVMRequest) (*empty.Empty, error) {
+	client, err := s.shimFirecrackerClient(ctx, req.VMID)
+	if err != nil {
+		return nil, err
+	}
+
+	defer client.Close()
+
+	resp, err := client.PauseVM(ctx, req)
+	if err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	return resp, nil
+}
+
+// ResumeVM resumes a VM
+func (s *local) ResumeVM(ctx context.Context, req *proto.ResumeVMRequest) (*empty.Empty, error) {
+	client, err := s.shimFirecrackerClient(ctx, req.VMID)
+	if err != nil {
+		return nil, err
+	}
+
+	defer client.Close()
+
+	resp, err := client.ResumeVM(ctx, req)
+	if err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	return resp, nil
+}
+
 func (s *local) waitForShimToExit(ctx context.Context, vmID string) error {
 	socketAddr, err := fcShim.SocketAddress(ctx, vmID)
 	if err != nil {
diff --git a/firecracker-control/service.go b/firecracker-control/service.go
index 5c931ab..35660f7 100644
--- a/firecracker-control/service.go
+++ b/firecracker-control/service.go
@@ -72,6 +72,16 @@ func (s *service) CreateVM(ctx context.Context, req *proto.CreateVMRequest) (*pr
 	return s.local.CreateVM(ctx, req)
 }
 
+func (s *service) PauseVM(ctx context.Context, req *proto.PauseVMRequest) (*empty.Empty, error) {
+	log.G(ctx).Debugf("pause VM request: %+v", req)
+	return s.local.PauseVM(ctx, req)
+}
+
+func (s *service) ResumeVM(ctx context.Context, req *proto.ResumeVMRequest) (*empty.Empty, error) {
+	log.G(ctx).Debugf("resume VM request: %+v", req)
+	return s.local.ResumeVM(ctx, req)
+}
+
 func (s *service) StopVM(ctx context.Context, req *proto.StopVMRequest) (*empty.Empty, error) {
 	log.G(ctx).Debugf("stop VM: %+v", req)
 	return s.local.StopVM(ctx, req)
diff --git a/go.mod b/go.mod
index 4ed72e0..0002f11 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module github.com/firecracker-microvm/firecracker-containerd
 require (
 	github.com/Microsoft/go-winio v0.4.14 // indirect
 	github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 // indirect
+	github.com/awslabs/tc-redirect-tap v0.0.0-20200708224642-a0300978797d
 	github.com/containerd/cgroups v0.0.0-20181105182409-82cb49fc1779 // indirect
 	github.com/containerd/console v0.0.0-20191219165238-8375c3424e4d // indirect
 	github.com/containerd/containerd v1.3.8-0.20200824223617-f99bb2cc4483
@@ -11,13 +12,13 @@ require (
 	github.com/containerd/go-runc v0.0.0-20190226155025-7d11b49dc076
 	github.com/containerd/ttrpc v0.0.0-20190613183316-1fb3814edf44
 	github.com/containerd/typeurl v0.0.0-20181015155603-461401dc8f19
-	github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc
-	github.com/containernetworking/plugins v0.8.6
+	github.com/containernetworking/cni v0.8.0
+	github.com/containernetworking/plugins v0.8.7
 	github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 // indirect
 	github.com/docker/distribution v2.7.1+incompatible // indirect
 	github.com/docker/go-events v0.0.0-20170721190031-9461782956ad // indirect
 	github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
-	github.com/firecracker-microvm/firecracker-go-sdk v0.21.1-0.20200811001213-ee1e7c41b7bd
+	github.com/firecracker-microvm/firecracker-go-sdk v0.22.1-0.20201117001223-cd822c0d457c
 	github.com/go-ole/go-ole v1.2.4 // indirect
 	github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384 // indirect
 	github.com/gofrs/uuid v3.3.0+incompatible
@@ -25,7 +26,7 @@ require (
 	github.com/gogo/protobuf v1.3.0
 	github.com/golang/protobuf v1.3.1
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
-	github.com/hashicorp/go-multierror v1.0.0
+	github.com/hashicorp/go-multierror v1.1.0
 	github.com/imdario/mergo v0.3.8 // indirect
 	github.com/mdlayher/vsock v0.0.0-20190329173812-a92c53d5dcab
 	github.com/miekg/dns v1.1.16
@@ -37,13 +38,13 @@ require (
 	github.com/prometheus/client_golang v0.9.2 // indirect
 	github.com/shirou/gopsutil v2.18.12+incompatible
 	github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
-	github.com/sirupsen/logrus v1.6.0
+	github.com/sirupsen/logrus v1.7.0
 	github.com/stretchr/testify v1.6.1
 	github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect
 	github.com/urfave/cli v1.20.0 // indirect
 	github.com/vishvananda/netlink v1.1.0
 	go.etcd.io/bbolt v1.3.1-etcd.8 // indirect
-	golang.org/x/sync v0.0.0-20190423024810-112230192c58
+	golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
 	golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
 	google.golang.org/genproto v0.0.0-20181109154231-b5d43981345b // indirect
 	google.golang.org/grpc v1.21.0
diff --git a/go.sum b/go.sum
index 56e869a..923ff03 100644
--- a/go.sum
+++ b/go.sum
@@ -14,7 +14,9 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 h1:UUppSQnhf4Yc6xGxSkoQpPhb7RVzuv5Nb1mwJ5VId9s=
 github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
 github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
 github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
@@ -22,6 +24,9 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
 github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
+github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
+github.com/awslabs/tc-redirect-tap v0.0.0-20200708224642-a0300978797d h1:AZYARHUEwaWIITYIuBxUoastJ1t+aHom/6ZwEhfZzwo=
+github.com/awslabs/tc-redirect-tap v0.0.0-20200708224642-a0300978797d/go.mod h1:kQGbgU5sye2xV5J0ruPiscqz3Cj30VtoWRrhBeIo7dM=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
@@ -43,10 +48,12 @@ github.com/containerd/ttrpc v0.0.0-20190613183316-1fb3814edf44/go.mod h1:PvCDdDG
 github.com/containerd/typeurl v0.0.0-20181015155603-461401dc8f19 h1:gzdItdct+4eLnZxiZi1YcIXx3uo5QWa/xXKnsldEqY8=
 github.com/containerd/typeurl v0.0.0-20181015155603-461401dc8f19/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
 github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc h1:zUNdrf9w09mWodVhZ9hX4Yk4Uu84n/OgdfPattAwwt8=
-github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI=
+github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
 github.com/containernetworking/plugins v0.8.6 h1:npZTLiMa4CRn6m5P9+1Dz4O1j0UeFbm8VYN6dlsw568=
 github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
+github.com/containernetworking/plugins v0.8.7 h1:bU7QieuAp+sACI2vCzESJ3FoT860urYP+lThyZkb/2M=
+github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
 github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
 github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk=
@@ -69,8 +76,8 @@ github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk
 github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
 github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
 github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/firecracker-microvm/firecracker-go-sdk v0.21.1-0.20200811001213-ee1e7c41b7bd h1:rPKyLpvuNQyDJYl43yaEfoPbOsHDr/yYFWADM+Mab8Q=
-github.com/firecracker-microvm/firecracker-go-sdk v0.21.1-0.20200811001213-ee1e7c41b7bd/go.mod h1:pUsVzdFHUnR8Xhu9srsqngXNEBlSDyDf08hmGWqgf34=
+github.com/firecracker-microvm/firecracker-go-sdk v0.22.1-0.20201117001223-cd822c0d457c h1:OVDRQkCg0SvAYg3bhL6YDjdF6c8TBpQF6kQ8qwO2nA4=
+github.com/firecracker-microvm/firecracker-go-sdk v0.22.1-0.20201117001223-cd822c0d457c/go.mod h1:AY+NnSajCqPOB59l4rseMETsDM0tcpTd+st3T9ko/cA=
 github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb h1:D4uzjWwKYQ5XnAvUbuvHW93esHg7F8N/OYeBBcJoTr0=
 github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
@@ -93,6 +100,9 @@ github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS
 github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
 github.com/go-openapi/errors v0.19.6 h1:xZMThgv5SQ7SMbWtKFkCf9bBdvR2iEyw9k3zGZONuys=
 github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
+github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
+github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc=
+github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
 github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
 github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
 github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
@@ -117,8 +127,9 @@ github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6
 github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
 github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
 github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
-github.com/go-openapi/runtime v0.19.20 h1:J/t+QIjbcoq8WJvjGxRKiFBhqUE8slS9SbmD0Oi/raQ=
-github.com/go-openapi/runtime v0.19.20/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
+github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
+github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4=
+github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
 github.com/go-openapi/spec v0.17.0 h1:XNvrt8FlSVP8T1WuhbAFF6QDhJc0zsoWzX4wXARhhpE=
 github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
 github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
@@ -137,6 +148,8 @@ github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH
 github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
 github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM=
 github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
+github.com/go-openapi/strfmt v0.19.10 h1:FEv6Pt/V4wLwP4vOCZbWlpfmi8kj4UiRip34IDE6SGw=
+github.com/go-openapi/strfmt v0.19.10/go.mod h1:qBBipho+3EoIqn6YDI+4RnQEtj6jT/IdKm+PAlXxSUc=
 github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
 github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
 github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
@@ -145,11 +158,16 @@ github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1
 github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
 github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE=
 github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
+github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc=
+github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
 github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
 github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
 github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
 github.com/go-openapi/validate v0.19.10 h1:tG3SZ5DC5KF4cyt7nqLVcQXGj5A7mpaYkAcNPlDK+Yk=
 github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
+github.com/go-openapi/validate v0.19.12 h1:mPLM/bfbd00PGOCJlU0yJL7IulkZ+q9VjPv7U11RMQQ=
+github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@@ -199,6 +217,8 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
@@ -209,11 +229,15 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
 github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
 github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56 h1:742eGXur0715JMq73aD95/FU0XpVKXqNuTnEfXsLOYQ=
 github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
@@ -223,8 +247,6 @@ github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
 github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -271,6 +293,7 @@ github.com/opencontainers/runtime-spec v0.1.2-0.20181106065543-31e0d16c1cb7/go.m
 github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -290,6 +313,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
 github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM=
 github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
 github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
@@ -300,8 +324,8 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c h1:gqEdF4VwBu3lTKGHS9rXE9x1/pEaSwCXRLOZRF6qtlw=
 github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c/go.mod h1:eMyUVp6f/5jnzM+3zahzl7q6UXLbgSc3MKg/+ow9QW0=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -322,6 +346,7 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
 github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf h1:3J37+NPjNyGW/dbfXtj3yWuF9OEepIdGOXRaJGbORV8=
 github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
 github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
@@ -339,6 +364,8 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
 go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
 go.mongodb.org/mongo-driver v1.3.4 h1:zs/dKNwX0gYUtzwrN9lLiR15hCO0nDwQj5xXx+vjCdE=
 go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
+go.mongodb.org/mongo-driver v1.4.2 h1:WlnEglfTg/PfPq4WXs2Vkl/5ICC6hoG8+r+LraPmGk4=
+go.mongodb.org/mongo-driver v1.4.2/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -366,6 +393,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
 golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -377,6 +405,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180928133829-e4b3c5e90611/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -394,6 +424,7 @@ golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
 golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
@@ -406,9 +437,12 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -416,6 +450,8 @@ golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181109154231-b5d43981345b h1:WkFtVmaZoTRVoRYr0LTC9SYNhlw0X0HrVPz2OVssVm4=
diff --git a/proto/firecracker.pb.go b/proto/firecracker.pb.go
index bce3f41..b2f1536 100644
--- a/proto/firecracker.pb.go
+++ b/proto/firecracker.pb.go
@@ -263,6 +263,82 @@ func (m *CreateVMResponse) GetCgroupPath() string {
 	return ""
 }
 
+type PauseVMRequest struct {
+	VMID                 string   `protobuf:"bytes,1,opt,name=VMID,json=vMID,proto3" json:"VMID,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PauseVMRequest) Reset()         { *m = PauseVMRequest{} }
+func (m *PauseVMRequest) String() string { return proto.CompactTextString(m) }
+func (*PauseVMRequest) ProtoMessage()    {}
+func (*PauseVMRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a73317e9fb8da571, []int{2}
+}
+func (m *PauseVMRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PauseVMRequest.Unmarshal(m, b)
+}
+func (m *PauseVMRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PauseVMRequest.Marshal(b, m, deterministic)
+}
+func (m *PauseVMRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PauseVMRequest.Merge(m, src)
+}
+func (m *PauseVMRequest) XXX_Size() int {
+	return xxx_messageInfo_PauseVMRequest.Size(m)
+}
+func (m *PauseVMRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_PauseVMRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PauseVMRequest proto.InternalMessageInfo
+
+func (m *PauseVMRequest) GetVMID() string {
+	if m != nil {
+		return m.VMID
+	}
+	return ""
+}
+
+type ResumeVMRequest struct {
+	VMID                 string   `protobuf:"bytes,1,opt,name=VMID,json=vMID,proto3" json:"VMID,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ResumeVMRequest) Reset()         { *m = ResumeVMRequest{} }
+func (m *ResumeVMRequest) String() string { return proto.CompactTextString(m) }
+func (*ResumeVMRequest) ProtoMessage()    {}
+func (*ResumeVMRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a73317e9fb8da571, []int{3}
+}
+func (m *ResumeVMRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ResumeVMRequest.Unmarshal(m, b)
+}
+func (m *ResumeVMRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ResumeVMRequest.Marshal(b, m, deterministic)
+}
+func (m *ResumeVMRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ResumeVMRequest.Merge(m, src)
+}
+func (m *ResumeVMRequest) XXX_Size() int {
+	return xxx_messageInfo_ResumeVMRequest.Size(m)
+}
+func (m *ResumeVMRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ResumeVMRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ResumeVMRequest proto.InternalMessageInfo
+
+func (m *ResumeVMRequest) GetVMID() string {
+	if m != nil {
+		return m.VMID
+	}
+	return ""
+}
+
 type StopVMRequest struct {
 	VMID                 string   `protobuf:"bytes,1,opt,name=VMID,json=vMID,proto3" json:"VMID,omitempty"`
 	TimeoutSeconds       uint32   `protobuf:"varint,2,opt,name=TimeoutSeconds,json=timeoutSeconds,proto3" json:"TimeoutSeconds,omitempty"`
@@ -275,7 +351,7 @@ func (m *StopVMRequest) Reset()         { *m = StopVMRequest{} }
 func (m *StopVMRequest) String() string { return proto.CompactTextString(m) }
 func (*StopVMRequest) ProtoMessage()    {}
 func (*StopVMRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{2}
+	return fileDescriptor_a73317e9fb8da571, []int{4}
 }
 func (m *StopVMRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_StopVMRequest.Unmarshal(m, b)
@@ -320,7 +396,7 @@ func (m *GetVMInfoRequest) Reset()         { *m = GetVMInfoRequest{} }
 func (m *GetVMInfoRequest) String() string { return proto.CompactTextString(m) }
 func (*GetVMInfoRequest) ProtoMessage()    {}
 func (*GetVMInfoRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{3}
+	return fileDescriptor_a73317e9fb8da571, []int{5}
 }
 func (m *GetVMInfoRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetVMInfoRequest.Unmarshal(m, b)
@@ -362,7 +438,7 @@ func (m *GetVMInfoResponse) Reset()         { *m = GetVMInfoResponse{} }
 func (m *GetVMInfoResponse) String() string { return proto.CompactTextString(m) }
 func (*GetVMInfoResponse) ProtoMessage()    {}
 func (*GetVMInfoResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{4}
+	return fileDescriptor_a73317e9fb8da571, []int{6}
 }
 func (m *GetVMInfoResponse) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetVMInfoResponse.Unmarshal(m, b)
@@ -429,7 +505,7 @@ func (m *SetVMMetadataRequest) Reset()         { *m = SetVMMetadataRequest{} }
 func (m *SetVMMetadataRequest) String() string { return proto.CompactTextString(m) }
 func (*SetVMMetadataRequest) ProtoMessage()    {}
 func (*SetVMMetadataRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{5}
+	return fileDescriptor_a73317e9fb8da571, []int{7}
 }
 func (m *SetVMMetadataRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_SetVMMetadataRequest.Unmarshal(m, b)
@@ -475,7 +551,7 @@ func (m *UpdateVMMetadataRequest) Reset()         { *m = UpdateVMMetadataRequest
 func (m *UpdateVMMetadataRequest) String() string { return proto.CompactTextString(m) }
 func (*UpdateVMMetadataRequest) ProtoMessage()    {}
 func (*UpdateVMMetadataRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{6}
+	return fileDescriptor_a73317e9fb8da571, []int{8}
 }
 func (m *UpdateVMMetadataRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_UpdateVMMetadataRequest.Unmarshal(m, b)
@@ -520,7 +596,7 @@ func (m *GetVMMetadataRequest) Reset()         { *m = GetVMMetadataRequest{} }
 func (m *GetVMMetadataRequest) String() string { return proto.CompactTextString(m) }
 func (*GetVMMetadataRequest) ProtoMessage()    {}
 func (*GetVMMetadataRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{7}
+	return fileDescriptor_a73317e9fb8da571, []int{9}
 }
 func (m *GetVMMetadataRequest) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetVMMetadataRequest.Unmarshal(m, b)
@@ -558,7 +634,7 @@ func (m *GetVMMetadataResponse) Reset()         { *m = GetVMMetadataResponse{} }
 func (m *GetVMMetadataResponse) String() string { return proto.CompactTextString(m) }
 func (*GetVMMetadataResponse) ProtoMessage()    {}
 func (*GetVMMetadataResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{8}
+	return fileDescriptor_a73317e9fb8da571, []int{10}
 }
 func (m *GetVMMetadataResponse) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_GetVMMetadataResponse.Unmarshal(m, b)
@@ -625,7 +701,7 @@ func (m *JailerConfig) Reset()         { *m = JailerConfig{} }
 func (m *JailerConfig) String() string { return proto.CompactTextString(m) }
 func (*JailerConfig) ProtoMessage()    {}
 func (*JailerConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_a73317e9fb8da571, []int{9}
+	return fileDescriptor_a73317e9fb8da571, []int{11}
 }
 func (m *JailerConfig) XXX_Unmarshal(b []byte) error {
 	return xxx_messageInfo_JailerConfig.Unmarshal(m, b)
@@ -698,6 +774,8 @@ func init() {
 	proto.RegisterEnum("DriveExposePolicy", DriveExposePolicy_name, DriveExposePolicy_value)
 	proto.RegisterType((*CreateVMRequest)(nil), "CreateVMRequest")
 	proto.RegisterType((*CreateVMResponse)(nil), "CreateVMResponse")
+	proto.RegisterType((*PauseVMRequest)(nil), "PauseVMRequest")
+	proto.RegisterType((*ResumeVMRequest)(nil), "ResumeVMRequest")
 	proto.RegisterType((*StopVMRequest)(nil), "StopVMRequest")
 	proto.RegisterType((*GetVMInfoRequest)(nil), "GetVMInfoRequest")
 	proto.RegisterType((*GetVMInfoResponse)(nil), "GetVMInfoResponse")
@@ -711,48 +789,49 @@ func init() {
 func init() { proto.RegisterFile("firecracker.proto", fileDescriptor_a73317e9fb8da571) }
 
 var fileDescriptor_a73317e9fb8da571 = []byte{
-	// 675 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0x41, 0x4f, 0xdb, 0x4a,
-	0x10, 0x7e, 0x26, 0x0e, 0x24, 0x63, 0x12, 0x92, 0x15, 0xbc, 0xb7, 0x42, 0x4f, 0xc8, 0xca, 0x81,
-	0x5a, 0x1c, 0x22, 0x15, 0x2e, 0x55, 0x4f, 0x40, 0x0c, 0xc8, 0x50, 0xa7, 0xd1, 0x86, 0x20, 0xb5,
-	0x37, 0xd7, 0x99, 0x04, 0x37, 0xb1, 0x37, 0xdd, 0xdd, 0x50, 0xf8, 0x5b, 0xed, 0x3f, 0xe9, 0x9f,
-	0xe9, 0xb5, 0xf2, 0x26, 0x24, 0x4e, 0x48, 0x11, 0x52, 0x4f, 0x3d, 0x65, 0xf7, 0x9b, 0x6f, 0x66,
-	0x3e, 0xcd, 0x37, 0x1b, 0x43, 0xb5, 0x17, 0x09, 0x0c, 0x45, 0x10, 0x0e, 0x50, 0xd4, 0x47, 0x82,
-	0x2b, 0xbe, 0x6b, 0xa9, 0x87, 0x11, 0xca, 0xc9, 0xa5, 0xf6, 0xd3, 0x84, 0xad, 0x86, 0xc0, 0x40,
-	0xe1, 0x8d, 0xcf, 0xf0, 0xcb, 0x18, 0xa5, 0x22, 0x04, 0xcc, 0x1b, 0xdf, 0x73, 0xa9, 0x61, 0x1b,
-	0x4e, 0x91, 0x99, 0x77, 0xbe, 0xe7, 0x92, 0x63, 0x00, 0x3f, 0x08, 0x6f, 0xa3, 0x04, 0x1b, 0xbd,
-	0x3e, 0x5d, 0xb3, 0x0d, 0xc7, 0x3a, 0xb4, 0xeb, 0xe7, 0xf3, 0xe2, 0x8f, 0x51, 0x9e, 0xf4, 0xa2,
-	0xfe, 0x58, 0x04, 0x2a, 0xe2, 0x09, 0x83, 0x78, 0x96, 0x43, 0x1c, 0xd8, 0xba, 0x42, 0x91, 0xe0,
-	0xd0, 0x8b, 0x83, 0x3e, 0xb6, 0x02, 0x75, 0x4b, 0x73, 0xba, 0xc1, 0xd6, 0x60, 0x11, 0x26, 0x7b,
-	0x00, 0x13, 0xe6, 0x89, 0xe8, 0x4b, 0x6a, 0x6a, 0x12, 0x0c, 0x66, 0x08, 0x39, 0x82, 0x22, 0xe3,
-	0x5c, 0xb9, 0x22, 0xba, 0x43, 0x9a, 0xd7, 0x52, 0x76, 0xb2, 0x52, 0x66, 0x41, 0x56, 0x14, 0x8f,
-	0x47, 0xf2, 0x06, 0x2c, 0x7d, 0xf0, 0xf9, 0x38, 0x51, 0x92, 0xae, 0xdb, 0x39, 0xc7, 0x3a, 0xfc,
-	0x37, 0x9b, 0x36, 0x0f, 0x33, 0xab, 0x3b, 0xa7, 0x92, 0x4b, 0xa8, 0x36, 0x51, 0x7d, 0xe5, 0x62,
-	0xe0, 0x25, 0x0a, 0x45, 0x2f, 0x08, 0x51, 0xd2, 0x0d, 0x9d, 0xff, 0x7f, 0x36, 0x7f, 0x99, 0xc4,
-	0xaa, 0xc9, 0x72, 0x1a, 0xd9, 0x87, 0x72, 0x83, 0x27, 0x2a, 0x88, 0x12, 0x14, 0x8d, 0xb4, 0x3c,
-	0x2d, 0xd8, 0x86, 0x93, 0x67, 0xe5, 0x70, 0x01, 0x25, 0x6f, 0x81, 0x9e, 0xdd, 0x47, 0xea, 0xa4,
-	0xa7, 0x50, 0x9c, 0x0c, 0x87, 0xd7, 0x81, 0x1c, 0x48, 0x17, 0x87, 0xa8, 0xb0, 0x4b, 0x8b, 0xb6,
-	0xe1, 0x14, 0x18, 0xc5, 0xdf, 0xc4, 0xc9, 0x6b, 0xd8, 0xbc, 0x0c, 0xa2, 0x61, 0x5a, 0x2a, 0xf5,
-	0x82, 0x82, 0x9e, 0x50, 0xa9, 0x9e, 0x05, 0xd9, 0xe6, 0xe7, 0xcc, 0x2d, 0x95, 0x75, 0x1d, 0xc5,
-	0xc8, 0xc7, 0xaa, 0x8d, 0x21, 0x4f, 0xba, 0x92, 0x5a, 0xb6, 0xe1, 0x94, 0x58, 0x59, 0x2d, 0xa0,
-	0xc4, 0x06, 0xeb, 0x1d, 0xef, 0x9f, 0x47, 0x3d, 0xae, 0xfd, 0xdb, 0xd4, 0xd6, 0x58, 0xc3, 0x39,
-	0x94, 0xba, 0xec, 0xa3, 0x12, 0x51, 0x28, 0x67, 0xac, 0xd2, 0xc4, 0xe5, 0x78, 0x11, 0xae, 0x7d,
-	0x33, 0xa0, 0x32, 0xdf, 0x3c, 0x39, 0xe2, 0x89, 0xc4, 0x95, 0xab, 0xb7, 0x07, 0xd0, 0xe6, 0xe1,
-	0x00, 0x95, 0xae, 0xb6, 0x36, 0x59, 0x07, 0x39, 0x43, 0x96, 0x45, 0xe5, 0x5e, 0x24, 0xca, 0x5c,
-	0x29, 0x2a, 0xed, 0xd5, 0xe8, 0x0b, 0x3e, 0x1e, 0x69, 0x52, 0x7e, 0xd2, 0x2b, 0x9c, 0x21, 0xb5,
-	0x2b, 0x28, 0xb5, 0x15, 0x1f, 0x3d, 0xff, 0x56, 0x9e, 0x4e, 0x73, 0x6d, 0xd5, 0x34, 0x6b, 0xfb,
-	0x50, 0xb9, 0x40, 0x75, 0xe3, 0x7b, 0x49, 0x8f, 0x3f, 0x53, 0xaf, 0xf6, 0xdd, 0x80, 0x6a, 0x86,
-	0xf8, 0x97, 0x8c, 0xea, 0x1c, 0xb6, 0xdb, 0xa9, 0x68, 0x1f, 0x55, 0xd0, 0x0d, 0x54, 0xf0, 0xdc,
-	0xc4, 0x76, 0xa1, 0xf0, 0x48, 0x9b, 0xaa, 0x2e, 0xc4, 0xd3, 0x7b, 0xcd, 0x83, 0xff, 0x3a, 0xa3,
-	0xae, 0x5e, 0x93, 0x3f, 0x2d, 0x75, 0x00, 0xdb, 0x17, 0x2f, 0x94, 0x54, 0x3b, 0x82, 0x9d, 0x25,
-	0xee, 0x74, 0xee, 0xd9, 0x06, 0xc6, 0x52, 0x83, 0x1f, 0xc6, 0xe2, 0xdb, 0x23, 0xdb, 0x90, 0x6f,
-	0xa2, 0x6a, 0xb6, 0xa7, 0xcc, 0x7c, 0x92, 0x5e, 0xd2, 0x7e, 0x8d, 0x56, 0x47, 0x4e, 0xf5, 0x99,
-	0x61, 0xab, 0x23, 0x53, 0xcc, 0xc7, 0x58, 0x4e, 0x3d, 0x31, 0x63, 0x8c, 0x25, 0xa9, 0x40, 0xae,
-	0xe3, 0xb9, 0xda, 0x80, 0x12, 0xcb, 0x8d, 0x3d, 0x37, 0x45, 0x2e, 0x3c, 0x57, 0x4f, 0xbb, 0xc4,
-	0x72, 0xfd, 0x89, 0xe5, 0x19, 0x1b, 0xd6, 0x97, 0x6d, 0x20, 0xc7, 0x50, 0xd5, 0x7f, 0x6c, 0x67,
-	0xf7, 0x23, 0x2e, 0xb1, 0xc5, 0x87, 0x51, 0xf8, 0x40, 0x37, 0x6c, 0xc3, 0x29, 0x1f, 0x92, 0xfa,
-	0x93, 0x08, 0xab, 0x76, 0x97, 0xa1, 0x83, 0x57, 0x2b, 0x2a, 0x90, 0x02, 0x98, 0x8d, 0xf7, 0xad,
-	0x0f, 0x95, 0x7f, 0xd2, 0xd3, 0xa9, 0xd7, 0x74, 0x2b, 0xc6, 0xe9, 0xc6, 0xc7, 0xbc, 0xfe, 0xa8,
-	0x7c, 0x5a, 0xd7, 0x3f, 0x47, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x92, 0x20, 0x20, 0x7d,
-	0x06, 0x00, 0x00,
+	// 693 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0xdf, 0x4f, 0xdb, 0x48,
+	0x10, 0x3e, 0x13, 0x07, 0x92, 0x31, 0xf9, 0xb5, 0x82, 0x3b, 0x0b, 0x9d, 0x90, 0x15, 0xdd, 0x71,
+	0x16, 0x0f, 0x91, 0x0e, 0x5e, 0x4e, 0xf7, 0x04, 0xc4, 0x80, 0x0c, 0x75, 0x1a, 0x6d, 0x08, 0x52,
+	0xfb, 0xe6, 0x3a, 0x93, 0xe0, 0x26, 0xf6, 0xa6, 0xbb, 0x6b, 0x0a, 0xff, 0x56, 0xfb, 0x9f, 0xf4,
+	0x9f, 0xe9, 0x6b, 0xe5, 0x4d, 0x48, 0x9c, 0x90, 0xa6, 0x48, 0x7d, 0xea, 0x53, 0x76, 0xbf, 0xf9,
+	0x66, 0xe6, 0xd3, 0x7c, 0xb3, 0x31, 0xd4, 0xfa, 0x21, 0xc7, 0x80, 0xfb, 0xc1, 0x10, 0x79, 0x63,
+	0xcc, 0x99, 0x64, 0x7b, 0x86, 0x7c, 0x1c, 0xa3, 0x98, 0x5c, 0xea, 0x5f, 0x75, 0xa8, 0x34, 0x39,
+	0xfa, 0x12, 0x6f, 0x3d, 0x8a, 0x1f, 0x12, 0x14, 0x92, 0x10, 0xd0, 0x6f, 0x3d, 0xd7, 0x31, 0x35,
+	0x4b, 0xb3, 0x8b, 0x54, 0xbf, 0xf7, 0x5c, 0x87, 0x9c, 0x00, 0x78, 0x7e, 0x70, 0x17, 0xc6, 0xd8,
+	0xec, 0x0f, 0xcc, 0x0d, 0x4b, 0xb3, 0x8d, 0x23, 0xab, 0x71, 0x31, 0x2f, 0xfe, 0x14, 0x65, 0x71,
+	0x3f, 0x1c, 0x24, 0xdc, 0x97, 0x21, 0x8b, 0x29, 0x44, 0xb3, 0x1c, 0x62, 0x43, 0xe5, 0x1a, 0x79,
+	0x8c, 0x23, 0x37, 0xf2, 0x07, 0xd8, 0xf6, 0xe5, 0x9d, 0x99, 0x53, 0x0d, 0x2a, 0xc3, 0x45, 0x98,
+	0xec, 0x03, 0x4c, 0x98, 0xa7, 0x7c, 0x20, 0x4c, 0x5d, 0x91, 0x60, 0x38, 0x43, 0xc8, 0x31, 0x14,
+	0x29, 0x63, 0xd2, 0xe1, 0xe1, 0x3d, 0x9a, 0x79, 0x25, 0x65, 0x37, 0x2b, 0x65, 0x16, 0xa4, 0x45,
+	0xfe, 0x74, 0x24, 0xff, 0x81, 0xa1, 0x0e, 0x1e, 0x4b, 0x62, 0x29, 0xcc, 0x4d, 0x2b, 0x67, 0x1b,
+	0x47, 0xbf, 0x67, 0xd3, 0xe6, 0x61, 0x6a, 0xf4, 0xe6, 0x54, 0x72, 0x05, 0xb5, 0x16, 0xca, 0x8f,
+	0x8c, 0x0f, 0xdd, 0x58, 0x22, 0xef, 0xfb, 0x01, 0x0a, 0x73, 0x4b, 0xe5, 0xff, 0x99, 0xcd, 0x5f,
+	0x26, 0xd1, 0x5a, 0xbc, 0x9c, 0x46, 0x0e, 0xa0, 0xdc, 0x64, 0xb1, 0xf4, 0xc3, 0x18, 0x79, 0x33,
+	0x2d, 0x6f, 0x16, 0x2c, 0xcd, 0xce, 0xd3, 0x72, 0xb0, 0x80, 0x92, 0xff, 0xc1, 0x3c, 0x7f, 0x08,
+	0xe5, 0x69, 0x5f, 0x22, 0x3f, 0x1d, 0x8d, 0x6e, 0x7c, 0x31, 0x14, 0x0e, 0x8e, 0x50, 0x62, 0xcf,
+	0x2c, 0x5a, 0x9a, 0x5d, 0xa0, 0x26, 0x7e, 0x27, 0x4e, 0xfe, 0x85, 0xed, 0x2b, 0x3f, 0x1c, 0xa5,
+	0xa5, 0x52, 0x2f, 0x4c, 0x50, 0x13, 0x2a, 0x35, 0xb2, 0x20, 0xdd, 0x7e, 0x9f, 0xb9, 0xa5, 0xb2,
+	0x6e, 0xc2, 0x08, 0x59, 0x22, 0x3b, 0x18, 0xb0, 0xb8, 0x27, 0x4c, 0xc3, 0xd2, 0xec, 0x12, 0x2d,
+	0xcb, 0x05, 0x94, 0x58, 0x60, 0xbc, 0x62, 0x83, 0x8b, 0xb0, 0xcf, 0x94, 0x7f, 0xdb, 0xca, 0x1a,
+	0x63, 0x34, 0x87, 0x52, 0x97, 0x3d, 0x94, 0x3c, 0x0c, 0xc4, 0x8c, 0x55, 0x9a, 0xb8, 0x1c, 0x2d,
+	0xc2, 0xf5, 0x4f, 0x1a, 0x54, 0xe7, 0x9b, 0x27, 0xc6, 0x2c, 0x16, 0xb8, 0x72, 0xf5, 0xf6, 0x01,
+	0x3a, 0x2c, 0x18, 0xa2, 0x54, 0xd5, 0x36, 0x26, 0xeb, 0x20, 0x66, 0xc8, 0xb2, 0xa8, 0xdc, 0x8b,
+	0x44, 0xe9, 0x2b, 0x45, 0xa5, 0xbd, 0x9a, 0x03, 0xce, 0x92, 0xb1, 0x22, 0xe5, 0x27, 0xbd, 0x82,
+	0x19, 0x52, 0xff, 0x0b, 0xca, 0x6d, 0x3f, 0x11, 0xeb, 0x1f, 0x4b, 0xfd, 0x6f, 0xa8, 0x50, 0x14,
+	0x49, 0xf4, 0x03, 0xda, 0x35, 0x94, 0x3a, 0x92, 0x8d, 0xd7, 0x3f, 0xbc, 0xe7, 0xd6, 0x6c, 0xac,
+	0xb2, 0xa6, 0x7e, 0x00, 0xd5, 0x4b, 0x94, 0xb7, 0x9e, 0x1b, 0xf7, 0xd9, 0xba, 0xa6, 0x9f, 0x35,
+	0xa8, 0x65, 0x88, 0xbf, 0xc8, 0xdc, 0x2f, 0x60, 0xa7, 0x93, 0x8a, 0xf6, 0x50, 0xfa, 0x3d, 0x5f,
+	0xfa, 0xeb, 0x26, 0xb6, 0x07, 0x85, 0x27, 0xda, 0x54, 0x75, 0x21, 0x9a, 0xde, 0xeb, 0x2e, 0xfc,
+	0xd1, 0x1d, 0xf7, 0xd4, 0xce, 0xfd, 0x6c, 0xa9, 0x43, 0xd8, 0xb9, 0x7c, 0xa1, 0xa4, 0xfa, 0x31,
+	0xec, 0x2e, 0x71, 0xa7, 0x73, 0xcf, 0x36, 0xd0, 0x96, 0x1a, 0x7c, 0xd1, 0x16, 0x1f, 0x32, 0xd9,
+	0x81, 0x7c, 0x0b, 0x65, 0xab, 0x33, 0x65, 0xe6, 0xe3, 0xf4, 0x92, 0xf6, 0x6b, 0xb6, 0xbb, 0x62,
+	0xaa, 0x4f, 0x0f, 0xda, 0x5d, 0x91, 0x62, 0x1e, 0x46, 0x62, 0xea, 0x89, 0x1e, 0x61, 0x24, 0x48,
+	0x15, 0x72, 0x5d, 0xd7, 0x51, 0x06, 0x94, 0x68, 0x2e, 0x71, 0x9d, 0x14, 0xb9, 0x74, 0x1d, 0x35,
+	0xed, 0x12, 0xcd, 0x0d, 0x26, 0x96, 0x67, 0x6c, 0xd8, 0x5c, 0xb6, 0x81, 0x9c, 0x40, 0x4d, 0xfd,
+	0x4b, 0x9e, 0x3f, 0x8c, 0x99, 0xc0, 0x36, 0x1b, 0x85, 0xc1, 0xa3, 0xb9, 0x65, 0x69, 0x76, 0xf9,
+	0x88, 0x34, 0x9e, 0x45, 0x68, 0xad, 0xb7, 0x0c, 0x1d, 0xfe, 0xb3, 0xa2, 0x02, 0x29, 0x80, 0xde,
+	0x7c, 0xdd, 0x7e, 0x53, 0xfd, 0x2d, 0x3d, 0x9d, 0xb9, 0x2d, 0xa7, 0xaa, 0x9d, 0x6d, 0xbd, 0xcd,
+	0xab, 0x2f, 0xd4, 0xbb, 0x4d, 0xf5, 0x73, 0xfc, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x74, 0xd8,
+	0x91, 0xca, 0x06, 0x00, 0x00,
 }
diff --git a/proto/firecracker.proto b/proto/firecracker.proto
index f97c06a..f077234 100644
--- a/proto/firecracker.proto
+++ b/proto/firecracker.proto
@@ -49,6 +49,14 @@ message CreateVMResponse {
     string CgroupPath = 5;
 }
 
+message PauseVMRequest {
+    string VMID = 1;
+}
+
+message ResumeVMRequest {
+    string VMID = 1;
+}
+
 message StopVMRequest {
     string VMID = 1;
     uint32 TimeoutSeconds = 2;
diff --git a/proto/service/fccontrol/fccontrol.proto b/proto/service/fccontrol/fccontrol.proto
index a55ff09..526fe59 100644
--- a/proto/service/fccontrol/fccontrol.proto
+++ b/proto/service/fccontrol/fccontrol.proto
@@ -10,6 +10,12 @@ service Firecracker {
     // Runs new Firecracker VM instance
     rpc CreateVM(CreateVMRequest) returns (CreateVMResponse);
 
+    // Pauses a VM
+    rpc PauseVM(PauseVMRequest) returns (google.protobuf.Empty);
+
+    // Resumes a VM
+    rpc ResumeVM(ResumeVMRequest) returns (google.protobuf.Empty);
+
     // Stops existing Firecracker instance by VM ID
     rpc StopVM(StopVMRequest) returns (google.protobuf.Empty);
 
diff --git a/proto/service/fccontrol/ttrpc/fccontrol.pb.go b/proto/service/fccontrol/ttrpc/fccontrol.pb.go
index 9ffb89b..7200644 100644
--- a/proto/service/fccontrol/ttrpc/fccontrol.pb.go
+++ b/proto/service/fccontrol/ttrpc/fccontrol.pb.go
@@ -27,28 +27,32 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 func init() { proto.RegisterFile("fccontrol.proto", fileDescriptor_b99f53e2bf82c5ef) }
 
 var fileDescriptor_b99f53e2bf82c5ef = []byte{
-	// 261 bytes of a gzipped FileDescriptorProto
+	// 290 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0x4b, 0x4e, 0xce,
 	0xcf, 0x2b, 0x29, 0xca, 0xcf, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x97, 0x92, 0x4e, 0xcf, 0xcf,
 	0x4f, 0xcf, 0x49, 0xd5, 0x07, 0xf3, 0x92, 0x4a, 0xd3, 0xf4, 0x53, 0x73, 0x0b, 0x4a, 0x2a, 0xa1,
 	0x92, 0x82, 0x69, 0x99, 0x45, 0xa9, 0xc9, 0x45, 0x89, 0xc9, 0xd9, 0xa9, 0x45, 0x10, 0x21, 0xa3,
-	0x57, 0x4c, 0x5c, 0xdc, 0x6e, 0x08, 0x51, 0x21, 0x7d, 0x2e, 0x0e, 0xe7, 0xa2, 0xd4, 0xc4, 0x92,
+	0x2b, 0xcc, 0x5c, 0xdc, 0x6e, 0x08, 0x51, 0x21, 0x7d, 0x2e, 0x0e, 0xe7, 0xa2, 0xd4, 0xc4, 0x92,
 	0xd4, 0x30, 0x5f, 0x21, 0x01, 0x3d, 0x18, 0x33, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x4a,
-	0x10, 0x49, 0xa4, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, 0x80, 0x8b, 0x2d, 0xb8, 0x24, 0xbf,
-	0x20, 0xcc, 0x57, 0x88, 0x4f, 0x0f, 0xc2, 0x80, 0x29, 0x16, 0xd3, 0x83, 0xb8, 0x45, 0x0f, 0xe6,
-	0x16, 0x3d, 0x57, 0x90, 0x5b, 0x84, 0x8c, 0xb8, 0x38, 0xdd, 0x53, 0x4b, 0xc2, 0x7c, 0x3d, 0xf3,
-	0xd2, 0xf2, 0x85, 0x04, 0xf5, 0xe0, 0x6c, 0x98, 0x3e, 0x21, 0x64, 0x21, 0xa8, 0x2d, 0x76, 0x5c,
-	0xbc, 0xc1, 0x20, 0x41, 0xdf, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x21, 0x51, 0x3d, 0x14,
-	0x3e, 0x21, 0x3b, 0x5d, 0xb8, 0x04, 0x42, 0x0b, 0x52, 0xc0, 0x2e, 0x87, 0x1b, 0x21, 0xa1, 0x87,
-	0x2e, 0x44, 0xc8, 0x14, 0x3b, 0x2e, 0x5e, 0x77, 0x34, 0x57, 0xb8, 0x63, 0x77, 0x05, 0x9a, 0x30,
-	0xc4, 0x17, 0x4e, 0xca, 0x27, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xd0, 0xf0, 0x48, 0x8e,
-	0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x8c, 0xe2, 0x84,
-	0xc7, 0x63, 0x12, 0x1b, 0xd8, 0x52, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0c, 0x15, 0x3e,
-	0x05, 0xdb, 0x01, 0x00, 0x00,
+	0x10, 0x49, 0xa4, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, 0x88, 0x8b, 0x3d, 0x20, 0xb1, 0xb4,
+	0x18, 0xa4, 0x9e, 0x5f, 0x0f, 0xca, 0x82, 0x29, 0x17, 0xd3, 0x83, 0xb8, 0x46, 0x0f, 0xe6, 0x1a,
+	0x3d, 0x57, 0x90, 0x6b, 0x84, 0x4c, 0xb8, 0x38, 0x82, 0x52, 0x8b, 0x4b, 0x73, 0x21, 0x96, 0xc0,
+	0x98, 0x84, 0x74, 0x19, 0x70, 0xb1, 0x05, 0x97, 0xe4, 0x17, 0x84, 0xf9, 0x0a, 0xf1, 0xe9, 0x41,
+	0x18, 0x84, 0x74, 0x18, 0x71, 0x71, 0xba, 0xa7, 0x96, 0x84, 0xf9, 0x7a, 0xe6, 0xa5, 0xe5, 0x0b,
+	0x09, 0xea, 0xc1, 0xd9, 0x30, 0x7d, 0x42, 0xc8, 0x42, 0x50, 0xff, 0xd8, 0x71, 0xf1, 0x06, 0x83,
+	0x04, 0x7d, 0x53, 0x4b, 0x12, 0x53, 0x12, 0x4b, 0x12, 0x85, 0x44, 0xf5, 0x50, 0xf8, 0x84, 0xec,
+	0x74, 0xe1, 0x12, 0x08, 0x2d, 0x48, 0x01, 0x87, 0x11, 0xdc, 0x08, 0x09, 0x3d, 0x74, 0x21, 0x42,
+	0xa6, 0xd8, 0x71, 0xf1, 0xba, 0xa3, 0xb9, 0xc2, 0x1d, 0xbb, 0x2b, 0xd0, 0x84, 0x21, 0xbe, 0x70,
+	0x52, 0x3e, 0xf1, 0x50, 0x8e, 0xe1, 0xc6, 0x43, 0x39, 0x86, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x1e,
+	0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0x63, 0x14, 0x27, 0x3c, 0xc5, 0x24,
+	0xb1, 0x81, 0x2d, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x26, 0xe6, 0x13, 0x45, 0x02,
+	0x00, 0x00,
 }
 
 type FirecrackerService interface {
 	CreateVM(ctx context.Context, req *proto1.CreateVMRequest) (*proto1.CreateVMResponse, error)
+	PauseVM(ctx context.Context, req *proto1.PauseVMRequest) (*empty.Empty, error)
+	ResumeVM(ctx context.Context, req *proto1.ResumeVMRequest) (*empty.Empty, error)
 	StopVM(ctx context.Context, req *proto1.StopVMRequest) (*empty.Empty, error)
 	GetVMInfo(ctx context.Context, req *proto1.GetVMInfoRequest) (*proto1.GetVMInfoResponse, error)
 	SetVMMetadata(ctx context.Context, req *proto1.SetVMMetadataRequest) (*empty.Empty, error)
@@ -65,6 +69,20 @@ func RegisterFirecrackerService(srv *github_com_containerd_ttrpc.Server, svc Fir
 			}
 			return svc.CreateVM(ctx, &req)
 		},
+		"PauseVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
+			var req proto1.PauseVMRequest
+			if err := unmarshal(&req); err != nil {
+				return nil, err
+			}
+			return svc.PauseVM(ctx, &req)
+		},
+		"ResumeVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
+			var req proto1.ResumeVMRequest
+			if err := unmarshal(&req); err != nil {
+				return nil, err
+			}
+			return svc.ResumeVM(ctx, &req)
+		},
 		"StopVM": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
 			var req proto1.StopVMRequest
 			if err := unmarshal(&req); err != nil {
@@ -121,6 +139,22 @@ func (c *firecrackerClient) CreateVM(ctx context.Context, req *proto1.CreateVMRe
 	return &resp, nil
 }
 
+func (c *firecrackerClient) PauseVM(ctx context.Context, req *proto1.PauseVMRequest) (*empty.Empty, error) {
+	var resp empty.Empty
+	if err := c.client.Call(ctx, "Firecracker", "PauseVM", req, &resp); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+func (c *firecrackerClient) ResumeVM(ctx context.Context, req *proto1.ResumeVMRequest) (*empty.Empty, error) {
+	var resp empty.Empty
+	if err := c.client.Call(ctx, "Firecracker", "ResumeVM", req, &resp); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
 func (c *firecrackerClient) StopVM(ctx context.Context, req *proto1.StopVMRequest) (*empty.Empty, error) {
 	var resp empty.Empty
 	if err := c.client.Call(ctx, "Firecracker", "StopVM", req, &resp); err != nil {
diff --git a/runtime/service.go b/runtime/service.go
index b62ed5f..dd3bcde 100644
--- a/runtime/service.go
+++ b/runtime/service.go
@@ -634,6 +634,42 @@ func (s *service) StopVM(requestCtx context.Context, request *proto.StopVMReques
 	return &empty.Empty{}, nil
 }
 
+// ResumeVM resumes a VM
+func (s *service) ResumeVM(ctx context.Context, req *proto.ResumeVMRequest) (*empty.Empty, error) {
+	defer logPanicAndDie(s.logger)
+
+	err := s.waitVMReady()
+	if err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	if err := s.machine.ResumeVM(ctx); err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	return &empty.Empty{}, nil
+}
+
+// PauseVM pauses a VM
+func (s *service) PauseVM(ctx context.Context, req *proto.PauseVMRequest) (*empty.Empty, error) {
+	defer logPanicAndDie(s.logger)
+
+	err := s.waitVMReady()
+	if err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	if err := s.machine.PauseVM(ctx); err != nil {
+		s.logger.WithError(err).Error()
+		return nil, err
+	}
+
+	return &empty.Empty{}, nil
+}
+
 // GetVMInfo returns metadata for the VM being managed by this shim. If the VM has not been created yet, this
 // method will wait for up to a hardcoded timeout for it to exist, returning an error if the timeout is reached.
 func (s *service) GetVMInfo(requestCtx context.Context, request *proto.GetVMInfoRequest) (*proto.GetVMInfoResponse, error) {


Test patch:
diff --git a/runtime/cni_integ_test.go b/runtime/cni_integ_test.go
index 280778c..56b44bf 100644
--- a/runtime/cni_integ_test.go
+++ b/runtime/cni_integ_test.go
@@ -24,11 +24,11 @@ import (
 	"testing"
 	"time"
 
+	args "github.com/awslabs/tc-redirect-tap/cmd/tc-redirect-tap/args"
 	"github.com/containerd/containerd"
 	"github.com/containerd/containerd/namespaces"
 	"github.com/containerd/containerd/oci"
 	"github.com/containerd/containerd/pkg/ttrpcutil"
-	"github.com/firecracker-microvm/firecracker-go-sdk/cni/cmd/tc-redirect-tap/args"
 	"github.com/shirou/gopsutil/cpu"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
diff --git a/runtime/service_integ_test.go b/runtime/service_integ_test.go
index c3bb831..3c1ed55 100644
--- a/runtime/service_integ_test.go
+++ b/runtime/service_integ_test.go
@@ -2032,6 +2032,139 @@ func TestCreateVM_Isolated(t *testing.T) {
 	}
 }
 
+func TestPauseResume(t *testing.T) {
+	prepareIntegTest(t)
+
+	client, err := containerd.New(containerdSockPath, containerd.WithDefaultRuntime(firecrackerRuntime))
+	require.NoError(t, err, "unable to create client to containerd service at %s, is containerd running?", containerdSockPath)
+	defer client.Close()
+
+	ctx := namespaces.WithNamespace(context.Background(), "default")
+
+	pluginClient, err := ttrpcutil.NewClient(containerdSockPath + ".ttrpc")
+	require.NoError(t, err, "failed to create ttrpc client")
+
+	fcClient := fccontrol.NewFirecrackerClient(pluginClient.Client())
+
+	subtests := []struct {
+		name    string
+		request *proto.CreateVMRequest
+		state   func(ctx context.Context, resp *proto.CreateVMResponse)
+	}{
+		{
+			name:    "PauseVM",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.PauseVM(ctx, &proto.PauseVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+		{
+			name:    "ResumeVM",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.ResumeVM(ctx, &proto.ResumeVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+		{
+			name:    "Consecutive PauseVM",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.PauseVM(ctx, &proto.PauseVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+
+				_, err = fcClient.PauseVM(ctx, &proto.PauseVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+		{
+			name:    "Consecutive ResumeVM",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.ResumeVM(ctx, &proto.ResumeVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+
+				_, err = fcClient.ResumeVM(ctx, &proto.ResumeVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+		{
+			name:    "PauseResume",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.PauseVM(ctx, &proto.PauseVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+
+				_, err = fcClient.ResumeVM(ctx, &proto.ResumeVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+		{
+			name:    "ResumePause",
+			request: &proto.CreateVMRequest{},
+			state: func(ctx context.Context, resp *proto.CreateVMResponse) {
+				_, err := fcClient.ResumeVM(ctx, &proto.ResumeVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+
+				_, err = fcClient.PauseVM(ctx, &proto.PauseVMRequest{VMID: resp.VMID})
+				require.NoError(t, err)
+			},
+		},
+	}
+
+	runTest := func(t *testing.T, request *proto.CreateVMRequest, state func(ctx context.Context, resp *proto.CreateVMResponse)) {
+		vmID := testNameToVMID(t.Name())
+
+		tempDir, err := ioutil.TempDir("", vmID)
+		require.NoError(t, err)
+		defer os.RemoveAll(tempDir)
+
+		logFile := filepath.Join(tempDir, "log.fifo")
+		metricsFile := filepath.Join(tempDir, "metrics.fifo")
+
+		request.VMID = vmID
+		request.LogFifoPath = logFile
+		request.MetricsFifoPath = metricsFile
+
+		resp, createVMErr := fcClient.CreateVM(ctx, request)
+
+		// Even CreateVM fails, the log file and the metrics file must have some data.
+		requireNonEmptyFifo(t, logFile)
+		requireNonEmptyFifo(t, metricsFile)
+
+		// Run test case
+		state(ctx, resp)
+
+		// No VM to stop.
+		if createVMErr != nil {
+			return
+		}
+
+		// Ensure the response fields are populated correctly
+		assert.Equal(t, request.VMID, resp.VMID)
+
+		_, err = fcClient.StopVM(ctx, &proto.StopVMRequest{VMID: request.VMID})
+		require.Equal(t, status.Code(err), codes.OK)
+	}
+
+	for _, subtest := range subtests {
+		state := subtest.state
+		request := subtest.request
+		t.Run(subtest.name, func(t *testing.T) {
+			runTest(t, request, state)
+		})
+
+		requestWithJailer := subtest.request
+		requestWithJailer.JailerConfig = &proto.JailerConfig{
+			UID: 30000,
+			GID: 30000,
+		}
+		t.Run(subtest.name+"/Jailer", func(t *testing.T) {
+			runTest(t, requestWithJailer, state)
+		})
+	}
+}
 func TestAttach_Isolated(t *testing.T) {
 	prepareIntegTest(t)