Fetch the repository succeeded.
This action will force synchronization from tupelo-shen/mysnapd, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
// -*- Mode: Go; indent-tabs-mode: t -*-
//go:build !nomanagers
// +build !nomanagers
/*
* Copyright (C) 2020 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package configcore
import (
"errors"
"fmt"
"strings"
"gitee.com/mysnapcore/mysnapd/overlord/configstate/config"
"gitee.com/mysnapcore/mysnapd/overlord/servicestate"
"gitee.com/mysnapcore/mysnapd/overlord/snapstate"
"gitee.com/mysnapcore/mysnapd/overlord/state"
"gitee.com/mysnapcore/mysnapd/progress"
"gitee.com/mysnapcore/mysnapd/snap"
"gitee.com/mysnapcore/mysnapd/snap/naming"
"gitee.com/mysnapcore/mysnapd/timings"
"gitee.com/mysnapcore/mysnapd/wrappers"
)
const vitalityOpt = "resilience.vitality-hint"
func init() {
// add supported configuration of this module
supportedConfigurations["core."+vitalityOpt] = true
}
func handleVitalityConfiguration(tr config.Conf, opts *fsOnlyContext) error {
var pristineVitalityStr, newVitalityStr string
if err := tr.GetPristine("core", vitalityOpt, &pristineVitalityStr); err != nil && !config.IsNoOption(err) {
return err
}
if err := tr.Get("core", vitalityOpt, &newVitalityStr); err != nil && !config.IsNoOption(err) {
return err
}
if pristineVitalityStr == newVitalityStr {
return nil
}
st := tr.State()
st.Lock()
defer st.Unlock()
// TODO: Reimplement most of this as a servicestate.UpdateVitalityRank
oldVitalityMap := map[string]int{}
newVitalityMap := map[string]int{}
// assign "0" (delete) rank to all old entries
for i, instanceName := range strings.Split(pristineVitalityStr, ",") {
oldVitalityMap[instanceName] = i + 1
newVitalityMap[instanceName] = 0
}
// build rank of the new entries
for i, instanceName := range strings.Split(newVitalityStr, ",") {
newVitalityMap[instanceName] = i + 1
}
// use a single cache of the quota groups for calculating the quota groups
// that services should be in
grps, err := servicestate.AllQuotas(st)
if err != nil {
return err
}
for instanceName, rank := range newVitalityMap {
var snapst snapstate.SnapState
err := snapstate.Get(st, instanceName, &snapst)
// not installed, vitality-score will be applied when the snap
// gets installed
if errors.Is(err, state.ErrNoState) {
continue
}
if err != nil {
return err
}
// not active, vitality-score will be applied when the snap
// becomes active
if !snapst.Active {
continue
}
info, err := snapst.CurrentInfo()
if err != nil {
return err
}
// nothing to do if rank is unchanged
if oldVitalityMap[instanceName] == newVitalityMap[instanceName] {
continue
}
// rank changed, rewrite/restart services
// first get the device context to decide if we need to set
// RequireMountedSnapdSnap
// TODO: use sysconfig.Device instead
deviceCtx, err := snapstate.DeviceCtx(st, nil, nil)
if err != nil {
return err
}
ensureOpts := &wrappers.EnsureSnapServicesOptions{}
// we need the snapd snap mounted whenever in order for services to
// start for all services on UC18+
if !deviceCtx.Classic() && deviceCtx.Model().Base() != "" {
ensureOpts.RequireMountedSnapdSnap = true
}
// get the options for this snap service
snapSvcOpts, err := servicestate.SnapServiceOptions(st, instanceName, grps)
if err != nil {
return err
}
m := map[*snap.Info]*wrappers.SnapServiceOptions{
info: snapSvcOpts,
}
// overwrite the VitalityRank we got from SnapServiceOptions to use the
// rank we calculated as part of this transaction
m[info].VitalityRank = rank
// ensure that the snap services are re-written with these units
if err := wrappers.EnsureSnapServices(m, ensureOpts, nil, progress.Null); err != nil {
return err
}
// and then restart the services
// TODO: this doesn't actually restart the services, meaning that the
// OOMScoreAdjust vitality-hint ranking doesn't take effect until the
// service is restarted by a refresh or a reboot, etc.
// TODO: this option also doesn't work with services that use
// Delegate=true, i.e. docker, greengrass, kubernetes, so we should do
// something about that combination because currently we jus silently
// apply the setting which never does anything
// XXX: copied from handlers.go:startSnapServices()
disabledSvcs, err := wrappers.QueryDisabledServices(info, progress.Null)
if err != nil {
return err
}
svcs := info.Services()
startupOrdered, err := snap.SortServices(svcs)
if err != nil {
return err
}
flags := &wrappers.StartServicesFlags{Enable: true}
tm := timings.New(nil)
if err = wrappers.StartServices(startupOrdered, disabledSvcs, flags, progress.Null, tm); err != nil {
return err
}
}
return nil
}
func validateVitalitySettings(tr config.Conf) error {
option, err := coreCfg(tr, vitalityOpt)
if err != nil {
return err
}
if option == "" {
return nil
}
vitalityHints := strings.Split(option, ",")
if len(vitalityHints) > 100 {
return fmt.Errorf("cannot set more than 100 snaps in %q: got %v", vitalityOpt, len(vitalityHints))
}
for _, instanceName := range vitalityHints {
if err := naming.ValidateInstance(instanceName); err != nil {
return fmt.Errorf("cannot set %q: %v", vitalityOpt, err)
}
// The "snapd" snap is always at OOMScoreAdjust=-900.
if instanceName == "snapd" {
return fmt.Errorf("cannot set %q: snapd snap vitality cannot be changed", vitalityOpt)
}
}
return nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。