On Thu, Mar 14, 2013 at 11:41:52AM -0400, Ted Unangst wrote:
> On Thu, Mar 14, 2013 at 14:30, Antoine Jacoutot wrote:
>
> > FYI I am seeing a somehow similar crash when using sysutils/bacula (both
> > 5.2 and 5.3).
> > It is 100% reproducible on my setup. Obviously painful since it means I
> > cannot run backups anymore...
>
> The following is brought to you without testing or warranty. It did
> compile at least once though.
Awesome, thanks! I ran several batches of concurrent backups and I cannot
reproduce the crash anymore :-)
I'm going to run with that patch for the time being... if I spot any
regression, I'll let you know.
> Index: stdlib/random.c
> ===================================================================
> RCS file: /cvs/src/lib/libc/stdlib/random.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 random.c
> --- stdlib/random.c 1 Jun 2012 01:01:57 -0000 1.17
> +++ stdlib/random.c 14 Mar 2013 15:37:14 -0000
> @@ -36,6 +36,8 @@
> #include <stdlib.h>
> #include <unistd.h>
>
> +#include "thread_private.h"
> +
> /*
> * random.c:
> *
> @@ -174,6 +176,12 @@ static int rand_type = TYPE_3;
> static int rand_deg = DEG_3;
> static int rand_sep = SEP_3;
>
> +_THREAD_PRIVATE_MUTEX(random);
> +static long random_l(void);
> +
> +#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random)
> +#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random)
> +
> /*
> * srandom:
> *
> @@ -186,8 +194,8 @@ static int rand_sep = SEP_3;
> * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
> * for default usage relies on values produced by this routine.
> */
> -void
> -srandom(unsigned int x)
> +static void
> +srandom_l(unsigned int x)
> {
> int i;
> int32_t test;
> @@ -213,10 +221,18 @@ srandom(unsigned int x)
> fptr = &state[rand_sep];
> rptr = &state[0];
> for (i = 0; i < 10 * rand_deg; i++)
> - (void)random();
> + (void)random_l();
> }
> }
>
> +void
> +srandom(unsigned int x)
> +{
> + LOCK();
> + srandom_l(x);
> + UNLOCK();
> +}
> +
> /*
> * srandomdev:
> *
> @@ -234,6 +250,7 @@ srandomdev(void)
> int mib[2];
> size_t len;
>
> + LOCK();
> if (rand_type == TYPE_0)
> len = sizeof(state[0]);
> else
> @@ -247,6 +264,7 @@ srandomdev(void)
> fptr = &state[rand_sep];
> rptr = &state[0];
> }
> + UNLOCK();
> }
>
> /*
> @@ -273,6 +291,7 @@ initstate(u_int seed, char *arg_state, s
> {
> char *ostate = (char *)(&state[-1]);
>
> + LOCK();
> if (rand_type == TYPE_0)
> state[-1] = rand_type;
> else
> @@ -302,11 +321,12 @@ initstate(u_int seed, char *arg_state, s
> }
> state = &(((int32_t *)arg_state)[1]); /* first location */
> end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
> - srandom(seed);
> + srandom_l(seed);
> if (rand_type == TYPE_0)
> state[-1] = rand_type;
> else
> state[-1] = MAX_TYPES*(rptr - state) + rand_type;
> + UNLOCK();
> return(ostate);
> }
>
> @@ -333,6 +353,7 @@ setstate(char *arg_state)
> int32_t rear = new_state[0] / MAX_TYPES;
> char *ostate = (char *)(&state[-1]);
>
> + LOCK();
> if (rand_type == TYPE_0)
> state[-1] = rand_type;
> else
> @@ -356,6 +377,7 @@ setstate(char *arg_state)
> fptr = &state[(rear + rand_sep) % rand_deg];
> }
> end_ptr = &state[rand_deg]; /* set end_ptr too */
> + UNLOCK();
> return(ostate);
> }
>
> @@ -376,8 +398,8 @@ setstate(char *arg_state)
> *
> * Returns a 31-bit random number.
> */
> -long
> -random(void)
> +static long
> +random_l(void)
> {
> int32_t i;
>
> @@ -393,4 +415,14 @@ random(void)
> rptr = state;
> }
> return((long)i);
> +}
> +
> +long
> +random(void)
> +{
> + long r;
> + LOCK();
> + r = random_l();
> + UNLOCK();
> + return r;
> }
--
Antoine