github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/sanity/version.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package sanity 21 22 import ( 23 "bytes" 24 "fmt" 25 "io/ioutil" 26 "path/filepath" 27 "strings" 28 29 "github.com/snapcore/snapd/dirs" 30 "github.com/snapcore/snapd/logger" 31 "github.com/snapcore/snapd/osutil" 32 "github.com/snapcore/snapd/release" 33 "github.com/snapcore/snapd/strutil" 34 ) 35 36 func init() { 37 checks = append(checks, checkKernelVersion) 38 } 39 40 // supportsMayDetachMounts checks whether a RHEL 7.4+ specific kernel knob is present 41 // and set to proper value 42 func supportsMayDetachMounts(kver string) error { 43 p := filepath.Join(dirs.GlobalRootDir, "/proc/sys/fs/may_detach_mounts") 44 value, err := ioutil.ReadFile(p) 45 if err != nil { 46 return fmt.Errorf("cannot read the value of fs.may_detach_mounts kernel parameter: %v", err) 47 } 48 if !bytes.Equal(value, []byte("1\n")) { 49 return fmt.Errorf("fs.may_detach_mounts kernel parameter is supported but disabled") 50 } 51 return nil 52 } 53 54 // checkKernelVersion looks for some unsupported configurations that users may 55 // encounter and provides advice on how to resolve them. 56 func checkKernelVersion() error { 57 if !release.OnClassic { 58 return nil 59 } 60 61 switch release.ReleaseInfo.ID { 62 case "ubuntu": 63 if release.ReleaseInfo.VersionID == "14.04" { 64 kver := osutil.KernelVersion() 65 // a kernel version looks like this: "4.4.0-112-generic" and 66 // we are only interested in the bits before the "-" 67 kver = strings.SplitN(kver, "-", 2)[0] 68 cmp, err := strutil.VersionCompare(kver, "3.13.0") 69 if err != nil { 70 logger.Noticef("cannot check kernel: %v", err) 71 return nil 72 } 73 if cmp <= 0 { 74 return fmt.Errorf("you need to reboot into a 4.4 kernel to start using snapd") 75 } 76 } 77 case "rhel", "centos": 78 // check for kernel tweaks on RHEL/CentOS 7.5+ 79 // CentoS 7.5 has VERSION_ID="7", RHEL 7.6 has VERSION_ID="7.6" 80 if release.ReleaseInfo.VersionID == "" || release.ReleaseInfo.VersionID[0] != '7' { 81 return nil 82 } 83 fullKver := osutil.KernelVersion() 84 // kernel version looks like this: "3.10.0-957.el7.x86_64" 85 kver := strings.SplitN(fullKver, "-", 2)[0] 86 cmp, err := strutil.VersionCompare(kver, "3.18.0") 87 if err != nil { 88 logger.Noticef("cannot check kernel: %v", err) 89 return nil 90 } 91 if cmp < 0 { 92 // pre 3.18 kernels here 93 if idx := strings.Index(fullKver, ".el7."); idx == -1 { 94 // non stock kernel, assume it's not supported 95 return fmt.Errorf("unsupported kernel version %q, you need to switch to the stock kernel", fullKver) 96 } 97 // stock kernel had bugfixes backported to it 98 return supportsMayDetachMounts(kver) 99 } 100 } 101 return nil 102 }