Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 50 additions & 18 deletions src/libcrun/criu.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ criu_notify (char *action, __attribute__ ((unused)) criu_notify_arg_t na)
# ifdef CRIU_PRE_DUMP_SUPPORT

static int
criu_check_mem_track (char *work_path, libcrun_error_t *err)
criu_check_mem_track (libcrun_error_t *err)
{
struct criu_feature_check features = { 0 };
int ret;
Expand All @@ -259,16 +259,12 @@ criu_check_mem_track (char *work_path, libcrun_error_t *err)

ret = libcriu_wrapper->criu_feature_check (&features, sizeof (features));
if (UNLIKELY (ret < 0))
return crun_make_error (err, 0,
"CRIU feature checking failed %d. Please check CRIU logfile %s/%s",
ret, work_path, CRIU_CHECKPOINT_LOG_FILE);
return crun_make_error (err, 0, "CRIU feature checking failed: %d", ret);

if (features.mem_track == true)
return 1;

return crun_make_error (err, 0,
"memory tracking not supported. Please check CRIU logfile %s/%s",
work_path, CRIU_CHECKPOINT_LOG_FILE);
return crun_make_error (err, 0, "CRIU memory tracking not supported");
}

# endif
Expand Down Expand Up @@ -514,6 +510,41 @@ validate_criu_version (libcrun_error_t *err)
return 0;
}

static void
show_criu_log (const char *work_path, const char *log)
{
cleanup_free char *log_path = NULL;
libcrun_error_t *tmp_err = NULL;
char line[1024];
FILE *f;

if (UNLIKELY (append_paths (&log_path, tmp_err, work_path, log, NULL)) < 0)
{
crun_error_release (tmp_err);
return;
}

f = fopen (log_path, "r");
if (f == NULL)
{
if (errno != ENOENT)
libcrun_error (errno, "Can't open CRIU log `%s`", log_path);
return;
}

/* Log with error verbosity as this is the default. */
libcrun_error (0, "--- excerpt from CRIU log `%s`", log_path);
while (fgets (line, sizeof (line), f) != NULL)
if (strstr (line, "Error ") != NULL)
{
line[strcspn (line, "\n")] = '\0';
libcrun_error (0, "%s", line);
}

fclose (f);
libcrun_error (0, "--- end of excerpt");
}

int
libcrun_container_checkpoint_linux_criu (libcrun_container_status_t *status, libcrun_container_t *container,
libcrun_checkpoint_restore_t *cr_options, libcrun_error_t *err)
Expand Down Expand Up @@ -619,7 +650,7 @@ libcrun_container_checkpoint_linux_criu (libcrun_container_status_t *status, lib
* changed compared to the previous dump. */
if (cr_options->parent_path != NULL)
{
criu_can_mem_track = criu_check_mem_track (cr_options->work_path, err);
criu_can_mem_track = criu_check_mem_track (err);
if (UNLIKELY (criu_can_mem_track == -1))
return -1;
libcriu_wrapper->criu_set_track_mem (true);
Expand All @@ -645,16 +676,17 @@ libcrun_container_checkpoint_linux_criu (libcrun_container_status_t *status, lib
{
if (criu_can_mem_track != 1)
{
criu_can_mem_track = criu_check_mem_track (cr_options->work_path, err);
criu_can_mem_track = criu_check_mem_track (err);
if (UNLIKELY (criu_can_mem_track == -1))
return -1;
}
libcriu_wrapper->criu_set_track_mem (true);
ret = libcriu_wrapper->criu_pre_dump ();
if (UNLIKELY (ret != 0))
return crun_make_error (err, 0,
"CRIU pre-dump failed %d. Please check CRIU logfile %s/%s",
ret, cr_options->work_path, CRIU_CHECKPOINT_LOG_FILE);
{
show_criu_log (cr_options->work_path, CRIU_CHECKPOINT_LOG_FILE);
return crun_make_error (err, 0, "CRIU pre-dump failed: %d", ret);
}
return 0;
}
}
Expand Down Expand Up @@ -820,9 +852,10 @@ libcrun_container_checkpoint_linux_criu (libcrun_container_status_t *status, lib

ret = libcriu_wrapper->criu_dump ();
if (UNLIKELY (ret != 0))
return crun_make_error (err, ret < 0 ? -ret : 0,
"CRIU checkpointing failed %d. Please check CRIU logfile %s/%s",
ret, cr_options->work_path, CRIU_CHECKPOINT_LOG_FILE);
{
show_criu_log (cr_options->work_path, CRIU_CHECKPOINT_LOG_FILE);
return crun_make_error (err, ret < 0 ? -ret : 0, "CRIU checkpointing failed: %d", ret);
}

return 0;
}
Expand Down Expand Up @@ -1257,9 +1290,8 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
ret = libcriu_wrapper->criu_restore_child ();
if (UNLIKELY (ret <= 0))
{
ret = crun_make_error (err, 0,
"CRIU restoring failed %d. Please check CRIU logfile `%s/%s`",
ret, cr_options->work_path, CRIU_RESTORE_LOG_FILE);
show_criu_log (cr_options->work_path, CRIU_RESTORE_LOG_FILE);
ret = crun_make_error (err, 0, "CRIU restoring failed: %d", ret);
goto out_umount;
}

Expand Down