Skip to content

Commit 3b71606

Browse files
authored
Merge pull request #306 from xibz/jailer-cgroup-path-clean
Adds cgroup path to CreateVMResponse
2 parents a922bc4 + 7fe8c50 commit 3b71606

File tree

11 files changed

+206
-88
lines changed

11 files changed

+206
-88
lines changed

firecracker-control/local.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func newLocal(ic *plugin.InitContext) (*local, error) {
7878
// CreateVM creates new Firecracker VM instance. It creates a runtime shim for the VM and the forwards
7979
// the CreateVM request to that shim. If there is already a VM created with the provided VMID, then
8080
// AlreadyExists is returned.
81-
func (s *local) CreateVM(requestCtx context.Context, req *proto.CreateVMRequest) (*empty.Empty, error) {
81+
func (s *local) CreateVM(requestCtx context.Context, req *proto.CreateVMRequest) (*proto.CreateVMResponse, error) {
8282
var err error
8383

8484
id := req.GetVMID()

firecracker-control/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (s *service) RegisterTTRPC(server *ttrpc.Server) error {
6767
return nil
6868
}
6969

70-
func (s *service) CreateVM(ctx context.Context, req *proto.CreateVMRequest) (*empty.Empty, error) {
70+
func (s *service) CreateVM(ctx context.Context, req *proto.CreateVMRequest) (*proto.CreateVMResponse, error) {
7171
log.G(ctx).Debugf("create VM request: %+v", req)
7272
return s.local.CreateVM(ctx, req)
7373
}

proto/firecracker.pb.go

Lines changed: 126 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/firecracker.proto

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ message CreateVMRequest {
3636
JailerConfig JailerConfig = 10;
3737
}
3838

39+
message CreateVMResponse {
40+
string VMID = 1;
41+
string SocketPath = 2;
42+
string LogFifoPath = 3;
43+
string MetricsFifoPath = 4;
44+
string CgroupPath = 5;
45+
}
46+
3947
message StopVMRequest {
4048
string VMID = 1;
4149
uint32 TimeoutSeconds = 2;
@@ -47,10 +55,10 @@ message GetVMInfoRequest {
4755

4856
message GetVMInfoResponse {
4957
string VMID = 1;
50-
uint32 ContextID = 2;
51-
string SocketPath = 3;
52-
string LogFifoPath = 4;
53-
string MetricsFifoPath = 5;
58+
string SocketPath = 2;
59+
string LogFifoPath = 3;
60+
string MetricsFifoPath = 4;
61+
string CgroupPath = 5;
5462
}
5563

5664
message SetVMMetadataRequest {

proto/service/fccontrol/fccontrol.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ option go_package = "fccontrol";
88

99
service Firecracker {
1010
// Runs new Firecracker VM instance
11-
rpc CreateVM(CreateVMRequest) returns (google.protobuf.Empty);
11+
rpc CreateVM(CreateVMRequest) returns (CreateVMResponse);
1212

1313
// Stops existing Firecracker instance by VM ID
1414
rpc StopVM(StopVMRequest) returns (google.protobuf.Empty);

proto/service/fccontrol/ttrpc/fccontrol.pb.go

Lines changed: 16 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/jailer.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type jailer interface {
5858
StubDrivesOptions() []stubDrivesOpt
5959
}
6060

61+
type cgroupPather interface {
62+
CgroupPath() string
63+
}
64+
6165
// newJailer is used to construct a jailer from the CreateVM request. If no
6266
// request or jailer config was provided, then the noopJailer will be returned.
6367
func newJailer(
@@ -73,5 +77,13 @@ func newJailer(
7377
}
7478

7579
l := logger.WithField("jailer", "runc")
76-
return newRuncJailer(ctx, l, ociBundlePath, service.config.JailerConfig.RuncBinaryPath, jailerUID, jailerGID)
80+
return newRuncJailer(
81+
ctx,
82+
l,
83+
service.vmID,
84+
ociBundlePath,
85+
service.config.JailerConfig.RuncBinaryPath,
86+
jailerUID,
87+
jailerGID,
88+
)
7789
}

runtime/runc_jailer.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,29 @@ type runcJailer struct {
5050
runcBinaryPath string
5151
uid uint32
5252
gid uint32
53+
vmID string
5354
configSpec specs.Spec
5455
}
5556

5657
const firecrackerFileName = "firecracker"
5758

58-
func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, runcBinPath string, uid, gid uint32) (*runcJailer, error) {
59-
l := logger.WithField("ociBundlePath", ociBundlePath).
60-
WithField("runcBinaryPath", runcBinPath)
61-
59+
func newRuncJailer(
60+
ctx context.Context,
61+
logger *logrus.Entry,
62+
vmID string,
63+
ociBundlePath string,
64+
runcBinaryPath string,
65+
uid uint32,
66+
gid uint32) (*runcJailer, error) {
67+
l := logger.WithField("ociBundlePath", ociBundlePath).WithField("runcBinaryPath", runcBinaryPath)
6268
j := &runcJailer{
6369
ctx: ctx,
6470
logger: l,
6571
ociBundlePath: ociBundlePath,
66-
runcBinaryPath: runcBinPath,
72+
runcBinaryPath: runcBinaryPath,
6773
uid: uid,
6874
gid: gid,
75+
vmID: vmID,
6976
}
7077

7178
spec := specs.Spec{}
@@ -418,6 +425,10 @@ func (j *runcJailer) overwriteConfig(cfg *Config, machineConfig *firecracker.Con
418425
return nil
419426
}
420427

428+
func (j runcJailer) CgroupPath() string {
429+
return filepath.Join("/firecracker-containerd", j.vmID)
430+
}
431+
421432
// setDefaultConfigValues will process the spec file provided and allow any
422433
// empty/zero values to be replaced with default values.
423434
func (j *runcJailer) setDefaultConfigValues(cfg *Config, socketPath string, spec specs.Spec) specs.Spec {
@@ -436,6 +447,10 @@ func (j *runcJailer) setDefaultConfigValues(cfg *Config, socketPath string, spec
436447
spec.Process.Args = cmd.Args
437448
}
438449

450+
cgroupPath := j.CgroupPath()
451+
j.logger.WithField("CgroupPath", cgroupPath).Debug("using cgroup path")
452+
spec.Linux.CgroupsPath = cgroupPath
453+
439454
return spec
440455
}
441456

runtime/runc_jailer_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ func TestBuildJailedRootHandler_Isolated(t *testing.T) {
5353
defer firecrackerFd.Close()
5454

5555
l := logrus.NewEntry(logrus.New())
56-
jailer, err := newRuncJailer(context.Background(), l, dir, "bin-path", 123, 456)
56+
vmID := "foo"
57+
jailer, err := newRuncJailer(context.Background(), l, vmID, dir, "path/to/runc", 123, 456)
5758
require.NoError(t, err, "failed to create runc jailer")
5859

5960
cfg := Config{
@@ -72,7 +73,6 @@ func TestBuildJailedRootHandler_Isolated(t *testing.T) {
7273
},
7374
},
7475
}
75-
vmID := "foo"
7676
handler := jailer.BuildJailedRootHandler(&cfg, &machineConfig, vmID)
7777

7878
machine := firecracker.Machine{

runtime/service.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,13 @@ func (s *service) waitVMReady() error {
410410

411411
// CreateVM will attempt to create the VM as specified in the provided request, but only on the first request
412412
// received. Any subsequent requests will be ignored and get an AlreadyExists error response.
413-
func (s *service) CreateVM(requestCtx context.Context, request *proto.CreateVMRequest) (*empty.Empty, error) {
413+
func (s *service) CreateVM(requestCtx context.Context, request *proto.CreateVMRequest) (*proto.CreateVMResponse, error) {
414414
defer logPanicAndDie(s.logger)
415415

416416
var (
417417
err error
418418
createRan bool
419+
resp proto.CreateVMResponse
419420
)
420421

421422
s.vmStartOnce.Do(func() {
@@ -445,7 +446,11 @@ func (s *service) CreateVM(requestCtx context.Context, request *proto.CreateVMRe
445446

446447
// let all the other methods know that the VM is ready for tasks
447448
close(s.vmReady)
448-
return &empty.Empty{}, nil
449+
450+
if c, ok := s.jailer.(cgroupPather); ok {
451+
resp.CgroupPath = c.CgroupPath()
452+
}
453+
return &resp, nil
449454
}
450455

451456
func (s *service) publishVMStart() error {

runtime/service_integ_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,10 @@ func TestMultipleVMs_Isolated(t *testing.T) {
274274

275275
rootfsPath := defaultVMRootfsPath
276276

277+
vmIDStr := strconv.Itoa(vmID)
277278
fcClient := fccontrol.NewFirecrackerClient(pluginClient.Client())
278279
req := &proto.CreateVMRequest{
279-
VMID: strconv.Itoa(vmID),
280+
VMID: vmIDStr,
280281
MachineCfg: &proto.FirecrackerMachineConfiguration{
281282
MemSizeMib: 512,
282283
},
@@ -296,7 +297,7 @@ func TestMultipleVMs_Isolated(t *testing.T) {
296297
JailerConfig: jailerConfig,
297298
}
298299

299-
_, err = fcClient.CreateVM(ctx, req)
300+
resp, err := fcClient.CreateVM(ctx, req)
300301
require.NoError(t, err, "failed to create vm")
301302

302303
var containerWg sync.WaitGroup
@@ -403,9 +404,13 @@ func TestMultipleVMs_Isolated(t *testing.T) {
403404

404405
jailer := &runcJailer{
405406
ociBundlePath: string(shimDir),
407+
vmID: vmIDStr,
406408
}
407409
_, err = os.Stat(jailer.RootPath())
408410
require.NoError(t, err, "failed to stat root path of jailer")
411+
_, err = os.Stat(filepath.Join("/sys/fs/cgroup/cpu", resp.CgroupPath))
412+
require.NoError(t, err, "failed to stat cgroup path of jailer")
413+
assert.Equal(t, filepath.Join("/firecracker-containerd", vmIDStr), resp.CgroupPath)
409414
}
410415

411416
// Verify each exec had the same stdout and use that value as the mount namespace that will be compared

0 commit comments

Comments
 (0)