[devel] Q: энтропия на сборочнице [bolt-0.9.1-alt1: Sisyphus/i586 test rebuild failed]
Konstantin Lepikhov
lakostis на altlinux.org
Вт Мар 2 12:36:49 MSK 2021
Hi Dmitry!
On 03/01/2021, at 08:56:20 PM you wrote:
<skip>
> > У меня есть смутные подозрения, что в какой-то момент в сборочнице
> > кончается энтропия и начинается фигня
>
> Это что, неустранимо вероятностный тест, который, если его запускать
> достаточно много раз, обязательно упадёт? А где он добывает себе
> рандомизацию?
Из того, что я вижу по логам пересборки, да, падения происходят
периодически и почему-то только на i586 и x86_64
По рандомизации:
/* general function */
typedef enum {
BOLT_RNG_ERROR = -1,
BOLT_RNG_URANDOM = 1,
BOLT_RNG_PRNG = 2,
BOLT_RNG_GETRANDOM = 3,
} BoltRng;
...
#if HAVE_FN_GETRANDOM
#include <sys/random.h>
# else
# define GRND_NONBLOCK 0
#endif
int
bolt_get_random_data (void *buf, gsize n)
{
gboolean ok;
ok = bolt_random_getrandom (buf, n, GRND_NONBLOCK, NULL);
if (ok)
return BOLT_RNG_GETRANDOM;
ok = bolt_random_urandom (buf, n);
if (ok)
return BOLT_RNG_URANDOM;
bolt_random_prng (buf, n);
return BOLT_RNG_PRNG;
}
/* specific implementations */
gboolean
bolt_random_getrandom (void *buf,
gsize n,
unsigned flags,
GError **error)
{
int r = -1;
g_return_val_if_fail (buf != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
#if HAVE_FN_GETRANDOM
r = getrandom (buf, n, flags);
#else
errno = ENOSYS;
#endif
if (r < 0)
{
g_set_error (error, G_IO_ERROR,
g_io_error_from_errno (errno),
"failed to get random data: %s",
g_strerror (errno));
return FALSE;
}
return TRUE;
}
gboolean
bolt_random_urandom (void *buf, gsize n)
{
gboolean ok;
int rndfd;
gsize len;
g_return_val_if_fail (buf != NULL, FALSE);
rndfd = bolt_open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY, 0, NULL);
if (rndfd < 0)
return FALSE;
ok = bolt_read_all (rndfd, buf, n, &len, NULL);
(void) close (rndfd);
/* NB: according to the man page random(4), "when calling
read(2) for the device /dev/urandom, reads of up to 256
bytes will return as many bytes as are requested and will
not be interrupted by a signal handler".
*/
return ok && len == n;
}
void
bolt_random_prng (void *buf, gsize n)
{
char *ptr = buf;
const gsize l = n % sizeof (guint32);
const gsize k = n - l;
if (buf == NULL || n == 0)
return;
for (gsize i = 0; i < k; i += sizeof (guint32))
{
guint32 r = g_random_int ();
memcpy (ptr + i, &r, sizeof (guint32));
}
if (l > 0)
{
guint32 r = g_random_int ();
memcpy (ptr + k, &r, l);
}
}
--
WBR et al.
Подробная информация о списке рассылки Devel