github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/kernel.go (about) 1 // MIT License 2 // 3 // Copyright (c) 2023 Paweł Gaczyński 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a 6 // copy of this software and associated documentation files (the 7 // "Software"), to deal in the Software without restriction, including 8 // without limitation the rights to use, copy, modify, merge, publish, 9 // distribute, sublicense, and/or sell copies of the Software, and to 10 // permit persons to whom the Software is furnished to do so, subject to 11 // the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be included 14 // in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 package giouring 25 26 import ( 27 "fmt" 28 29 "golang.org/x/sys/unix" 30 ) 31 32 type KernelVersion struct { 33 Kernel int 34 Major int 35 Minor int 36 Flavor string 37 } 38 39 const ( 40 firstNumberOfParts = 2 41 secondNumberOfParts = 1 42 ) 43 44 func parseKernelVersion(kernelVersionStr string) (*KernelVersion, error) { 45 var ( 46 kernel, major, minor, parsed int 47 flavor, partial string 48 ) 49 50 parsed, _ = fmt.Sscanf(kernelVersionStr, "%d.%d%s", &kernel, &major, &partial) 51 if parsed < firstNumberOfParts { 52 return nil, fmt.Errorf("cannot parse kernel version: %s", kernelVersionStr) 53 } 54 55 parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor) 56 if parsed < secondNumberOfParts { 57 flavor = partial 58 } 59 60 return &KernelVersion{ 61 Kernel: kernel, 62 Major: major, 63 Minor: minor, 64 Flavor: flavor, 65 }, nil 66 } 67 68 func GetKernelVersion() (*KernelVersion, error) { 69 uts := &unix.Utsname{} 70 71 if err := unix.Uname(uts); err != nil { 72 return nil, err 73 } 74 75 return parseKernelVersion(unix.ByteSliceToString(uts.Release[:])) 76 } 77 78 func CompareKernelVersion(a, b KernelVersion) int { 79 if a.Kernel > b.Kernel { 80 return 1 81 } else if a.Kernel < b.Kernel { 82 return -1 83 } 84 85 if a.Major > b.Major { 86 return 1 87 } else if a.Major < b.Major { 88 return -1 89 } 90 91 if a.Minor > b.Minor { 92 return 1 93 } else if a.Minor < b.Minor { 94 return -1 95 } 96 97 return 0 98 } 99 100 func CheckKernelVersion(k, major, minor int) (bool, error) { 101 var ( 102 v *KernelVersion 103 err error 104 ) 105 if v, err = GetKernelVersion(); err != nil { 106 return false, err 107 } 108 if CompareKernelVersion(*v, KernelVersion{Kernel: k, Major: major, Minor: minor}) < 0 { 109 return false, nil 110 } 111 112 return true, nil 113 }