github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/configstate/configcore/journal.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 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 configcore 21 22 import ( 23 "fmt" 24 "os" 25 "path/filepath" 26 27 "github.com/snapcore/snapd/dirs" 28 "github.com/snapcore/snapd/osutil" 29 "github.com/snapcore/snapd/osutil/sys" 30 "github.com/snapcore/snapd/overlord/configstate/config" 31 "github.com/snapcore/snapd/systemd" 32 ) 33 34 var osutilFindGid = osutil.FindGid 35 var sysChownPath = sys.ChownPath 36 37 func init() { 38 supportedConfigurations["core.journal.persistent"] = true 39 } 40 41 func validateJournalSettings(tr config.ConfGetter) error { 42 return validateBoolFlag(tr, "journal.persistent") 43 } 44 45 func handleJournalConfiguration(tr config.ConfGetter, opts *fsOnlyContext) error { 46 output, err := coreCfg(tr, "journal.persistent") 47 if err != nil { 48 return nil 49 } 50 51 if output == "" { 52 return nil 53 } 54 55 rootDir := dirs.GlobalRootDir 56 if opts != nil { 57 rootDir = opts.RootDir 58 } 59 60 tempLogPath := filepath.Join(rootDir, "/var/log/journal-snapd") 61 logPath := filepath.Join(rootDir, "/var/log/journal") 62 marker := ".snapd-created" 63 64 logDirExists, _, _ := osutil.DirExists(logPath) 65 66 switch output { 67 case "true": 68 if logDirExists { 69 // don't check marker; if the directory exists then logging is 70 // already enabled (although possibly not controlled by us), but 71 // don't error out. In such case we will error out if setting 72 // to false is attempted. 73 return nil 74 } 75 if err := os.MkdirAll(tempLogPath, 0755); err != nil { 76 return err 77 } 78 if err := osutil.AtomicWriteFile(filepath.Join(tempLogPath, marker), nil, 0700, 0); err != nil { 79 return nil 80 } 81 if err := os.Rename(tempLogPath, logPath); err != nil { 82 return err 83 } 84 case "false": 85 if !logDirExists { 86 return nil 87 } 88 // only remove journal log dir if our marker file is there 89 if !osutil.FileExists(filepath.Join(logPath, marker)) { 90 return fmt.Errorf("the %s directory was not created by snapd, journal logs will not be removed nor disabled", logPath) 91 } 92 // This removes all logs from /var/log/journal when journal.persistent 93 // is set to false. 94 // It's assumed that core device is fully controlled by snapd. 95 if err := os.RemoveAll(logPath); err != nil { 96 return err 97 } 98 default: 99 return fmt.Errorf("unsupported journal.persistent option: %q", output) 100 } 101 102 if opts == nil { 103 ver, err := systemd.Version() 104 if err != nil { 105 return err 106 } 107 108 // old systemd-journal (e.g. on core16) closes the pipes on SIGUSR1, 109 // causing SIGPIPE and restart of snapd and other services. 110 // upstream bug: https://bugs.freedesktop.org/show_bug.cgi?id=84923, 111 // therefore only tell journald to reload if it's new enough. 112 if ver >= 236 { 113 sysd := systemd.New(dirs.GlobalRootDir, systemd.SystemMode, nil) 114 if err := sysd.Kill("systemd-journald", "USR1", ""); err != nil { 115 return err 116 } 117 } 118 } 119 120 return nil 121 }