lib/pull: Wait for pending ops to complete on error

I saw in a stack trace that the main thread was calling `exit()` even while
worker threads were alive and doing sha256/write/fsync etc. for objects.

The stack trace was a SEGV as the main thread was calling into library
`atexit()` handlers and we were a liblz4 destructor:

```
 #0  0x00007f2db790f8d4 _fini (liblz4.so.1)
 #1  0x00007f2dbbae1c68 __run_exit_handlers (libc.so.6)
```

(Why that library has a destructor I don't know offhand, can't find
 it in the source in a quick look)

Anyways, global library destructors and worker threads continuing simply don't
mix. Let's wait for our outstanding operations before we exit. This is also a
good idea for projects using libostree as a shared library, as we don't want
worker threads outliving operations.

Our existing pull corruption tests exercise coverage here.

I added a new `caught-error` status boolean to the progress API, and use it the
commandline to tell the user that we're waiting for outstanding ops.

Closes: #1185
Approved by: jlebon
This commit is contained in:
Colin Walters authored and Atomic Bot committed 2017-09-19 19:05:26 +00:00
1 parent 3e564116b2
commit 5c4f26bd65
2 files changed
+36 -8

No files matched your search

+6 -1
View File
@@ -4023,7 +4023,7 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
gpointer user_data)
{
g_autofree char *status = NULL;
gboolean scanning;
gboolean caught_error, scanning;
guint outstanding_fetches;
guint outstanding_metadata_fetches;
guint outstanding_writes;
@@ -4039,6 +4039,7 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
"outstanding-fetches", "u", &outstanding_fetches,
"outstanding-metadata-fetches", "u", &outstanding_metadata_fetches,
"outstanding-writes", "u", &outstanding_writes,
"caught-error", "b", &caught_error,
"scanning", "u", &scanning,
"scanned-metadata", "u", &n_scanned_metadata,
"fetched-delta-parts", "u", &fetched_delta_parts,
@@ -4052,6 +4053,10 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
{
g_string_append (buf, status);
}
else if (caught_error)
{
g_string_append_printf (buf, "Caught error, waiting for outstanding tasks");
}
else if (outstanding_fetches)
{
guint64 bytes_transferred, start_time, total_delta_part_size;