提交 903e43fb 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!85 atune: sync dev branch code

Merge pull request !85 from hanxinke/master
...@@ -137,8 +137,7 @@ func NewClient(addr string, port string, opts ...Opt) (*Client, error) { ...@@ -137,8 +137,7 @@ func NewClient(addr string, port string, opts ...Opt) (*Client, error) {
func UnixConnect(ctx context.Context, addr string) (net.Conn, error) { func UnixConnect(ctx context.Context, addr string) (net.Conn, error) {
unix_addr, _ := net.ResolveUnixAddr("unix", addr) unix_addr, _ := net.ResolveUnixAddr("unix", addr)
conn, err := net.DialUnix("unix", nil, unix_addr) return net.DialUnix("unix", nil, unix_addr)
return conn, err
} }
func newClient(address string, opts ...Opt) (*Client, error) { func newClient(address string, opts ...Opt) (*Client, error) {
......
...@@ -97,6 +97,7 @@ const ( ...@@ -97,6 +97,7 @@ const (
var ( var (
TransProtocol string TransProtocol string
Address string Address string
Connect string
Port string Port string
RestPort string RestPort string
TLS bool TLS bool
...@@ -134,6 +135,7 @@ func (c *Cfg) Load() error { ...@@ -134,6 +135,7 @@ func (c *Cfg) Load() error {
section := cfg.Section("server") section := cfg.Section("server")
TransProtocol = section.Key("protocol").MustString(DefaultProtocol) TransProtocol = section.Key("protocol").MustString(DefaultProtocol)
Address = section.Key("address").MustString(DefaultTgtAddr) Address = section.Key("address").MustString(DefaultTgtAddr)
Connect = section.Key("connect").MustString("")
Port = section.Key("port").MustString(DefaultTgtPort) Port = section.Key("port").MustString(DefaultTgtPort)
RestPort = section.Key("rest_port").MustString("8383") RestPort = section.Key("rest_port").MustString("8383")
TLS = section.Key("tls").MustBool(false) TLS = section.Key("tls").MustBool(false)
......
...@@ -128,7 +128,7 @@ func (p *Profile) Backup() error { ...@@ -128,7 +128,7 @@ func (p *Profile) Backup() error {
backedPath := path.Join(config.DefaultBackupPath, p.name+"_"+timeUnix) backedPath := path.Join(config.DefaultBackupPath, p.name+"_"+timeUnix)
err := os.MkdirAll(backedPath, 0750) err := os.MkdirAll(backedPath, 0750)
if err != nil { if err != nil {
log.Error(err.Error()) log.Error("failed to create backup path")
return nil return nil
} }
......
...@@ -108,7 +108,7 @@ func (y *YamlPrjCli) BenchMark() (string, error) { ...@@ -108,7 +108,7 @@ func (y *YamlPrjCli) BenchMark() (string, error) {
} }
// RunSet method call the set script to set the value // RunSet method call the set script to set the value
func (y *YamlPrjSvr) RunSet(optStr string) error { func (y *YamlPrjSvr) RunSet(optStr string) (error, string) {
paraMap := make(map[string]string) paraMap := make(map[string]string)
paraSlice := strings.Split(optStr, ",") paraSlice := strings.Split(optStr, ",")
for _, para := range paraSlice { for _, para := range paraSlice {
...@@ -118,10 +118,11 @@ func (y *YamlPrjSvr) RunSet(optStr string) error { ...@@ -118,10 +118,11 @@ func (y *YamlPrjSvr) RunSet(optStr string) error {
} }
paraMap[kvs[0]] = kvs[1] paraMap[kvs[0]] = kvs[1]
} }
scripts := make([]string, 0)
for _, obj := range y.Object { for _, obj := range y.Object {
out, err := ExecCommand(obj.Info.GetScript) out, err := ExecCommand(obj.Info.GetScript)
if err != nil { if err != nil {
return fmt.Errorf("failed to exec %s, err: %v", obj.Info.GetScript, err) return fmt.Errorf("failed to exec %s, err: %v", obj.Info.GetScript, err), ""
} }
if strings.TrimSpace(string(out)) == paraMap[obj.Name] { if strings.TrimSpace(string(out)) == paraMap[obj.Name] {
...@@ -133,14 +134,15 @@ func (y *YamlPrjSvr) RunSet(optStr string) error { ...@@ -133,14 +134,15 @@ func (y *YamlPrjSvr) RunSet(optStr string) error {
log.Info("set script:", newScript) log.Info("set script:", newScript)
_, err = ExecCommand(newScript) _, err = ExecCommand(newScript)
if err != nil { if err != nil {
return fmt.Errorf("failed to exec %s, err: %v", newScript, err) return fmt.Errorf("failed to exec %s, err: %v", newScript, err), ""
} }
scripts = append(scripts, newScript)
} }
return nil return nil, strings.Join(scripts, ",")
} }
// RestartProject method call the StartWorkload and StopWorkload script to restart the service // RestartProject method call the StartWorkload and StopWorkload script to restart the service
func (y *YamlPrjSvr) RestartProject() error { func (y *YamlPrjSvr) RestartProject() (error, string) {
startWorkload := y.Startworkload startWorkload := y.Startworkload
stopWorkload := y.Stopworkload stopWorkload := y.Stopworkload
...@@ -152,26 +154,30 @@ func (y *YamlPrjSvr) RestartProject() error { ...@@ -152,26 +154,30 @@ func (y *YamlPrjSvr) RestartProject() error {
break break
} }
} }
scripts := make([]string, 0)
if needRestart { if needRestart {
out, err := ExecCommand(stopWorkload) out, err := ExecCommand(stopWorkload)
if err != nil { if err != nil {
return fmt.Errorf("failed to exec %s, err: %v", stopWorkload, err) return fmt.Errorf("failed to exec %s, err: %v", stopWorkload, err), ""
} }
log.Debug(string(out)) log.Debug(string(out))
scripts = append(scripts, stopWorkload)
out, err = ExecCommand(startWorkload) out, err = ExecCommand(startWorkload)
if err != nil { if err != nil {
return fmt.Errorf("failed to exec %s, err: %v", startWorkload, err) return fmt.Errorf("failed to exec %s, err: %v", startWorkload, err), ""
} }
log.Debug(string(out)) log.Debug(string(out))
scripts = append(scripts, startWorkload)
} }
return nil return nil, strings.Join(scripts, ",")
} }
//exec command and get result //exec command and get result
func ExecCommand(script string) ([]byte, error) { func ExecCommand(script string) ([]byte, error) {
cmd := exec.Command("sh", "-c", script) cmd := exec.Command("sh", "-c", script)
out, err := cmd.CombinedOutput() return cmd.CombinedOutput()
return out, err
} }
...@@ -60,7 +60,7 @@ func (t *Timer) Run() error { ...@@ -60,7 +60,7 @@ func (t *Timer) Run() error {
section, err := t.Cfg.Raw.GetSection("server") section, err := t.Cfg.Raw.GetSection("server")
if err != nil { if err != nil {
log.Errorf("Faild to get section system, error: %v", err) log.Errorf("failed to get section system, error: %v", err)
return err return err
} }
if !section.Haskey("type") { if !section.Haskey("type") {
......
...@@ -15,6 +15,7 @@ package tuning ...@@ -15,6 +15,7 @@ package tuning
import ( import (
PB "atune/api/profile" PB "atune/api/profile"
"atune/common/client"
"atune/common/config" "atune/common/config"
"atune/common/http" "atune/common/http"
"atune/common/log" "atune/common/log"
...@@ -22,6 +23,8 @@ import ( ...@@ -22,6 +23,8 @@ import (
"atune/common/project" "atune/common/project"
"atune/common/utils" "atune/common/utils"
"fmt" "fmt"
"golang.org/x/net/context"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
...@@ -57,7 +60,6 @@ func (o *Optimizer) InitTuned(ch chan *PB.AckCheck) error { ...@@ -57,7 +60,6 @@ func (o *Optimizer) InitTuned(ch chan *PB.AckCheck) error {
//dynamic profle setting //dynamic profle setting
o.MaxIter = clientIter o.MaxIter = clientIter
if o.MaxIter > o.Prj.Maxiterations { if o.MaxIter > o.Prj.Maxiterations {
o.MaxIter = o.Prj.Maxiterations
log.Infof("project:%s max iterations:%d", o.Prj.Project, o.Prj.Maxiterations) log.Infof("project:%s max iterations:%d", o.Prj.Project, o.Prj.Maxiterations)
ch <- &PB.AckCheck{Name: fmt.Sprintf("server project %s max iterations %d\n", ch <- &PB.AckCheck{Name: fmt.Sprintf("server project %s max iterations %d\n",
o.Prj.Project, o.Prj.Maxiterations)} o.Prj.Project, o.Prj.Maxiterations)}
...@@ -153,18 +155,30 @@ func (o *Optimizer) DynamicTuned(ch chan *PB.AckCheck) error { ...@@ -153,18 +155,30 @@ func (o *Optimizer) DynamicTuned(ch chan *PB.AckCheck) error {
} }
log.Infof("setting params is: %s", o.RespPutIns.Param) log.Infof("setting params is: %s", o.RespPutIns.Param)
if err := o.Prj.RunSet(o.RespPutIns.Param); err != nil { err, scripts := o.Prj.RunSet(o.RespPutIns.Param)
if err != nil {
log.Error(err) log.Error(err)
return err return err
} }
log.Info("set the parameter success") log.Info("set the parameter success")
if err := o.Prj.RestartProject(); err != nil { err = syncConfigToOthers(scripts)
if err != nil {
return err
}
err, scripts = o.Prj.RestartProject()
if err != nil {
log.Error(err) log.Error(err)
return err return err
} }
log.Info("restart project success") log.Info("restart project success")
err = syncConfigToOthers(scripts)
if err != nil {
return err
}
o.StartIterTime = time.Now().Format(config.DefaultTimeFormat) o.StartIterTime = time.Now().Format(config.DefaultTimeFormat)
if o.Iter == o.MaxIter { if o.Iter == o.MaxIter {
...@@ -206,11 +220,16 @@ func (o *Optimizer) RestoreConfigTuned(ch chan *PB.AckCheck) error { ...@@ -206,11 +220,16 @@ func (o *Optimizer) RestoreConfigTuned(ch chan *PB.AckCheck) error {
} }
log.Infof("restoring params is: %s", string(content)) log.Infof("restoring params is: %s", string(content))
if err := o.Prj.RunSet(string(content)); err != nil { err, scripts := o.Prj.RunSet(string(content))
if err != nil {
log.Error(err) log.Error(err)
return err return err
} }
if err := syncConfigToOthers(scripts); err != nil {
return err
}
result := fmt.Sprintf("restore %s project params success", o.Prj.Project) result := fmt.Sprintf("restore %s project params success", o.Prj.Project)
ch <- &PB.AckCheck{Name: result, Status: utils.SUCCESS} ch <- &PB.AckCheck{Name: result, Status: utils.SUCCESS}
log.Infof(result) log.Infof(result)
...@@ -301,3 +320,80 @@ func CheckServerPrj(data string, optimizer *Optimizer) error { ...@@ -301,3 +320,80 @@ func CheckServerPrj(data string, optimizer *Optimizer) error {
return fmt.Errorf("project:%s not found", data) return fmt.Errorf("project:%s not found", data)
} }
//sync tuned node
func (o *Optimizer) SyncTunedNode(ch chan *PB.AckCheck) error {
log.Infof("setting params is: %s", string(o.Content))
commands := strings.Split(string(o.Content), ",")
for _, command := range commands {
_, err := project.ExecCommand(command)
if err != nil {
return fmt.Errorf("failed to exec %s, err: %v", command, err)
}
}
log.Info("set the parameter success")
ch <- &PB.AckCheck{Status: utils.SUCCESS}
return nil
}
//sync config to other nodes in cluster mode
func syncConfigToOthers(scripts string) error {
if config.TransProtocol != "tcp" || scripts == "" {
return nil
}
otherServers := strings.Split(strings.TrimSpace(config.Connect), ",")
log.Infof("sync other nodes: %s", otherServers)
for _, server := range otherServers {
if server == config.Address || server == "" {
continue
}
if err := syncConfigToNode(server, scripts); err != nil {
log.Errorf("server %s failed to sync config, err: %v", server, err)
return err
}
}
return nil
}
//sync config to server node
func syncConfigToNode(server string, scripts string) error {
c, err := client.NewClient(server, config.Port)
if err != nil {
return err
}
defer c.Close()
svc := PB.NewProfileMgrClient(c.Connection())
stream, err := svc.Tuning(context.Background())
if err != nil {
return err
}
defer stream.CloseSend()
content := &PB.ProfileInfo{Name: "sync-config", Content: []byte(scripts)}
if err := stream.Send(content); err != nil {
return fmt.Errorf("sends failure, error: %v", err)
}
for {
reply, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
return err
}
if reply.Status == utils.SUCCESS {
log.Infof("server %s reply status success", server)
break
}
}
return nil
}
...@@ -21,6 +21,10 @@ protocol = unix ...@@ -21,6 +21,10 @@ protocol = unix
# ranges: /var/run/atuned/atuned.sock or ip address # ranges: /var/run/atuned/atuned.sock or ip address
address = /var/run/atuned/atuned.sock address = /var/run/atuned/atuned.sock
# the atune nodes in cluster mode, separated by commas
# it is valid when protocol is tcp
# connect = ip01,ip02,ip03
# the atuned grpc listening port # the atuned grpc listening port
# the port can be set between 0 to 65535 which not be used # the port can be set between 0 to 65535 which not be used
# port = 60001 # port = 60001
......
...@@ -368,7 +368,7 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM ...@@ -368,7 +368,7 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM
//3. judge the workload type is exist in the database //3. judge the workload type is exist in the database
classProfile := &sqlstore.GetClass{Class: workloadType} classProfile := &sqlstore.GetClass{Class: workloadType}
if err := sqlstore.GetClasses(classProfile); err != nil { if err = sqlstore.GetClasses(classProfile); err != nil {
log.Errorf("inquery workload type table failed %v", err) log.Errorf("inquery workload type table failed %v", err)
return fmt.Errorf("inquery workload type table failed %v", err) return fmt.Errorf("inquery workload type table failed %v", err)
} }
...@@ -476,23 +476,31 @@ func (s *ProfileServer) Tuning(stream PB.ProfileMgr_TuningServer) error { ...@@ -476,23 +476,31 @@ func (s *ProfileServer) Tuning(stream PB.ProfileMgr_TuningServer) error {
data := reply.Name data := reply.Name
content := reply.Content content := reply.Content
//sync config with other server
if data == "sync-config" {
optimizer.Content = content
if err = optimizer.SyncTunedNode(ch); err != nil {
return err
}
continue
}
// data == "" means in tuning process // data == "" means in tuning process
if data == "" { if data == "" {
optimizer.Content = content optimizer.Content = content
err := optimizer.DynamicTuned(ch) if err = optimizer.DynamicTuned(ch); err != nil {
if err != nil {
return err return err
} }
continue continue
} }
if err := tuning.CheckServerPrj(data, &optimizer); err != nil { if err = tuning.CheckServerPrj(data, &optimizer); err != nil {
return err return err
} }
//content == nil means in restore config //content == nil means in restore config
if content == nil { if content == nil {
if err := optimizer.RestoreConfigTuned(ch); err != nil { if err = optimizer.RestoreConfigTuned(ch); err != nil {
return err return err
} }
continue continue
...@@ -575,9 +583,9 @@ func (s *ProfileServer) InfoProfile(profileInfo *PB.ProfileInfo, stream PB.Profi ...@@ -575,9 +583,9 @@ func (s *ProfileServer) InfoProfile(profileInfo *PB.ProfileInfo, stream PB.Profi
profileNames := strings.Split(profileType, ",") profileNames := strings.Split(profileType, ",")
for _, name := range profileNames { for _, name := range profileNames {
name = strings.Trim(name, " ") name = strings.Trim(name, " ")
context, _ := sqlstore.GetContext(name) infoName, _ := sqlstore.GetContext(name)
context = "\n*** " + name + ":\n" + context infoName = "\n*** " + name + ":\n" + infoName
_ = stream.Send(&PB.ProfileInfo{Name: context}) _ = stream.Send(&PB.ProfileInfo{Name: infoName})
} }
return nil return nil
...@@ -706,8 +714,7 @@ func (s *ProfileServer) Collection(message *PB.CollectFlag, stream PB.ProfileMgr ...@@ -706,8 +714,7 @@ func (s *ProfileServer) Collection(message *PB.CollectFlag, stream PB.ProfileMgr
} }
classApps := &sqlstore.GetClassApp{Class: message.GetType()} classApps := &sqlstore.GetClassApp{Class: message.GetType()}
err = sqlstore.GetClassApps(classApps) if err = sqlstore.GetClassApps(classApps); err != nil {
if err != nil {
return err return err
} }
if len(classApps.Result) == 0 { if len(classApps.Result) == 0 {
...@@ -722,11 +729,11 @@ func (s *ProfileServer) Collection(message *PB.CollectFlag, stream PB.ProfileMgr ...@@ -722,11 +729,11 @@ func (s *ProfileServer) Collection(message *PB.CollectFlag, stream PB.ProfileMgr
return fmt.Errorf("output_path %s is not exist", message.GetOutputPath()) return fmt.Errorf("output_path %s is not exist", message.GetOutputPath())
} }
if err := utils.InterfaceByName(message.GetNetwork()); err != nil { if err = utils.InterfaceByName(message.GetNetwork()); err != nil {
return err return err
} }
if err := utils.DiskByName(message.GetBlock()); err != nil { if err = utils.DiskByName(message.GetBlock()); err != nil {
return err return err
} }
......
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-03-03
disk=$(echo "$@" | awk '{print $1}')
value=$(/sbin/blockdev --getra /dev/"$disk")
ret=$?
[ $ret -ne 0 ] && echo "\033[31m failed to command /sbin/blockdev --getra \033[31m" && exit 1
echo "$disk $value"
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-03-03
disk=$(echo "$@" | awk '{print $1}')
value=$(echo "$@" | awk '{print $2}')
/sbin/blockdev --setra "$value" /dev/"$disk"
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
declare -A kmap=(["gro"]="generic-receive-offload" ["gso"]="generic-segmentation-offload" declare -A kmap=(["gro"]="generic-receive-offload" ["gso"]="generic-segmentation-offload"
["tso"]="tcp-segmentation-offload" ["lro"]="large-receive-offload") ["tso"]="tcp-segmentation-offload" ["lro"]="large-receive-offload")
declare -A cmap=(["adaptive-rx"]="Adaptive" ["adaptive-tx"]="Adaptive") declare -A cmap=(["adaptive-rx"]="Adaptive" ["adaptive-tx"]="Adaptive")
declare -A lmap=(["combined"]="Combined")
declare -A gmap=(["rx"]="RX:" ["tx"]="TX:")
koption="on off" koption="on off"
xoption="toeplitz xor crc32" xoption="toeplitz xor crc32"
coption="on off" coption="on off"
...@@ -32,12 +34,18 @@ function get_ethtool_value() { ...@@ -32,12 +34,18 @@ function get_ethtool_value() {
network=${para[1]} network=${para[1]}
case "$option" in case "$option" in
"-K") "-K")
value=$(ethtool -k "$network" | grep -w "${kmap["${para[2]}"]}" | awk '{print $2}') property=$(ethtool -k "$network" | grep -w "${kmap["${para[2]}"]}")
value=$(echo "$property" | awk '{print $2}')
if !(judge_value "$value" $koption); then if !(judge_value "$value" $koption); then
echo "\033[31m the last parameter of ethtool must select in [$koption] \033[31m" echo "\033[31m the last parameter of ethtool must select in [$koption] \033[31m"
return 1 return 1
fi fi
echo "-K $network "${para[2]}" $value" affix=$(echo "$property" | awk '{print $3}')
if [[ "$affix" == "[fixed]" ]]; then
echo "fixed"
else
echo "-K $network "${para[2]}" $value"
fi
;; ;;
"-X") "-X")
for opt in $xoption; do for opt in $xoption; do
...@@ -65,6 +73,14 @@ function get_ethtool_value() { ...@@ -65,6 +73,14 @@ function get_ethtool_value() {
fi fi
echo "-C $network "${para[2]}" $value" echo "-C $network "${para[2]}" $value"
;; ;;
"-L")
value=$(ethtool -l "$network" | grep -w "${lmap["${para[2]}"]}" | awk 'NR==2{print $2}')
echo "-L $network "${para[2]}" $value"
;;
"-G")
value=$(ethtool -g "$network" | grep -w "${gmap["${para[2]}"]}" | awk 'NR==2{print $2}')
echo "-G $network "${para[2]}" $value"
;;
*) *)
echo "\033[31m this option is not supported \033[31m" && return 1 echo "\033[31m this option is not supported \033[31m" && return 1
;; ;;
...@@ -86,3 +102,20 @@ function judge_value() { ...@@ -86,3 +102,20 @@ function judge_value() {
false false
} }
function cmd_conversion() {
option=$(echo "$@" | awk '{print $1}')
network=$(echo "$@" | awk '{print $2}')
case "$option" in
"-L")
if [[ $(echo "$@" | awk '{print $4}') == "max" ]]; then
max_value=$(ethtool -l "$network" | grep -w "Combined" | awk 'NR==1{print $2}')
echo "$@" | sed "s/max/$max_value/"
else
echo "$@"
fi
;;
*)
echo "$@"
;;
esac
}
...@@ -20,11 +20,12 @@ command -v ethtool >/dev/null 2>&1 ...@@ -20,11 +20,12 @@ command -v ethtool >/dev/null 2>&1
ret=$? ret=$?
[ $ret -ne 0 ] && echo "\033[31m command ethtool is not exist \033[31m" && exit 1 [ $ret -ne 0 ] && echo "\033[31m command ethtool is not exist \033[31m" && exit 1
fixed="fixed"
para=$(cmd_conversion "$@")
value=$(get_ethtool_value "$@") value=$(get_ethtool_value "$@")
if [[ "$value" == $(eval echo "$*") ]]; then if [[ "$value" == "$para" ]] || [[ "$value" == "$fixed" ]] || [[ "$para" == "$fixed" ]]; then
echo "no need to set" echo "no need to set"
exit 0 exit 0
fi fi
ethtool "$@" ethtool $(eval echo "$para")
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-02-24
lsmod | grep hinic &>/dev/null
ret=$?
[ $ret -ne 0 ] && echo "disable" && exit 0
value=$(cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff)
echo "$value"
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-02-24
SCRIPT=$(basename "$0")
if [ $# != 1 ]; then
echo "Usage: ${SCRIPT} number or disable"
exit 1
fi
path="/etc/modprobe.d/hinic.conf"
case "$1" in
"disable")
lsmod | grep hinic &>/dev/null
ret=$?
[ $ret -eq 0 ] && rmmod hinic
exit 0
;;
"2" | "4" | "8" | "16")
[ ! -f "$path" ] && touch "$path"
sed -i '/options hinic rx_buff=/d' "$path"
echo "options hinic rx_buff=$1" >>"$path"
lsmod | grep hinic &>/dev/null
ret=$?
[ $ret -eq 0 ] && rmmod hinic
modprobe hinic
;;
*)
echo "\033[31m this option is not supported \033[31m" && exit 1
;;
esac
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-03-02
declare -A default=(["UserTasksMax"]="4096")
keywords=$(echo "$@" | awk '{print $1}')
value=$(echo "$@" | awk '{print $2}')
result=$(cat /etc/systemd/logind.conf | grep -w "^$keywords" | awk -F "=" '{print$2}')
if [[ "$result" == "" ]]; then
echo "$keywords ${default["$keywords"]}"
else
echo "$keywords $result"
fi
#!/bin/sh
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-03-02
keywords=$(echo "$@" | awk '{print $1}')
value=$(echo "$@" | awk '{print $2}')
file=/etc/systemd/logind.conf
sed -i "/$keywords=/d" "$file"
sed -i "/\[Login\]/a$keywords=$value" "$file"
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册