1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // +build linux
- package overlay2
- import (
- "crypto/rand"
- "encoding/base32"
- "fmt"
- "io"
- "os"
- "syscall"
- "time"
- "github.com/Sirupsen/logrus"
- )
- // generateID creates a new random string identifier with the given length
- func generateID(l int) string {
- const (
- // ensures we backoff for less than 450ms total. Use the following to
- // select new value, in units of 10ms:
- // n*(n+1)/2 = d -> n^2 + n - 2d -> n = (sqrt(8d + 1) - 1)/2
- maxretries = 9
- backoff = time.Millisecond * 10
- )
- var (
- totalBackoff time.Duration
- count int
- retries int
- size = (l*5 + 7) / 8
- u = make([]byte, size)
- )
- // TODO: Include time component, counter component, random component
- for {
- // This should never block but the read may fail. Because of this,
- // we just try to read the random number generator until we get
- // something. This is a very rare condition but may happen.
- b := time.Duration(retries) * backoff
- time.Sleep(b)
- totalBackoff += b
- n, err := io.ReadFull(rand.Reader, u[count:])
- if err != nil {
- if retryOnError(err) && retries < maxretries {
- count += n
- retries++
- logrus.Errorf("error generating version 4 uuid, retrying: %v", err)
- continue
- }
- // Any other errors represent a system problem. What did someone
- // do to /dev/urandom?
- panic(fmt.Errorf("error reading random number generator, retried for %v: %v", totalBackoff.String(), err))
- }
- break
- }
- s := base32.StdEncoding.EncodeToString(u)
- return s[:l]
- }
- // retryOnError tries to detect whether or not retrying would be fruitful.
- func retryOnError(err error) bool {
- switch err := err.(type) {
- case *os.PathError:
- return retryOnError(err.Err) // unpack the target error
- case syscall.Errno:
- if err == syscall.EPERM {
- // EPERM represents an entropy pool exhaustion, a condition under
- // which we backoff and retry.
- return true
- }
- }
- return false
- }
|