Skip to content

Commit 6ad2bdf

Browse files
authored
Merge pull request firecracker-microvm#491 from xibz/master
Enables jailer to copy cache topology
2 parents 6e994af + 3820ab3 commit 6ad2bdf

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

runtime/runc_jailer.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,28 @@ import (
4141

4242
const (
4343
networkNamespaceRuncName = "network"
44+
cacheTopologyPath = "/sys/devices/system/cpu/cpu0/cache"
45+
cacheFolderPrefix = "index"
4446
)
4547

48+
var cacheTopologyPaths = []string{
49+
"sys",
50+
"devices",
51+
"system",
52+
"cpu",
53+
"cpu0",
54+
"cache",
55+
}
56+
57+
var cacheTopologyFiles = []string{
58+
"level",
59+
"type",
60+
"size",
61+
"number_of_sets",
62+
"shared_cpu_map",
63+
"coherency_line_size",
64+
}
65+
4666
// runcJailer uses runc to set up a jailed environment for the Firecracker VM.
4767
type runcJailer struct {
4868
ctx context.Context
@@ -255,6 +275,10 @@ func (j *runcJailer) BuildJailedRootHandler(cfg *config.Config, machineConfig *f
255275
m.Cfg.VsockDevices[i] = v
256276
}
257277

278+
if err := j.setupCacheTopology(rootPath); err != nil {
279+
return err
280+
}
281+
258282
j.logger.Debugf("Writing %q for runc", rootPathToConfig)
259283
// we pass m.Cfg as opposed to machineConfig as we want the populated
260284
// config defaults when calling NewMachine
@@ -640,3 +664,57 @@ func (j runcJailer) Stop(force bool) error {
640664
}
641665
return j.runcClient.Kill(j.ctx, j.vmID, int(signal), &runc.KillOpts{All: true})
642666
}
667+
668+
// setupCacheTopology will copy indexed contents from the cacheTopologyPath to
669+
// the jailer. This is needed for arm architecture as arm does not
670+
// automatically setup any cache topology
671+
func (j runcJailer) setupCacheTopology(path string) error {
672+
j.logger.WithField("path", path).Debug("Creating cache topology")
673+
const mode = os.FileMode(0700)
674+
675+
// builds the cache topology path from the root directory
676+
for _, p := range cacheTopologyPaths {
677+
path = filepath.Join(path, p)
678+
if err := mkdirAndChown(path, mode, j.Config.UID, j.Config.GID); err != nil {
679+
return err
680+
}
681+
}
682+
683+
err := filepath.Walk(cacheTopologyPath, func(cachePath string, info os.FileInfo, err error) error {
684+
if err != nil {
685+
return err
686+
}
687+
if !info.IsDir() {
688+
return nil
689+
}
690+
691+
folder := filepath.Base(cachePath)
692+
if !strings.HasPrefix(folder, cacheFolderPrefix) {
693+
return nil
694+
}
695+
696+
indexPath := filepath.Join(path, folder)
697+
if err := mkdirAndChown(indexPath, info.Mode(), j.Config.UID, j.Config.GID); err != nil {
698+
return err
699+
}
700+
701+
j.logger.WithField("src path", cachePath).WithField("dst path", indexPath).Debug("copying cache folder")
702+
for _, file := range cacheTopologyFiles {
703+
cacheFilePath := filepath.Join(cachePath, file)
704+
info, err := os.Stat(cacheFilePath)
705+
if err != nil {
706+
return err
707+
}
708+
709+
// This is suppose to be a hard copy as intructed by the Firecracker team.
710+
// Bind mounting here may cause some issues on the host's machine
711+
if err := j.copyFileToJail(cacheFilePath, filepath.Join(indexPath, file), info.Mode()); err != nil {
712+
return err
713+
}
714+
}
715+
716+
return nil
717+
})
718+
719+
return err
720+
}

0 commit comments

Comments
 (0)