提交 4bc89027 编写于 作者: X xionglei6

Add: 增加绑核操作,解析'd-caps', 'apl'

Signed-off-by: Nxionglei6 <xionglei6@huawei.com>
上级 abb195cc
......@@ -46,6 +46,7 @@ extern "C" {
#define SERVICE_ATTR_DYNAMIC 0x100 // dynamic service
#define SERVICE_ATTR_ONDEMAND 0x200 // ondemand, manage socket by init
#define MAX_APL_NAME 32
#define MAX_SERVICE_NAME 32
#define MAX_WRITEPID_FILES 100
......@@ -57,6 +58,11 @@ extern "C" {
#define SERVICES_ARR_NAME_IN_JSON "services"
typedef struct {
int *cpus;
int cpuNum;
} CpuArgs;
typedef struct {
uid_t uID;
gid_t *gIDArray;
......@@ -83,6 +89,9 @@ typedef struct {
int crashTime;
unsigned int attribute;
int importance;
char apl[MAX_APL_NAME + 1];
ServiceArgs capsArgs;
CpuArgs cpuInfo;
Perms servPerm;
ServiceArgs pathArgs;
ServiceArgs extraArgs;
......
......@@ -33,6 +33,9 @@ extern "C" {
#define CRITICAL_STR_IN_CFG "critical"
#define DISABLED_STR_IN_CFG "disabled"
#define CONSOLE_STR_IN_CFG "console"
#define D_CAPS_STR_IN_CFG "d-caps"
#define APL_STR_IN_CFG "apl"
#define CPU_CORE_STAR_IN_CFG "cpucore"
#define MAX_SERVICES_CNT_IN_FILE 100
......
......@@ -18,6 +18,8 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <stdio.h>
#ifdef __MUSL__
#include <stropts.h>
#endif
......@@ -177,6 +179,41 @@ void SetSecon(Service *service)
#endif // WITH_SELINUX
}
static int SetAffinityBetweenProcAndCore(pid_t pid, int cpuIndex)
{
cpu_set_t setMask;
CPU_ZERO(&setMask);
CPU_SET(cpuIndex, &setMask);
int ret = sched_setaffinity(pid, sizeof(cpu_set_t), &setMask);
if (ret != 0) {
INIT_LOGI("Set affinity between process(pid=%d) with CPU's core %d failed", pid, cpuIndex);
return SERVICE_FAILURE;
} else {
INIT_LOGE("Set affinity between process(pid=%d) with CPU's core %d successfully", pid, cpuIndex);
}
return SERVICE_SUCCESS;
}
static int BindCpuCore(Service *service)
{
if (service == NULL || service->cpuInfo.cpuNum <= 0) {
return SERVICE_SUCCESS;
}
long cpuNum = sysconf(_SC_NPROCESSORS_CONF);
INIT_ERROR_CHECK(service->cpuInfo.cpuNum <= cpuNum, return SERVICE_FAILURE,
"%s cpus cores exceeds total number of device cores", service->name);
int index = 0;
for (int i = 0; i < service->cpuInfo.cpuNum; i++) {
index = (int)service->cpuInfo.cpus[i];
if ((int)cpuNum <= index) {
INIT_LOGW("%s core number %d of CPU cores does not exist", service->name, index);
continue;
}
(void)SetAffinityBetweenProcAndCore(getpid(), index);
}
return SERVICE_SUCCESS;
}
int ServiceStart(Service *service)
{
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
......@@ -205,6 +242,9 @@ int ServiceStart(Service *service)
if (service->attribute & SERVICE_ATTR_CONSOLE) {
OpenConsole();
}
// bind cpu core
INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
"binding core number failed for service %s", service->name);
// permissions
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE),
"service %s exit! set perms failed! err %d.", service->name, errno);
......
......@@ -154,7 +154,13 @@ void ReleaseService(Service *service)
}
FreeServiceArg(&service->pathArgs);
FreeServiceArg(&service->writePidArgs);
FreeServiceArg(&service->capsArgs);
if (service->cpuInfo.cpus != NULL) {
free(service->cpuInfo.cpus);
service->cpuInfo.cpus = NULL;
}
service->cpuInfo.cpuNum = 0;
if (service->servPerm.caps != NULL) {
free(service->servPerm.caps);
service->servPerm.caps = NULL;
......@@ -215,7 +221,12 @@ static int GetServiceArgs(const cJSON *argJson, const char *name, int maxCount,
for (int i = 0; i < count + 1; ++i) {
args->argv[i] = NULL;
}
args->count = count + 1;
// ServiceArgs have a variety of uses, some requiring a NULL ending, some not
if (strcmp(name, D_CAPS_STR_IN_CFG) != 0) {
args->count = count + 1;
} else {
args->count = count;
}
for (int i = 0; i < count; ++i) {
char *curParam = cJSON_GetStringValue(cJSON_GetArrayItem(obj, i));
INIT_ERROR_CHECK(curParam != NULL, return SERVICE_FAILURE, "Invalid arg %d", i);
......@@ -495,6 +506,7 @@ static int CheckServiceKeyName(const cJSON *curService)
char *cfgServiceKeyList[] = {
"name", "path", "uid", "gid", "once", "importance", "caps", "disabled",
"writepid", "critical", "socket", "console", "dynamic", "file", "ondemand",
"d-caps", "apl", "cpucore",
#ifdef WITH_SELINUX
SECON_STR_IN_CFG,
#endif // WITH_SELINUX
......@@ -573,6 +585,49 @@ int GetCritical(const cJSON *curArrItem, Service *curServ, const char *attrName
return SERVICE_SUCCESS;
}
static int Comparefunc(const void *before, const void *after)
{
return (*(int*)before - *(int*)after);
}
static int GetCpuArgs(const cJSON *argJson, const char *name, CpuArgs *args)
{
INIT_ERROR_CHECK(argJson != NULL, return SERVICE_FAILURE, "Invalid argJson");
cJSON *obj = cJSON_GetObjectItem(argJson, name);
INIT_CHECK(obj != NULL, return SERVICE_FAILURE);
int ret = cJSON_IsArray(obj);
INIT_ERROR_CHECK(ret, return SERVICE_FAILURE, "Invalid type");
int count = cJSON_GetArraySize(obj);
int tmpArray[count];
for (int i = 0; i < count; ++i) {
cJSON *item = cJSON_GetArrayItem(obj, i);
INIT_ERROR_CHECK(item != NULL, return SERVICE_FAILURE, "prase invalid");
tmpArray[i] = (int)cJSON_GetNumberValue(item);
}
qsort(tmpArray, count, sizeof(int), Comparefunc);
int cpuCount = 0;
for (int j = 0; j < count; j++) {
if (j == 0 && tmpArray[0] == 0) {
tmpArray[cpuCount++] = 0;
continue;
}
if (tmpArray[j] != tmpArray[j-1]) {
tmpArray[cpuCount++] = tmpArray[j];
}
}
args->cpus=(int*)malloc(cpuCount * sizeof(int));
INIT_ERROR_CHECK(args->cpus != NULL, return SERVICE_FAILURE, "Failed to malloc for argv");
for (int i = 0; i < cpuCount; ++i) {
args->cpus[i] = -1;
}
args->cpuNum = cpuCount;
for (int i = 0; i < count; ++i) {
args->cpus[i] = tmpArray[i];
}
return SERVICE_SUCCESS;
}
int ParseOneService(const cJSON *curItem, Service *service)
{
INIT_CHECK_RETURN_VALUE(curItem != NULL && service != NULL, SERVICE_FAILURE);
......@@ -604,8 +659,10 @@ int ParseOneService(const cJSON *curItem, Service *service)
ret = GetServiceAttr(curItem, service, CONSOLE_STR_IN_CFG, SERVICE_ATTR_CONSOLE, NULL);
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get console for service %s", service->name);
ret = GetServiceArgs(curItem, "writepid", MAX_WRITEPID_FILES, &service->writePidArgs);
INIT_CHECK_ONLY_ELOG(ret == 0, "No writepid arg for service %s", service->name);
(void)GetServiceArgs(curItem, "writepid", MAX_WRITEPID_FILES, &service->writePidArgs);
(void)GetServiceArgs(curItem, D_CAPS_STR_IN_CFG, MAX_WRITEPID_FILES, &service->capsArgs);
(void)GetStringItem(curItem, APL_STR_IN_CFG, service->apl, MAX_APL_NAME);
(void)GetCpuArgs(curItem, CPU_CORE_STAR_IN_CFG, &service->cpuInfo);
ret = GetServiceCaps(curItem, service);
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get caps for service %s", service->name);
ret = GetDynamicService(curItem, service);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册