Merge pull request #19671 from holiman/usbfix

account/usbwallet: abort usb enumeration after failures
This commit is contained in:
Péter Szilágyi 2019-06-05 16:52:31 +03:00 committed by GitHub
commit 30c2b1b06d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 1 deletions

View File

@ -20,6 +20,7 @@ import (
"errors" "errors"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
@ -64,6 +65,7 @@ type Hub struct {
// TODO(karalabe): remove if hotplug lands on Windows // TODO(karalabe): remove if hotplug lands on Windows
commsPend int // Number of operations blocking enumeration commsPend int // Number of operations blocking enumeration
commsLock sync.Mutex // Lock protecting the pending counter and enumeration commsLock sync.Mutex // Lock protecting the pending counter and enumeration
enumFails uint32 // Number of times enumeration has failed
} }
// NewLedgerHub creates a new hardware wallet manager for Ledger devices. // NewLedgerHub creates a new hardware wallet manager for Ledger devices.
@ -138,6 +140,10 @@ func (hub *Hub) refreshWallets() {
if elapsed < refreshThrottling { if elapsed < refreshThrottling {
return return
} }
// If USB enumeration is continually failing, don't keep trying indefinitely
if atomic.LoadUint32(&hub.enumFails) > 2 {
return
}
// Retrieve the current list of USB wallet devices // Retrieve the current list of USB wallet devices
var devices []usb.DeviceInfo var devices []usb.DeviceInfo
@ -156,13 +162,17 @@ func (hub *Hub) refreshWallets() {
} }
infos, err := usb.Enumerate(hub.vendorID, 0) infos, err := usb.Enumerate(hub.vendorID, 0)
if err != nil { if err != nil {
failcount := atomic.AddUint32(&hub.enumFails, 1)
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
// See rationale before the enumeration why this is needed and only on Linux. // See rationale before the enumeration why this is needed and only on Linux.
hub.commsLock.Unlock() hub.commsLock.Unlock()
} }
log.Error("error enumerating USB enumeration: ", "code", err) log.Error("Failed to enumerate USB devices", "hub", hub.scheme,
"vendor", hub.vendorID, "failcount", failcount, "err", err)
return return
} }
atomic.StoreUint32(&hub.enumFails, 0)
for _, info := range infos { for _, info := range infos {
for _, id := range hub.productIDs { for _, id := range hub.productIDs {
// Windows and Macos use UsageID matching, Linux uses Interface matching // Windows and Macos use UsageID matching, Linux uses Interface matching