Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/runtime/export_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const SigeventMaxSize = _sigev_max_size

var NewOSProc0 = newosproc0
var Mincore = mincore
var ParseRelease = parseRelease

type Siginfo siginfo
type Sigevent sigevent
6 changes: 4 additions & 2 deletions src/runtime/os_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -962,9 +962,11 @@ func getKernelVersion() kernelVersion {
// semver syntax, but allows the minor and patch versions to be
// elided.
func parseRelease(rel string) (major, minor, patch int, ok bool) {
// Strip anything after a dash or plus.
// Strip anything after a dash, plus, or underscore. Some
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change seems fine, but we no longer actually follow semver grammar, strictly speaking (to be fair, Synology et al. started it). Maybe note this in the doc comment above? E.g.,

// parseRelease parses a dot-separated version number.
// It follows semver syntax, but allows the minor and patch
// versions to be elided, and accepts "_" as a separator for
// pre-release labels in addition to "-".

or words to that effect.

(Likewise we don't handle build labels either, though if we got one of those on a kernel release we probably have bigger issues 😅)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, this code from Go (which is like 10 years old) never did semver... it also parse "4.5" without a patch.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think we need to match the spec, my comment was mostly just about updating the comment. But it's unexported, so certainly not essential.

// embedded Linux vendors (e.g., Synology) append a platform
// identifier with an underscore, like "3.4.35_hi3535".
for i := 0; i < len(rel); i++ {
if rel[i] == '-' || rel[i] == '+' {
if rel[i] == '-' || rel[i] == '+' || rel[i] == '_' {
rel = rel[:i]
break
}
Expand Down
25 changes: 25 additions & 0 deletions src/runtime/runtime_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ func TestMincoreErrorSign(t *testing.T) {
}
}

func TestParseRelease(t *testing.T) {
tests := []struct {
in string
major, minor, patch int
ok bool
}{
{"6.1.0", 6, 1, 0, true},
{"5.15.0-91-generic", 5, 15, 0, true},
{"4.19.0+", 4, 19, 0, true},
// Synology embedded Linux appends a platform identifier
// after an underscore.
{"3.4.35_hi3535", 3, 4, 35, true},
{"2.6.32_synology", 2, 6, 32, true},
{"3.10", 3, 10, 0, true},
{"bogus", 0, 0, 0, false},
}
for _, tt := range tests {
major, minor, patch, ok := ParseRelease(tt.in)
if major != tt.major || minor != tt.minor || patch != tt.patch || ok != tt.ok {
t.Errorf("ParseRelease(%q) = (%d, %d, %d, %v); want (%d, %d, %d, %v)",
tt.in, major, minor, patch, ok, tt.major, tt.minor, tt.patch, tt.ok)
}
}
}

func TestKernelStructSize(t *testing.T) {
// Check that the Go definitions of structures exchanged with the kernel are
// the same size as what the kernel defines.
Expand Down
Loading