Merge pull request #1371 from adrianreber/master
checkpoint: check if system supports pre-dumping
This commit is contained in:
commit
f8ce01dbdc
|
@ -535,6 +535,56 @@ func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struc
|
|||
return notifyMemoryPressure(c.cgroupManager.GetPaths(), level)
|
||||
}
|
||||
|
||||
var criuFeatures *criurpc.CriuFeatures
|
||||
|
||||
func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error {
|
||||
|
||||
var t criurpc.CriuReqType
|
||||
t = criurpc.CriuReqType_FEATURE_CHECK
|
||||
|
||||
if err := c.checkCriuVersion("1.8"); err != nil {
|
||||
// Feature checking was introduced with CRIU 1.8.
|
||||
// Ignore the feature check if an older CRIU version is used
|
||||
// and just act as before.
|
||||
// As all automated PR testing is done using CRIU 1.7 this
|
||||
// code will not be tested by automated PR testing.
|
||||
return nil
|
||||
}
|
||||
|
||||
// make sure the features we are looking for are really not from
|
||||
// some previous check
|
||||
criuFeatures = nil
|
||||
|
||||
req := &criurpc.CriuReq{
|
||||
Type: &t,
|
||||
// Theoretically this should not be necessary but CRIU
|
||||
// segfaults if Opts is empty.
|
||||
// Fixed in CRIU 2.12
|
||||
Opts: rpcOpts,
|
||||
Features: criuFeat,
|
||||
}
|
||||
|
||||
err := c.criuSwrk(nil, req, criuOpts, false)
|
||||
if err != nil {
|
||||
logrus.Debugf("%s", err)
|
||||
return fmt.Errorf("CRIU feature check failed")
|
||||
}
|
||||
|
||||
logrus.Debugf("Feature check says: %s", criuFeatures)
|
||||
missingFeatures := false
|
||||
|
||||
if *criuFeat.MemTrack && !*criuFeatures.MemTrack {
|
||||
missingFeatures = true
|
||||
logrus.Debugf("CRIU does not support MemTrack")
|
||||
}
|
||||
|
||||
if missingFeatures {
|
||||
return fmt.Errorf("CRIU is missing features")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkCriuVersion checks Criu version greater than or equal to minVersion
|
||||
func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
var x, y, z, versionReq int
|
||||
|
@ -717,6 +767,14 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
|||
|
||||
var t criurpc.CriuReqType
|
||||
if criuOpts.PreDump {
|
||||
feat := criurpc.CriuFeatures{
|
||||
MemTrack: proto.Bool(true),
|
||||
}
|
||||
|
||||
if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t = criurpc.CriuReqType_PRE_DUMP
|
||||
} else {
|
||||
t = criurpc.CriuReqType_DUMP
|
||||
|
@ -1018,16 +1076,21 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
|||
}
|
||||
|
||||
logrus.Debugf("Using CRIU in %s mode", req.GetType().String())
|
||||
val := reflect.ValueOf(req.GetOpts())
|
||||
v := reflect.Indirect(val)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
st := v.Type()
|
||||
name := st.Field(i).Name
|
||||
if strings.HasPrefix(name, "XXX_") {
|
||||
continue
|
||||
// In the case of criurpc.CriuReqType_FEATURE_CHECK req.GetOpts()
|
||||
// should be empty. For older CRIU versions it still will be
|
||||
// available but empty.
|
||||
if req.GetType() != criurpc.CriuReqType_FEATURE_CHECK {
|
||||
val := reflect.ValueOf(req.GetOpts())
|
||||
v := reflect.Indirect(val)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
st := v.Type()
|
||||
name := st.Field(i).Name
|
||||
if strings.HasPrefix(name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
value := val.MethodByName("Get" + name).Call([]reflect.Value{})
|
||||
logrus.Debugf("CRIU option %s with value %v", name, value[0])
|
||||
}
|
||||
value := val.MethodByName("Get" + name).Call([]reflect.Value{})
|
||||
logrus.Debugf("CRIU option %s with value %v", name, value[0])
|
||||
}
|
||||
data, err := proto.Marshal(req)
|
||||
if err != nil {
|
||||
|
@ -1063,6 +1126,10 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
|||
|
||||
t := resp.GetType()
|
||||
switch {
|
||||
case t == criurpc.CriuReqType_FEATURE_CHECK:
|
||||
logrus.Debugf("Feature check says: %s", resp)
|
||||
criuFeatures = resp.GetFeatures()
|
||||
break
|
||||
case t == criurpc.CriuReqType_NOTIFY:
|
||||
if err := c.criuNotifications(resp, process, opts, extFds); err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue