root/tools/perf/util/target.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. target__validate
  2. target__parse_uid
  3. target__strerror

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Helper functions for handling target threads/cpus
   4  *
   5  * Copyright (C) 2012, LG Electronics, Namhyung Kim <namhyung.kim@lge.com>
   6  */
   7 
   8 #include "target.h"
   9 
  10 #include <pwd.h>
  11 #include <stdio.h>
  12 #include <stdlib.h>
  13 #include <string.h>
  14 #include <linux/kernel.h>
  15 #include <linux/string.h>
  16 
  17 enum target_errno target__validate(struct target *target)
  18 {
  19         enum target_errno ret = TARGET_ERRNO__SUCCESS;
  20 
  21         if (target->pid)
  22                 target->tid = target->pid;
  23 
  24         /* CPU and PID are mutually exclusive */
  25         if (target->tid && target->cpu_list) {
  26                 target->cpu_list = NULL;
  27                 if (ret == TARGET_ERRNO__SUCCESS)
  28                         ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
  29         }
  30 
  31         /* UID and PID are mutually exclusive */
  32         if (target->tid && target->uid_str) {
  33                 target->uid_str = NULL;
  34                 if (ret == TARGET_ERRNO__SUCCESS)
  35                         ret = TARGET_ERRNO__PID_OVERRIDE_UID;
  36         }
  37 
  38         /* UID and CPU are mutually exclusive */
  39         if (target->uid_str && target->cpu_list) {
  40                 target->cpu_list = NULL;
  41                 if (ret == TARGET_ERRNO__SUCCESS)
  42                         ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
  43         }
  44 
  45         /* PID and SYSTEM are mutually exclusive */
  46         if (target->tid && target->system_wide) {
  47                 target->system_wide = false;
  48                 if (ret == TARGET_ERRNO__SUCCESS)
  49                         ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
  50         }
  51 
  52         /* UID and SYSTEM are mutually exclusive */
  53         if (target->uid_str && target->system_wide) {
  54                 target->system_wide = false;
  55                 if (ret == TARGET_ERRNO__SUCCESS)
  56                         ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
  57         }
  58 
  59         /* THREAD and SYSTEM/CPU are mutually exclusive */
  60         if (target->per_thread && (target->system_wide || target->cpu_list)) {
  61                 target->per_thread = false;
  62                 if (ret == TARGET_ERRNO__SUCCESS)
  63                         ret = TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD;
  64         }
  65 
  66         return ret;
  67 }
  68 
  69 enum target_errno target__parse_uid(struct target *target)
  70 {
  71         struct passwd pwd, *result;
  72         char buf[1024];
  73         const char *str = target->uid_str;
  74 
  75         target->uid = UINT_MAX;
  76         if (str == NULL)
  77                 return TARGET_ERRNO__SUCCESS;
  78 
  79         /* Try user name first */
  80         getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
  81 
  82         if (result == NULL) {
  83                 /*
  84                  * The user name not found. Maybe it's a UID number.
  85                  */
  86                 char *endptr;
  87                 int uid = strtol(str, &endptr, 10);
  88 
  89                 if (*endptr != '\0')
  90                         return TARGET_ERRNO__INVALID_UID;
  91 
  92                 getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
  93 
  94                 if (result == NULL)
  95                         return TARGET_ERRNO__USER_NOT_FOUND;
  96         }
  97 
  98         target->uid = result->pw_uid;
  99         return TARGET_ERRNO__SUCCESS;
 100 }
 101 
 102 /*
 103  * This must have a same ordering as the enum target_errno.
 104  */
 105 static const char *target__error_str[] = {
 106         "PID/TID switch overriding CPU",
 107         "PID/TID switch overriding UID",
 108         "UID switch overriding CPU",
 109         "PID/TID switch overriding SYSTEM",
 110         "UID switch overriding SYSTEM",
 111         "SYSTEM/CPU switch overriding PER-THREAD",
 112         "Invalid User: %s",
 113         "Problems obtaining information for user %s",
 114 };
 115 
 116 int target__strerror(struct target *target, int errnum,
 117                           char *buf, size_t buflen)
 118 {
 119         int idx;
 120         const char *msg;
 121 
 122         BUG_ON(buflen == 0);
 123 
 124         if (errnum >= 0) {
 125                 str_error_r(errnum, buf, buflen);
 126                 return 0;
 127         }
 128 
 129         if (errnum <  __TARGET_ERRNO__START || errnum >= __TARGET_ERRNO__END)
 130                 return -1;
 131 
 132         idx = errnum - __TARGET_ERRNO__START;
 133         msg = target__error_str[idx];
 134 
 135         switch (errnum) {
 136         case TARGET_ERRNO__PID_OVERRIDE_CPU ...
 137              TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD:
 138                 snprintf(buf, buflen, "%s", msg);
 139                 break;
 140 
 141         case TARGET_ERRNO__INVALID_UID:
 142         case TARGET_ERRNO__USER_NOT_FOUND:
 143                 snprintf(buf, buflen, msg, target->uid_str);
 144                 break;
 145 
 146         default:
 147                 /* cannot reach here */
 148                 break;
 149         }
 150 
 151         return 0;
 152 }

/* [<][>][^][v][top][bottom][index][help] */