Hello community, here is the log from the commit of package xfsprogs for openSUSE:Factory checked in at 2017-06-30 18:38:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xfsprogs (Old) and /work/SRC/openSUSE:Factory/.xfsprogs.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "xfsprogs" Fri Jun 30 18:38:12 2017 rev:45 rq:505785 version:4.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/xfsprogs/xfsprogs.changes 2017-06-10 17:50:15.786078749 +0200 +++ /work/SRC/openSUSE:Factory/.xfsprogs.new/xfsprogs.changes 2017-06-30 18:38:14.752869237 +0200 @@ -1,0 +2,14 @@ +Thu Jun 22 20:15:28 UTC 2017 - jeffm@suse.com + +- Fix crash in xfs_repair when threads fail to start (bsc#1019938). + * Added xfs_repair-clear-pthread_t-when-pthread_create-fails.patch + * Added xfs_repair-add-prefetch-trace-calls-to-debug-thread-creation-failures.patch + * Added xfs_repair-fix-thread-creation-failure-recovery.patch + +------------------------------------------------------------------- +Fri Jun 2 18:23:03 UTC 2017 - jeffm@suse.com + +- fsr: fix uninitialized fs usage after timeout (bsc#1002699). + * Added fsr-fix-uninitialized-fs-usage-after-timeout.patch + +------------------------------------------------------------------- New: ---- fsr-fix-uninitialized-fs-usage-after-timeout.patch xfs_repair-add-prefetch-trace-calls-to-debug-thread-creation-failures.patch xfs_repair-clear-pthread_t-when-pthread_create-fails.patch xfs_repair-fix-thread-creation-failure-recovery.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xfsprogs.spec ++++++ --- /var/tmp/diff_new_pack.m16W2t/_old 2017-06-30 18:38:15.472767980 +0200 +++ /var/tmp/diff_new_pack.m16W2t/_new 2017-06-30 18:38:15.476767417 +0200 @@ -31,6 +31,10 @@ Source3: module-setup.sh.in Source4: dracut-fsck-help.txt Patch0: xfsprogs-docdir.diff +Patch1: fsr-fix-uninitialized-fs-usage-after-timeout.patch +Patch2: xfs_repair-clear-pthread_t-when-pthread_create-fails.patch +Patch3: xfs_repair-add-prefetch-trace-calls-to-debug-thread-creation-failures.patch +Patch4: xfs_repair-fix-thread-creation-failure-recovery.patch BuildRequires: libblkid-devel BuildRequires: readline-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -42,6 +46,7 @@ %if 0%{?suse_version} >= 1310 BuildRequires: suse-module-tools %endif +BuildRequires: xz %description A set of commands to use the XFS file system, including mkfs.xfs. @@ -75,6 +80,10 @@ %if 0%{?suse_version} %patch0 %endif +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build export OPTIMIZER="-fPIC" ++++++ fsr-fix-uninitialized-fs-usage-after-timeout.patch ++++++ From: Jeff Mahoney <jeffm@suse.com> Date: Fri, 2 Jun 2017 14:15:41 -0400 Subject: fsr: fix uninitialized fs usage after timeout Patch-mainline: Submitted to linux-xfs, 2 Jun 2017 References: bsc#1002699 In the main loop of fsrallfs, we exit when we've hit the timeout but we increment fs before we get there. If we're operating on the last file system in the array, we'll hit an uninitialized fsdesc and crash in fsrall_cleanup. Signed-off-by: Jeff Mahoney <jeffm@suse.com> --- fsr/xfs_fsr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index 517b75f0..e695c243 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -598,7 +598,7 @@ fsrallfs(char *mtab, int howlong, char *leftofffile) signal(SIGTERM, aborter); /* reorg for 'howlong' -- checked in 'fsrfs' */ - while (endtime > time(0)) { + for (; endtime > time(0); fs->npass++, fs++) { pid_t pid; if (fs == fsend) fs = fsbase; @@ -629,8 +629,6 @@ fsrallfs(char *mtab, int howlong, char *leftofffile) break; } startino = 0; /* reset after the first time through */ - fs->npass++; - fs++; } fsrall_cleanup(endtime <= time(0)); } ++++++ xfs_repair-add-prefetch-trace-calls-to-debug-thread-creation-failures.patch ++++++ From: Jeff Mahoney <jeffm@suse.com> Subject: xfs_repair: add prefetch trace calls to debug thread creation failures Patch-mainline: Submitted, 16 Jan 2017 References: bsc#1019938 When debugging prefetch failures, it's useful to have thread creation failure messages that are output as warnings on stderr in the trace log as well. It's also helpful to see when an AG gets queued behind another one rather than having the thread started directly, which has a separate trace line. Signed-off-by: Jeff Mahoney <jeffm@suse.com> --- repair/prefetch.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/repair/prefetch.c b/repair/prefetch.c index 044fab2..37d60d6 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -703,6 +703,8 @@ pf_queuing_worker( if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); + pftrace("failed to create prefetch thread for AG %d: %s", + args->agno, strerror(err)); args->io_threads[i] = 0; if (i == 0) { pf_start_processing(args); @@ -817,6 +819,8 @@ pf_create_prefetch_thread( if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); + pftrace("failed to create prefetch thread for AG %d: %s", + args->agno, strerror(err)); args->queuing_thread = 0; cleanup_inode_prefetch(args); } @@ -882,8 +886,11 @@ start_inode_prefetch( if (prev_args->prefetch_done) { if (!pf_create_prefetch_thread(args)) args = NULL; - } else + } else { prev_args->next_args = args; + pftrace("queued AG %d after AG %d", + args->agno, prev_args->agno); + } pthread_mutex_unlock(&prev_args->lock); } -- 2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ++++++ xfs_repair-clear-pthread_t-when-pthread_create-fails.patch ++++++ From: Jeff Mahoney <jeffm@suse.com> Subject: xfs_repair: clear pthread_t when pthread_create fails Patch-mainline: Submitted, 16 Jan 2017 References: bsc#1019938 pf_queuing_worker and pf_create_prefetch_thread both try to handle thread creation failure gracefully, but assume that pthread_create doesn't modify the pthread_t when it fails.
From the pthread_create man page: On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
In fact, glibc's pthread_create writes the pthread_t value before calling clone(). When we join the created threads in cleanup_inode_prefetch and the cleanup stage of pf_queuing_worker, we assume that if the pthread_t is nonzero that it's a valid thread handle and end up crashing in pthread_join. This patch zeros out the handle after pthread_create failure. Signed-off-by: Jeff Mahoney <jeffm@suse.com> --- repair/prefetch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/repair/prefetch.c b/repair/prefetch.c index ff50606..044fab2 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -703,6 +703,7 @@ pf_queuing_worker( if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); + args->io_threads[i] = 0; if (i == 0) { pf_start_processing(args); return NULL; @@ -816,6 +817,7 @@ pf_create_prefetch_thread( if (err != 0) { do_warn(_("failed to create prefetch thread: %s\n"), strerror(err)); + args->queuing_thread = 0; cleanup_inode_prefetch(args); } -- 2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ++++++ xfs_repair-fix-thread-creation-failure-recovery.patch ++++++ From: Jeff Mahoney <jeffm@suse.com> Subject: xfs_repair: fix thread creation failure recovery Patch-mainline: Submitted, 16 Jan 2017 References: bsc#1019938 When pf_create_prefetch_thread fails, it tears down the args struct and frees it. This causes a use-after-free in prefetch_ag_range, which then passes the now-invalid pointer to start_inode_prefetch. The struct is only freed when the queuing thread can't be started. When we can't start even one worker thread, we mark the args ready for processing and allow it to proceed single-threaded. Unfortunately, this only marks the current args ready for processing and since we return immediately, the call to pf_create_prefetch_thread at the end of pf_queuing_worker never gets called and we wait forever for prefetch to start on the next AG. This patch factors out the cleanup into a new pf_skip_prefetch_thread that is called when we fail to create either the queuing thread or the first of the workers. It marks the args ready for processing, marks it done so start_inode_prefetch doesn't add another AG to the list, and tries to start a new thread for the next AG in the list. We also clear ->next_args and check for it in cleanup_inode_prefetch so this condition is easier to catch should it arise again. Signed-off-by: Jeff Mahoney <jeffm@suse.com> --- repair/prefetch.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/repair/prefetch.c b/repair/prefetch.c index 37d60d6..4c74b6e 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -679,11 +679,32 @@ static int pf_create_prefetch_thread( prefetch_args_t *args); +/* + * If we fail to create the queuing thread or can't create even one + * prefetch thread, we need to let processing continue without it. + */ +static void +pf_skip_prefetch_thread(prefetch_args_t *args) +{ + prefetch_args_t *next; + + pthread_mutex_lock(&args->lock); + args->prefetch_done = 1; + pf_start_processing(args); + next = args->next_args; + args->next_args = NULL; + pthread_mutex_unlock(&args->lock); + + if (next) + pf_create_prefetch_thread(next); +} + static void * pf_queuing_worker( void *param) { prefetch_args_t *args = param; + prefetch_args_t *next_args; int num_inos; ino_tree_node_t *irec; ino_tree_node_t *cur_irec; @@ -707,7 +728,7 @@ pf_queuing_worker( args->agno, strerror(err)); args->io_threads[i] = 0; if (i == 0) { - pf_start_processing(args); + pf_skip_prefetch_thread(args); return NULL; } /* @@ -798,11 +819,13 @@ pf_queuing_worker( ASSERT(btree_is_empty(args->io_queue)); args->prefetch_done = 1; - if (args->next_args) - pf_create_prefetch_thread(args->next_args); - + next_args = args->next_args; + args->next_args = NULL; pthread_mutex_unlock(&args->lock); + if (next_args) + pf_create_prefetch_thread(next_args); + return NULL; } @@ -822,7 +845,7 @@ pf_create_prefetch_thread( pftrace("failed to create prefetch thread for AG %d: %s", args->agno, strerror(err)); args->queuing_thread = 0; - cleanup_inode_prefetch(args); + pf_skip_prefetch_thread(args); } return err == 0; @@ -884,14 +907,15 @@ start_inode_prefetch( } else { pthread_mutex_lock(&prev_args->lock); if (prev_args->prefetch_done) { + pthread_mutex_unlock(&prev_args->lock); if (!pf_create_prefetch_thread(args)) args = NULL; } else { prev_args->next_args = args; pftrace("queued AG %d after AG %d", args->agno, prev_args->agno); + pthread_mutex_unlock(&prev_args->lock); } - pthread_mutex_unlock(&prev_args->lock); } return args; @@ -1066,6 +1090,8 @@ cleanup_inode_prefetch( pftrace("AG %d prefetch done", args->agno); + ASSERT(args->next_args == NULL); + pthread_mutex_destroy(&args->lock); pthread_cond_destroy(&args->start_reading); pthread_cond_destroy(&args->start_processing); -- 2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html