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