Merge pull request #10515 from hashicorp/dnephin/fix-arm32-atomic-aligment
Fix panic on 32-bit platforms
This commit is contained in:
commit
72ea979c39
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
agent: fix a panic on 32-bit platforms caused by misaligned struct fields used with sync/atomic.
|
||||||
|
```
|
|
@ -116,14 +116,20 @@ jobs:
|
||||||
- run: go get -u github.com/hashicorp/lint-consul-retry && lint-consul-retry
|
- run: go get -u github.com/hashicorp/lint-consul-retry && lint-consul-retry
|
||||||
- run: *notify-slack-failure
|
- run: *notify-slack-failure
|
||||||
|
|
||||||
# Runs Go linters
|
|
||||||
lint:
|
lint:
|
||||||
|
description: "Run golangci-lint"
|
||||||
|
parameters:
|
||||||
|
go-arch:
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
docker:
|
docker:
|
||||||
- image: *GOLANG_IMAGE
|
- image: *GOLANG_IMAGE
|
||||||
environment:
|
environment:
|
||||||
GOTAGS: "" # No tags for OSS but there are for enterprise
|
GOTAGS: "" # No tags for OSS but there are for enterprise
|
||||||
|
GOARCH: "<<parameters.go-arch>>"
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- run: go env
|
||||||
- run:
|
- run:
|
||||||
name: Install golangci-lint
|
name: Install golangci-lint
|
||||||
command: |
|
command: |
|
||||||
|
@ -275,6 +281,40 @@ jobs:
|
||||||
path: /tmp/jsonfile
|
path: /tmp/jsonfile
|
||||||
- run: *notify-slack-failure
|
- run: *notify-slack-failure
|
||||||
|
|
||||||
|
# go-test-32bit is to catch problems where 64-bit ints must be 64-bit aligned
|
||||||
|
# to use them with sync/atomic. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
# Running tests with GOARCH=386 seems to be the best way to detect this
|
||||||
|
# problem. Only runs tests that are -short to limit the time we spend checking
|
||||||
|
# for these bugs.
|
||||||
|
go-test-32bit:
|
||||||
|
docker:
|
||||||
|
- image: *GOLANG_IMAGE
|
||||||
|
environment:
|
||||||
|
<<: *ENVIRONMENT
|
||||||
|
GOTAGS: "" # No tags for OSS but there are for enterprise
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run: *install-gotestsum
|
||||||
|
- run: go mod download
|
||||||
|
- run:
|
||||||
|
name: go test 32-bit
|
||||||
|
environment:
|
||||||
|
GOARCH: 386
|
||||||
|
command: |
|
||||||
|
mkdir -p $TEST_RESULTS_DIR /tmp/jsonfile
|
||||||
|
go env
|
||||||
|
gotestsum \
|
||||||
|
--jsonfile /tmp/jsonfile/go-test-32bit.log \
|
||||||
|
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
||||||
|
-tags="$GOTAGS" -p 2 \
|
||||||
|
-short ./...
|
||||||
|
|
||||||
|
- store_test_results:
|
||||||
|
path: *TEST_RESULTS_DIR
|
||||||
|
- store_artifacts:
|
||||||
|
path: *TEST_RESULTS_DIR
|
||||||
|
- run: *notify-slack-failure
|
||||||
|
|
||||||
go-test-lib:
|
go-test-lib:
|
||||||
description: "test a library against a specific Go version"
|
description: "test a library against a specific Go version"
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -959,6 +999,10 @@ workflows:
|
||||||
- check-generated-protobuf: *filter-ignore-non-go-branches
|
- check-generated-protobuf: *filter-ignore-non-go-branches
|
||||||
- lint-consul-retry: *filter-ignore-non-go-branches
|
- lint-consul-retry: *filter-ignore-non-go-branches
|
||||||
- lint: *filter-ignore-non-go-branches
|
- lint: *filter-ignore-non-go-branches
|
||||||
|
- lint:
|
||||||
|
name: "lint-32bit"
|
||||||
|
go-arch: "386"
|
||||||
|
<<: *filter-ignore-non-go-branches
|
||||||
- test-connect-ca-providers: *filter-ignore-non-go-branches
|
- test-connect-ca-providers: *filter-ignore-non-go-branches
|
||||||
- dev-build: *filter-ignore-non-go-branches
|
- dev-build: *filter-ignore-non-go-branches
|
||||||
- go-test:
|
- go-test:
|
||||||
|
@ -984,6 +1028,7 @@ workflows:
|
||||||
go-version: "1.15"
|
go-version: "1.15"
|
||||||
<<: *filter-ignore-non-go-branches
|
<<: *filter-ignore-non-go-branches
|
||||||
- go-test-race: *filter-ignore-non-go-branches
|
- go-test-race: *filter-ignore-non-go-branches
|
||||||
|
- go-test-32bit: *filter-ignore-non-go-branches
|
||||||
build-distros:
|
build-distros:
|
||||||
unless: << pipeline.parameters.trigger-load-test >>
|
unless: << pipeline.parameters.trigger-load-test >>
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
@ -5473,7 +5473,7 @@ func TestLoad_FullConfig(t *testing.T) {
|
||||||
HTTPSPort: 15127,
|
HTTPSPort: 15127,
|
||||||
HTTPUseCache: false,
|
HTTPUseCache: false,
|
||||||
KeyFile: "IEkkwgIA",
|
KeyFile: "IEkkwgIA",
|
||||||
KVMaxValueSize: 1234567800000000,
|
KVMaxValueSize: 1234567800,
|
||||||
LeaveDrainTime: 8265 * time.Second,
|
LeaveDrainTime: 8265 * time.Second,
|
||||||
LeaveOnTerm: true,
|
LeaveOnTerm: true,
|
||||||
Logging: logging.Config{
|
Logging: logging.Config{
|
||||||
|
@ -5868,7 +5868,7 @@ func TestLoad_FullConfig(t *testing.T) {
|
||||||
"wan_ipv4": "78.63.37.19",
|
"wan_ipv4": "78.63.37.19",
|
||||||
},
|
},
|
||||||
TranslateWANAddrs: true,
|
TranslateWANAddrs: true,
|
||||||
TxnMaxReqLen: 5678000000000000,
|
TxnMaxReqLen: 567800000,
|
||||||
UIConfig: UIConfig{
|
UIConfig: UIConfig{
|
||||||
Dir: "pVncV4Ey",
|
Dir: "pVncV4Ey",
|
||||||
ContentPath: "/qp1WRhYH/", // slashes are added in parsing
|
ContentPath: "/qp1WRhYH/", // slashes are added in parsing
|
||||||
|
|
|
@ -285,8 +285,8 @@ limits {
|
||||||
rpc_rate = 12029.43
|
rpc_rate = 12029.43
|
||||||
rpc_max_burst = 44848
|
rpc_max_burst = 44848
|
||||||
rpc_max_conns_per_client = 2954
|
rpc_max_conns_per_client = 2954
|
||||||
kv_max_value_size = 1234567800000000
|
kv_max_value_size = 1234567800
|
||||||
txn_max_req_len = 5678000000000000
|
txn_max_req_len = 567800000
|
||||||
}
|
}
|
||||||
log_level = "k1zo9Spt"
|
log_level = "k1zo9Spt"
|
||||||
log_json = true
|
log_json = true
|
||||||
|
|
|
@ -285,8 +285,8 @@
|
||||||
"rpc_rate": 12029.43,
|
"rpc_rate": 12029.43,
|
||||||
"rpc_max_burst": 44848,
|
"rpc_max_burst": 44848,
|
||||||
"rpc_max_conns_per_client": 2954,
|
"rpc_max_conns_per_client": 2954,
|
||||||
"kv_max_value_size": 1234567800000000,
|
"kv_max_value_size": 1234567800,
|
||||||
"txn_max_req_len": 5678000000000000
|
"txn_max_req_len": 567800000
|
||||||
},
|
},
|
||||||
"log_level": "k1zo9Spt",
|
"log_level": "k1zo9Spt",
|
||||||
"log_json": true,
|
"log_json": true,
|
||||||
|
|
|
@ -52,8 +52,11 @@ var defaultMetrics = metrics.Default
|
||||||
// statsHandler is a grpc/stats.StatsHandler which emits connection and
|
// statsHandler is a grpc/stats.StatsHandler which emits connection and
|
||||||
// request metrics to go-metrics.
|
// request metrics to go-metrics.
|
||||||
type statsHandler struct {
|
type statsHandler struct {
|
||||||
|
// activeConns is used with sync/atomic and MUST be 64-bit aligned. To ensure
|
||||||
|
// alignment on 32-bit platforms this field must remain the first field in
|
||||||
|
// the struct. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
activeConns uint64
|
||||||
metrics *metrics.Metrics
|
metrics *metrics.Metrics
|
||||||
activeConns uint64 // must be 8-byte aligned for atomic access
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStatsHandler(m *metrics.Metrics) *statsHandler {
|
func newStatsHandler(m *metrics.Metrics) *statsHandler {
|
||||||
|
@ -103,10 +106,11 @@ func (c *statsHandler) HandleConn(_ context.Context, s stats.ConnStats) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type activeStreamCounter struct {
|
type activeStreamCounter struct {
|
||||||
|
// count is used with sync/atomic and MUST be 64-bit aligned. To ensure
|
||||||
|
// alignment on 32-bit platforms this field must remain the first field in
|
||||||
|
// the struct. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
count uint64
|
||||||
metrics *metrics.Metrics
|
metrics *metrics.Metrics
|
||||||
// count of the number of open streaming RPCs on a server. It is accessed
|
|
||||||
// atomically.
|
|
||||||
count uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRPCCountingStreamInterceptor is a grpc.ServerStreamInterceptor that emits a
|
// GRPCCountingStreamInterceptor is a grpc.ServerStreamInterceptor that emits a
|
||||||
|
|
|
@ -59,6 +59,10 @@ func TestRun_FlagValidation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateConfigFromFlags(t *testing.T) {
|
func TestGenerateConfigFromFlags(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("too slow for testing.Short")
|
||||||
|
}
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
command func() cmd
|
command func() cmd
|
||||||
|
|
|
@ -175,6 +175,11 @@ type manual struct {
|
||||||
// Configurator receives an initial TLS configuration from agent configuration,
|
// Configurator receives an initial TLS configuration from agent configuration,
|
||||||
// and receives updates from config reloads, auto-encrypt, and auto-config.
|
// and receives updates from config reloads, auto-encrypt, and auto-config.
|
||||||
type Configurator struct {
|
type Configurator struct {
|
||||||
|
// version is increased each time the Configurator is updated. Must be accessed
|
||||||
|
// using sync/atomic. Also MUST be the first field in this struct to ensure
|
||||||
|
// 64-bit alignment. See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
version uint64
|
||||||
|
|
||||||
// lock synchronizes access to all fields on this struct except for logger and version.
|
// lock synchronizes access to all fields on this struct except for logger and version.
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
base *Config
|
base *Config
|
||||||
|
@ -188,9 +193,6 @@ type Configurator struct {
|
||||||
// logger is not protected by a lock. It must never be changed after
|
// logger is not protected by a lock. It must never be changed after
|
||||||
// Configurator is created.
|
// Configurator is created.
|
||||||
logger hclog.Logger
|
logger hclog.Logger
|
||||||
// version is increased each time the Configurator is updated. Must be accessed
|
|
||||||
// using sync/atomic.
|
|
||||||
version uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigurator creates a new Configurator and sets the provided
|
// NewConfigurator creates a new Configurator and sets the provided
|
||||||
|
|
Loading…
Reference in New Issue