使用C从Linux中的现有文件获取硬件信息

时间:2017-06-06 06:34:27

标签: c linux memory cpu disk

我使用execv运行lshw命令来获取C代码中的CPU,磁盘和内存。但我想搜索另一个解决方案,以便从/proc或任何其他现有数据中获取这些信息。有什么建议吗?这是我的代码:

char *params[9]  = {"/usr/bin/lshw", "-short", "-c", "disk", 
                  "-c", "memory", "-c", "processor", 0}; //cmd params filled
execv(params[0], params);

Linux命令:$ sudo lshw -short -c disk -c processor -c memory

$ sudo lshw -short -c disk -c processor -c memory
H/W path         Device     Class          Description
======================================================
/0/0                        memory         64KiB BIOS
/0/22                       memory         16GiB System Memory
/0/22/0                     memory         DIMM Synchronous [empty]
/0/22/1                     memory         DIMM Synchronous [empty]
/0/22/2                     memory         8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/22/3                     memory         8GiB DIMM Synchronous 2133 MHz (0.5 ns)
/0/2a                       memory         256KiB L1 cache
/0/2b                       memory         1MiB L2 cache
/0/2c                       memory         6MiB L3 cache
/0/2d                       processor      Intel(R) Xeon(R) CPU D-1521 @ 2.40GHz
/0/1/0.0.0       /dev/sda   disk           16GB SATADOM-SH 3IE3
/0/2/0.0.0       /dev/sdb   disk           120GB Patriot Blaze

我有两个问题:

  • 在哪里找到解析/proc中文件的指南 这些硬件信息?
  • 我是否需要跟踪lshw的源代码以查找lshw的内容?

编辑:

Advanced Linux Programming的第7章是解析/proc文件系统的指南。

3 个答案:

答案 0 :(得分:4)

获取硬件信息的最佳方法是在Linux上使用sysconf()和sysctl *()函数(Mac OS X,freebsd,openbsd)以及sysconf()和sysinfo()。

Parsing / proc / *比调用sysinfo()或sysconf()更慢,更复杂。

下面是一个小例子,为您提供有关Mac OS X上处理器和内存的一些信息:

qsub

你必须阅读man 3 sysctl,或者阅读Linux man 2 sysconf和man 2 sysinfo。

一个有趣的链接:http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system#Other

您可以计算检索一些sysctl变量的CPU负载和使用情况,并自己进行数学计算(您可以在google上找到公式)。

  

但是在哪里可以找到来自$ sudo lshw -short -c memory的报告中的物理DIMM信息?

您可以在C程序中执行命令,将其保存为字符串,如:

#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main()
{
 char *p = NULL;
 size_t len;
 sysctlbyname("hw.model", NULL, &len, NULL, 0);
 p = malloc(len);
 sysctlbyname("hw.model", p, &len, NULL, 0);
 printf("%s\n", p);
 /* CTL_MACHDEP variables are architecture dependent so doesn't work 
 for every one */
 sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
 p = malloc(len);
 sysctlbyname("machdep.cpu.brand_string", p, &len, NULL, 0);
 printf("%s\n", p);
 int64_t mem;
 len = sizeof(mem);
 sysctlbyname("hw.memsize", &mem, &len, NULL, 0);
 printf("System Memory : %lld\n", mem);
 return (0);
}

(我不会检查此代码中的所有函数返回,不要太长,但是你应该在程序中执行此操作。)

这是一个解析文件/ proc / meminfo的示例,以保存在我想要的双数组2个字符串中,然后将它们打印出来:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>

char *strjoin(char *s1, char *s2, int n)
{
    int i = strlen(s2);
    int j = 0;
    if ((s2 = realloc(s2, (i + n + 1))) == NULL)
            perror(0);
    while (j < n && s1[j])
    {
            s2[i] = s1[j];
            i++;
            j++;
    }
    s2[i] = 0;
    return (s2);
}

int main()
{
    pid_t father;
    char buf[500] = {0};
    char *str;
    char *argv[5] = {"/usr/bin/lshw", "-short", "-c", "memory"};
    int fd[2];
    int ret;

    if (pipe(fd) == -1)
    {
            perror(NULL);
            return -1;
    }
    father = fork();
    if (father == 0)
    {
            close(fd[1]);
            while ((ret = read(fd[0], buf, 500)))
            {
                    str = strjoin(buf, str, ret);
            }
            close(fd[0]);
    }
    else
    {
            close(fd[0]);
            execv(argv[0], argv);
            close(fd[1]);
            wait(0);
    }
    wait(0);
    printf("%s", str);
    return 0;
}

如果要保存更多字符串,请在双数组信息中使用malloc更多空间,如果在读取循环内部,则使用else添加它们。您可以使用/ proc /中的任何文件来获取所需的信息。

答案 1 :(得分:1)

通过阅读lshw的源代码,我发现lshw/sys/class/dmi/读取原始数据。由于lshw是用我不熟悉的CPP编写的,因此Where does dmidecode get the SMBIOS table?提到了dmidecode.c/sys/class/dmi读取与lshw相同的原始数据的问题{1}}确实。

以下是dmidecode.c

中的定义
#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"

我从dmidecode.c中提取代码以获取CPU和内存信息,并使用lsscsi获取磁盘信息。

感谢您的帮助。

答案 2 :(得分:-2)

1:要获得CPU负载,请使用以下命令:

top -bn1 | grep load

这将为您提供如下输出:

top - 12:26:20 up 35 min,  2 users,  load average: 0.02, 0.01, 0.00

现在从上面的字符串解析平均负载。 2:要获取内存信息,请使用以下命令:

free -m

这会给你:

total       used       free     shared    buffers     cached
Mem:         15926        308      15617          6         15        122
-/+ buffers/cache:        171      15755
Swap:            0          0          0

要获取磁盘信息,请使用:

df -H /home/test

这会给你:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       102G  5.4G   91G   6% /

现在从上面的结果中解析出你想要的内容。