View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001165 | bareos-core | director | public | 2020-01-03 09:57 | 2020-01-07 15:09 |
Reporter | franku | Assigned To | franku | ||
Priority | normal | Severity | major | Reproducibility | random |
Status | resolved | Resolution | fixed | ||
Summary | 0001165: Same job name for jobs submitted at the same time | ||||
Description | Restore jobs submitted at the same time end up with the same job name, which results in one of the jobs being rejected by the storage daemon and failing. | ||||
Steps To Reproduce | See attached files: why.c: test-source file with the code stripped down to the essence output: log-output of the test that shows up the problem | ||||
Additional Information | The seq variable is incremented inside of the mutex, which should be safe, but then its value is read into the JobControlRecord outside of the mutex, which is a race condition if other threads are manipulating the value at the same time. | ||||
Tags | No tags attached. | ||||
why.c (1,939 bytes)
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define THREADCOUNT 20 /* compile with "gcc -o whyc why.c -lpthread" */ void *maybeunique(void* arg) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static time_t last_start_time = 0; static int seq = 0; int lseq; time_t now = time(NULL); struct tm *info; char dt[50]; time_t rawtime; pthread_mutex_lock(&mutex); seq++; if (seq > 59) { seq = 0; while (now == last_start_time) { usleep(500000); now = time(NULL); } } last_start_time = now; lseq = seq; //assign static value to thread-local variable pthread_mutex_unlock(&mutex); time(&rawtime); info = localtime(&rawtime); strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", info); fprintf(stdout, "jobname.%s_%02d (seq = %02d, lseq = %02d)\n", dt, lseq, seq, lseq); fflush(stdout); return (void*) NULL; } int main(int argc, char** argv) { int r; pthread_t threads[THREADCOUNT]; fprintf(stdout, "starting...\n"); fflush(stdout); for (int i = 0; i < THREADCOUNT; i++) { r = pthread_create(&threads[i], NULL, &maybeunique, NULL); if (r) { fprintf(stderr, "failed to create thread %d, errno is %d\n", i, r); } } fprintf(stdout, "threads dispatched. waiting...\n"); fflush(stdout); for (int i = 0; i < 5; i++) { r = pthread_join(threads[i], NULL); if (r) { fprintf(stderr, "failed to wait on thread %d, errno is %d\n", i, r); } } fprintf(stdout, "done\n"); fflush(stdout); exit(0); } output (1,116 bytes)
$ ./whyc starting... jobname.2019-12-27_17.23.33_01 (seq = 05, lseq = 01) jobname.2019-12-27_17.23.33_05 (seq = 07, lseq = 05) jobname.2019-12-27_17.23.33_03 (seq = 07, lseq = 03) jobname.2019-12-27_17.23.33_08 (seq = 11, lseq = 08) jobname.2019-12-27_17.23.33_06 (seq = 11, lseq = 06) jobname.2019-12-27_17.23.33_02 (seq = 11, lseq = 02) jobname.2019-12-27_17.23.33_07 (seq = 12, lseq = 07) jobname.2019-12-27_17.23.33_04 (seq = 13, lseq = 04) jobname.2019-12-27_17.23.33_09 (seq = 13, lseq = 09) jobname.2019-12-27_17.23.33_10 (seq = 14, lseq = 10) jobname.2019-12-27_17.23.33_14 (seq = 14, lseq = 14) jobname.2019-12-27_17.23.33_12 (seq = 14, lseq = 12) jobname.2019-12-27_17.23.33_13 (seq = 14, lseq = 13) jobname.2019-12-27_17.23.33_15 (seq = 15, lseq = 15) jobname.2019-12-27_17.23.33_11 (seq = 16, lseq = 11) jobname.2019-12-27_17.23.33_17 (seq = 17, lseq = 17) jobname.2019-12-27_17.23.33_16 (seq = 17, lseq = 16) jobname.2019-12-27_17.23.33_18 (seq = 18, lseq = 18) jobname.2019-12-27_17.23.33_19 (seq = 19, lseq = 19) threads dispatched. waiting... jobname.2019-12-27_17.23.33_20 (seq = 20, lseq = 20) done |
|
bareos: master 472ceb9b 2020-01-03 10:46 Committer: GitHub Ported: N/A Details Diff |
Merge pull request 0000385 from WaryWolf/fix-job-creation-racecond copy value of seq to the stack to avoid race condition when generating Job names |
Affected Issues 0001165 |
|
mod - AUTHORS | Diff File | ||
mod - core/src/dird/job.cc | Diff File | ||
bareos: bareos-18.2 0ee566dc 2020-01-03 10:46 Ported: N/A Details Diff |
Merge pull request 0000385 from WaryWolf/fix-job-creation-racecond (manual merge) copy value of seq to the stack to avoid race condition when generating Job names |
Affected Issues 0001165 |
|
mod - AUTHORS | Diff File | ||
mod - core/src/dird/job.cc | Diff File | ||
bareos: bareos-19.2 36c230fa 2020-01-03 10:46 Ported: N/A Details Diff |
Merge pull request 0000385 from WaryWolf/fix-job-creation-racecond copy value of seq to the stack to avoid race condition when generating Job names |
Affected Issues 0001165 |
|
mod - AUTHORS | Diff File | ||
mod - core/src/dird/job.cc | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2020-01-03 09:57 | franku | New Issue | |
2020-01-03 09:57 | franku | File Added: why.c | |
2020-01-03 09:57 | franku | File Added: output | |
2020-01-03 09:58 | franku | Assigned To | => franku |
2020-01-03 09:58 | franku | Status | new => confirmed |
2020-01-03 09:58 | franku | Steps to Reproduce Updated | |
2020-01-03 10:31 | franku | Changeset attached | => bareos master 472ceb9b |
2020-01-03 15:22 | franku | Changeset attached | => bareos bareos-18.2 0ee566dc |
2020-01-07 14:40 | franku | Changeset attached | => bareos bareos-19.2 36c230fa |
2020-01-07 15:07 | franku | Status | confirmed => resolved |
2020-01-07 15:07 | franku | Resolution | open => fixed |