#include <pthread.h>
#include <sys/statvfs.h>
#include <time.h>
-#include "path.h"
+#include "libfrog/paths.h"
#include "disk.h"
#include "read_verify.h"
#include "xfs_scrub.h"
fflush(pt.fp);
}
-#define NSEC_PER_SEC (1000000000)
static void *
progress_report_thread(void *arg)
{
struct timespec abstime;
int ret;
+ rcu_register_thread();
pthread_mutex_lock(&pt.lock);
while (1) {
+ uint64_t progress_val;
+
/* Every half second. */
ret = clock_gettime(CLOCK_REALTIME, &abstime);
if (ret)
abstime.tv_sec++;
abstime.tv_nsec -= NSEC_PER_SEC;
}
- pthread_cond_timedwait(&pt.wakeup, &pt.lock, &abstime);
+ ret = pthread_cond_timedwait(&pt.wakeup, &pt.lock, &abstime);
+ if (ret && ret != ETIMEDOUT)
+ break;
if (pt.terminate)
break;
- progress_report(ptcounter_value(pt.ptc));
+ ret = ptcounter_value(pt.ptc, &progress_val);
+ if (!ret)
+ progress_report(progress_val);
}
pthread_mutex_unlock(&pt.lock);
+ rcu_unregister_thread();
return NULL;
}
pt.fp = NULL;
}
-/* Set ourselves up to report progress. */
-bool
+/*
+ * Set ourselves up to report progress. If errors are encountered, this
+ * function will log them and return nonzero.
+ */
+int
progress_init_phase(
struct scrub_ctx *ctx,
FILE *fp,
assert(pt.fp == NULL);
if (fp == NULL || max == 0) {
pt.fp = NULL;
- return true;
+ return 0;
}
pt.fp = fp;
pt.isatty = isatty(fileno(fp));
pt.twiddle = 0;
pt.terminate = false;
- pt.ptc = ptcounter_init(nr_threads);
- if (!pt.ptc)
+ ret = ptcounter_alloc(nr_threads, &pt.ptc);
+ if (ret) {
+ str_liberror(ctx, ret, _("allocating progress counter"));
goto out_max;
+ }
ret = pthread_create(&pt.thread, NULL, progress_report_thread, NULL);
- if (ret)
+ if (ret) {
+ str_liberror(ctx, ret, _("creating progress reporting thread"));
goto out_ptcounter;
+ }
- return true;
+ return 0;
out_ptcounter:
ptcounter_free(pt.ptc);
out_max:
pt.max = 0;
pt.fp = NULL;
- return false;
+ return ret;
}