Configuring User Permissions

After tools in Installing perf, iotop, and ltrace are installed, configure dependent user permissions. Perform the following steps to configure the permissions:

  1. Log in to the environment as the root user.
  2. Run the following command to create the msprof_data_collection.sh file in the /usr/bin/ directory:
    cd /usr/bin
    touch msprof_data_collection.sh
  3. Add the script content to the msprof_data_collection.sh file.
    1. Open the msprof_data_collection.sh file.
      chmod u+wx msprof_data_collection.sh
      vi msprof_data_collection.sh
    2. Copy the following code to the msprof_data_collection.sh file:

      Ensure that the environment supports the pstree command.

        1
        2
        3
        4
        5
        6
        7
        8
        9
       10
       11
       12
       13
       14
       15
       16
       17
       18
       19
       20
       21
       22
       23
       24
       25
       26
       27
       28
       29
       30
       31
       32
       33
       34
       35
       36
       37
       38
       39
       40
       41
       42
       43
       44
       45
       46
       47
       48
       49
       50
       51
       52
       53
       54
       55
       56
       57
       58
       59
       60
       61
       62
       63
       64
       65
       66
       67
       68
       69
       70
       71
       72
       73
       74
       75
       76
       77
       78
       79
       80
       81
       82
       83
       84
       85
       86
       87
       88
       89
       90
       91
       92
       93
       94
       95
       96
       97
       98
       99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      #!/bin/bash
      # This script is used to run perf/iotop/ltrace by profiling.
      
      command_type=$1
      command_param=$2
      script_dir="/usr/bin"
      script_name="$(basename "$0")"
      reg_int='^[1-9][0-9]{,6}$|^0$'
      
      function get_version(){
          if [ "${command_param}" = "perf" ] || [ "${command_param}" = "ltrace" ] || [ "${command_param}" = "iotop" ]; then
              "${command_param}" --version
          else
              printf "The value of the second parameter is incorrect, please enter the correct parameter, "
              printf "such as: perf, ltrace, iotop\n"
              exit 1
          fi
      }
      
      function kill_prof_cmd(){
          if [[ ${command_param} =~ ${reg_int} ]]; then
              ppid=`ps -o ppid= -p ${command_param}`
              ppid_user=$(ps -o uid -e -o pid | awk -va="${ppid}" '$2==a {print $1}')
              shell_user=`id -u ${SUDO_USER}`
              if [ "${ppid_user}" != "${shell_user}" ]; then
                  echo "UID of ${ppid} is:${ppid_user}, UID running this script is:${shell_user}"
                  exit 1
              fi
              pidLine=`pstree -p ${command_param}`
              pidLine=`echo $pidLine | awk 'BEGIN{ FS="(" ; RS=")" } NF>1 { print $NF }'`
              for pid in $pidLine
                  do 
                      kill -2 ${pid}
                  done     
              exit 1
          else
              echo "Input pid:${command_param} error"
              exit 1
          fi
      }
      
      # The user who runs the script must be the same as the user to which the pid process belongs.
      function check_pid(){
          if [[ ! ${command_param} =~ ${reg_int} ]]; then
              echo "Input pid:${command_param} error"
              exit 1
          fi
          params=$(cat /proc/sys/kernel/pid_max)
          if [[ ! "$params" =~ ${reg_int} ]]; then
              echo "Get max_pid error"
              exit 1
          fi
          if [ "${command_param}" -gt "${params}" ]; then
              echo "Input pid:${command_param} gt pid_max:${params}"
              exit 1
          fi
          pid_user=$(ps -o uid -e -o pid | awk -va="${command_param}" '$2==a {print $1}')
          shell_user=`id -u ${SUDO_USER}`
          if [ "${pid_user}" != "${shell_user}" ]; then
              echo "UID of ${command_param} is:${pid_user}, UID running this script is:${shell_user}"
              exit 1
          fi
      }
      
      function run_prof_trace_cmd(){
          check_pid
          perf trace -T --syscalls -p "${command_param}"
      }
      
      function run_ltrace_cmd(){
          check_pid
          ltrace -ttt -T -e pthread_attr_init -e pthread_create -e pthread_join -e pthread_mutex_init -p "${command_param}"
      }
      
      function run_iotop_cmd(){
          check_pid
          iotop -b -d 0.02 -P -t -p "${command_param}"
      }
      
      function check_username(){
          echo "${command_param}" | grep -q -E '^[ 0-9a-zA-Z./:]*$'
          result=$?
          if [ "$result" -ne 0 ]; then
              echo "Parameter:${command_param} is invalied!"
              exit 1
          fi
          if ! id -u "${command_param}" >/dev/null 2>&1 ; then
              echo "User:${command_param} does not exist"
              exit 1
          fi
      }
      
      function get_cmd(){
          params=$(cat /proc/sys/kernel/pid_max)
          if [[ ! "$params" =~ ${reg_int} ]]; then
              echo "Get max_pid error"
              exit 1
          fi
          digits=1
          while ((${params}>10)); do
              let "digits++"
              ((params /= 10))
          done
          compile='[1-9]'
          arr[0]='[0-9]'
          for((i=1;i<digits;i++)); do
              compile="${compile}[0-9]"
              arr[i]=${compile}
          done
          cmd="${script_dir}/${script_name} get-version perf,${script_dir}/${script_name} get-version ltrace,${script_dir}/${script_name} get-version iotop"
          cmd="${cmd},${script_dir}/${script_name} kill pid"
          for i in "${arr[@]}"; do
              cmd="${cmd},${script_dir}/${script_name} perf $i,${script_dir}/${script_name} ltrace $i,${script_dir}/${script_name} iotop $i"
          done
          cmd="$command_param ALL=(ALL:ALL) NOPASSWD:${cmd}"
          cmd=$(echo -e "${cmd}\nDefaults env_reset")
          echo "${cmd}"
      }
      
      function set_sudoers(){
          if [ -d "/etc/sudoers.d" ]; then
              if [ -f "/etc/sudoers.d/${command_param}_profiling" ]; then
                  echo "The file /etc/sudoers.d/${command_param}_profiling already exist"
              fi
              echo "${cmd}" > /etc/sudoers.d/"${command_param}"_profiling
              result=$?
              if [ "$result" -ne 0 ]; then
                  echo "Set cmd to /etc/sudoers.d/${command_param}_profiling failed!"
                  exit 1
              else
                  echo "The user permission have been configured successfully. You can find the configuration file /etc/sudoers.d/${command_param}_profiling"
                  exit
              fi
          fi
          has_add=$(cat /etc/sudoers|grep "${script_name}"|grep "${command_param}")
          if [ "${has_add}" ]; then
              echo "The configure already exist, please confirm its content is correct"
              exit
          fi
          chmod u+w /etc/sudoers
          result=$?
          if [ "$result" -ne 0 ]; then
              echo "Permission configure failed"
              exit 1
          fi
          echo "${cmd}" >> /etc/sudoers
          chmod u-w /etc/sudoers
          echo "The user permission have been configured successfully. You can find the configuration file in the /etc/sudoers."
      }
      
      function handle_sudoers(){
          check_username
          get_cmd
          set_sudoers
      }
      
      function main(){
          if [ $# -ne 2 ]; then
              echo "The number of parameters is incorrect, please enter two parameters"
              exit 1
          fi
          if [ "${command_type}" = "set-sudoers" ]; then
              echo "Run set-sudoers cmd"
              handle_sudoers
          elif [ "${command_type}" = "get-version" ]; then
              #echo "Run get-version cmd"
              get_version
          elif [ "${command_type}" = "kill" ]; then
              #echo "kill cmd"
              kill_prof_cmd
          elif [ "${command_type}" = "perf" ]; then
              #echo "run perf trace cmd"
              run_prof_trace_cmd
          elif [ "${command_type}" = "ltrace" ] ; then
              #echo "run ltrace cmd"
              run_ltrace_cmd
          elif [ "${command_type}" = "iotop" ]; then
              #echo "run iotop cmd"
              run_iotop_cmd
          else
              printf "The value of the first parameter is incorrect, please enter the correct parameter, "
              printf "such as: set-sudoers, get-version, kill, perf, ltrace, iotop\n"
              exit 1
          fi
      }
      
      main "$@"
      
    3. Save the modification and exit. Then, run the following command to remove the write permission on the msprof_data_collection.sh file:
      chmod u-w msprof_data_collection.sh
    4. Ensure that other users do not have the write permission on the msprof_data_collection.sh file.
      chmod o-w msprof_data_collection.sh
  4. Run the following command to grant permissions to the installation user for running the perf, iotop, and ltrace tools (HwHiAiUser is used as an example):
    /usr/bin/msprof_data_collection.sh set-sudoers HwHiAiUser

    If the command output shown in Figure 1 is displayed, the execution is successful.

    msprof_data_collection.sh allows users to obtain the sudo permission, which may cause privilege escalation risks. Exercise caution when running this command. After the configuration and collection are complete, perform step 5 to clear the sudo permission.

    Figure 1 Execution success
  5. For security purposes, clear the configuration after configuring the preceding permissions and collecting profile data.
    1. Check whether the /etc/sudoers.d/{installation_user_name}_profiling file exists. If the file exists, delete it.
    2. Check whether the /etc/sudoers file exists. If the file exists, perform the following operations:
      Open the /etc/sudoers file.
      chmod u+w /etc/sudoers
      vi /etc/sudoers
      Delete the following content:
      huawei ALL=(ALL:ALL) NOPASSWD:/usr/bin/msprof_data_collection.sh get-version perf,/usr/bin/msprof_data_collection.sh get-version ltrace,/usr/bin/msprof_data_collection.sh get-version iotop,/usr/bin/msprof_data_collection.sh pkill perf,/usr/bin/msprof_data_collection.sh pkill ltrace,/usr/bin/msprof_data_collection.sh pkill iotop,/usr/bin/msprof_data_collection.sh perf [0-9],/usr/bin/msprof_data_collection.sh ltrace [0-9],/usr/bin/msprof_data_collection.sh iotop [0-9],/usr/bin/msprof_data_collection.sh perf [1-9][0-9],/usr/bin/msprof_data_collection.sh ltrace [1-9][0-9],/usr/bin/msprof_data_collection.sh iotop [1-9][0-9],/usr/bin/msprof_data_collection.sh perf [1-9][0-9][0-9],/usr/bin/msprof_data_collection.sh ltrace [1-9][0-9][0-9],/usr/bin/msprof_data_collection.sh iotop [1-9][0-9][0-9],/usr/bin/msprof_data_collection.sh perf [1-9][0-9][0-9][0-9],/usr/bin/msprof_data_collection.sh ltrace [1-9][0-9][0-9][0-9],/usr/bin/msprof_data_collection.sh iotop [1-9][0-9][0-9][0-9],/usr/bin/msprof_data_collection.sh perf [1-9][0-9][0-9][0-9][0-9],/usr/bin/msprof_data_collection.sh ltrace [1-9][0-9][0-9][0-9][0-9],/usr/bin/msprof_data_collection.sh iotop [1-9][0-9][0-9][0-9][0-9]
      Defaults env_reset
    3. Remove the write permission on the /etc/sudoers file.
      chmod u-w /etc/sudoers