简体   繁体   English

在被调用的core_pattern过程中调用sched_setaffinity失败

[英]sched_setaffinity fails when called in core_pattern called procedure

I have /proc/sys/kernel/core_pattern set to pipe core dumps to my program. 我将/ proc / sys / kernel / core_pattern设置为将核心转储管道传输到我的程序。 This program calls a shell script (using "system") which in turn calls my test program, attached. 该程序调用一个shell脚本(使用“系统”),然后依次调用我的测试程序。 This test program attempts to call sched_setaffinity which fails, EINVAL, for any CPU. 此测试程序尝试为任何CPU调用sched_setaffinity,该失败,EINVAL。 The same test program called directly from a shell script (running as root) works OK. 直接从shell脚本(以root用户身份运行)调用的同一测试程序可以正常运行。

#include <stdio.h>      
#include <stdlib.h>     
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <sys/time.h>
#include <sys/resource.h>
#include <syslog.h>


typedef unsigned long long int UINT64;

// Functions to convert Linux CPU list to/from UINT64
static UINT64 GetCpuMask(cpu_set_t* cpuSet)
{
    UINT64 mask = 0;
    const int maxCpus = CPU_SETSIZE < 64?CPU_SETSIZE:64;
    for (int cpu = 0; cpu < maxCpus; cpu++){
        mask |= CPU_ISSET(cpu, cpuSet)? 1ll<<cpu : 0;
    }
    return mask;
}
static void GetCpuSet(UINT64 mask, cpu_set_t* cpuSet)
{
    const int maxCpus = CPU_SETSIZE < 64?CPU_SETSIZE:64;
    CPU_ZERO(cpuSet);
    for (int cpu = 0; cpu < maxCpus; cpu++){
        if (1ll<<cpu & mask){
            CPU_SET(cpu, cpuSet);
        }
    }
}
UINT64 GetThreadAffinityMask()
{
    cpu_set_t cpuSet;

    if (!sched_getaffinity(0, sizeof(cpu_set_t), &cpuSet)){
        return GetCpuMask(&cpuSet);
    }
    syslog (LOG_ERR, "sched_getaffinity fails, errno %d:%s", errno, strerror(errno));
    return 0;
}

int main( int argc, char *argv[] )
{
// Temp test...
    setlogmask (LOG_UPTO (LOG_INFO)); // unless overridden in config file
    openlog ("proc3", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER );

    UINT64 old_mask=GetThreadAffinityMask();
    syslog (LOG_INFO, "old_mask 0x%x", old_mask);

    cpu_set_t testCpuSet;
    for (int cpu = 0; cpu < 16; cpu++){
        CPU_ZERO(&testCpuSet);
        CPU_SET(cpu, &testCpuSet);
        UINT64 try_mask = GetCpuMask(&testCpuSet);
        if (!sched_setaffinity(0, sizeof(cpu_set_t), &testCpuSet)){
            syslog (LOG_INFO, "sched_setaffinity OK, cpu %d (mask 0x%x)",cpu, try_mask);
            UINT64 new_mask = GetThreadAffinityMask();
            syslog (LOG_INFO, "new_mask 0x%x", new_mask);
        } else {
            syslog (LOG_INFO, "sched_setaffinity, cpu %d errno %d:%s", cpu, errno, strerror(errno));
        }
    }
}

The logged output when called directly from a root shell: 直接从根shell调用时记录的输出:

Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: old_mask 0xf
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity OK, cpu 0 (mask 0x1)
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: new_mask 0x1
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity OK, cpu 1 (mask 0x2)
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: new_mask 0x2
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity OK, cpu 2 (mask 0x4)
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: new_mask 0x4
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity OK, cpu 3 (mask 0x8)
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: new_mask 0x8
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 4 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 5 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 6 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 7 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 8 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 9 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 10 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 11 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 12 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 13 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 14 errno 22:Invalid argument
Sep 19 11:42:43 apxdev-cjn-1 proc3[9122]: sched_setaffinity, cpu 15 errno 22:Invalid argument

The logged output when called from the dump hook: 从转储钩子调用时记录的输出:

Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: old_mask 0xf
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 0 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 1 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 2 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 3 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 4 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 5 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 6 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 7 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 8 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 9 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 10 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 11 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 12 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 13 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 14 errno 22:Invalid argument
Sep 19 11:50:25 apxdev-cjn-1 proc3[12372]: sched_setaffinity, cpu 15 errno 22:Invalid argument

With the addition of the kernel version, an answer: 除了内核版本,答案是:

It appears that EINVAL in the sched_setaffinity call is due to the PF_NO_SETAFFINITY flag being set in the task flags. 看来sched_setaffinity调用中的EINVAL是由于在任务标志中设置了PF_NO_SETAFFINITY标志。 This flag is enabled in most kernel threads to ensure that user-level programs don't manipulate the affinity of the kernel thread in inappropriate ways. 在大多数内核线程中都启用了此标志,以确保用户级程序不会以不适当的方式操纵内核线程的亲和力。

In later versions of the kernel, code was added to the flush_old_exec function in fs/exec.c causing the flag to be cleared when a user-level helper program is exec'd (such as that invoked by the piped core_pattern function here). 在更高版本的内核中,将代码添加到fs/exec.cflush_old_exec函数中,从而在执行用户级帮助程序(例如此处通过管道的core_pattern函数调用的帮助程序)时清除该标志。

The source for the kernel version specified by OP is available at https://buildlogs.centos.org/c7.1511.u/kernel/20160217024115/3.10.0-327.10.1.el7.x86_64/ . 由OP指定的内核版本的源位于https://buildlogs.centos.org/c7.1511.u/kernel/20160217024115/3.10.0-327.10.1.el7.x86_64/ The code that clears PF_SET_NOAFFINITY when exec'ing a user-mode program is not present in this version. 此版本中没有执行用户模式程序时清除PF_SET_NOAFFINITY的代码。

This flag will be inherited by child processes (AFAICT: the entire task structure is copied and I cannot see anything that would clear it). 该标志将被子进程继承(AFAICT:整个任务结构已复制,我看不到任何可以清除它的东西)。

According to https://www.kernel.org/doc/Documentation/filesystems/proc.txt , the flags value should be visible in /proc/<pid>/stat ( PF_SET_NOAFFINITY in this version is #defined to 0x04000000). 根据https://www.kernel.org/doc/Documentation/filesystems/proc.txt ,该flags值应在可见/proc/<pid>/statPF_SET_NOAFFINITY在这个版本中已经#defined到0x04000000)。 You should be able to decode the values there and determine for sure whether the flag is set. 您应该能够在那里解码值并确定是否设置了标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM