[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