我当前正在开发一个需要大量系统和过程信息的应用程序,其中某些信息只能通过/ proc获得,并且我对访问结构有一些一般性问题。
该应用程序将在Linux(内核> = 2.6)上运行,而不是在任何其他Unix风格的OS上运行。它应该可以访问/ proc中的任何数据,由于规范尚不清楚,所以我现在不能说什么了,但是整个/ proc目录与应用程序有关。
连接基于内核的解析过程根本不是问题,只是我找不到关于版本之间变化的任何好的文档,这些文档可以帮助我预先捕获解析错误。
另外:是否存在可以通过内核选项激活/停用的功能的明确列表(当然/ proc-feature本身除外)?我正在寻找仅在内核中设置了适当选项的情况下存在的文件/目录的列表。
作为我正在考虑的示例,这是proc手册页(http://linux.die.net/man/5/proc)的链接,其中包含很多有用的信息,例如,某些选项包括最早的它们提供了内核版本,其中包括是否需要加载模块。但是,这并没有描述所有信息的输出格式,如果我想解析它,这是我所需要的(例如,如果它在所有内核版本中都是一致的,或者在某个时候已更改)。
我想知道的第二件事是,如果被查询的进程在被查询时死亡,将会发生什么。我的时间间隔是几点?例如,如果我要获取一列读取所有结构的进程列表,然后逐一解析它们,那么如果我的进程x在读取之前死了,会发生什么?即使我检查目录是否存在,也可以在以后的一个应用程序调用中消失。
最后但并非最不重要的一点:是否有没有安装proc的主要发行版?
据我了解,很多通用工具都基于/ proc接口,例如lsmodor free,所以我猜想我可以期望/ proc几乎总是存在。
我想知道是否有办法从bash进程设置环境变量并从另一个进程读取它.
由于环境变量的值是进程的本地值(除继承之外),因此不能只export FOO="bar"在终端中执行并从另一个终端读取它.然后我试图让他们通过/proc/environ,但这是我得到的:
etuardu@subranu:~$ FOO="foo" bash
etuardu@subranu:~$ strings /proc/$$/environ | grep FOO
FOO=foo
etuardu@subranu:~$ export FOO="bar"
etuardu@subranu:~$ strings /proc/$$/environ | grep FOO
FOO=foo
etuardu@subranu:~$ echo $FOO
bar
Run Code Online (Sandbox Code Playgroud)
看来我可以在进程启动时获得该环境变量的值.
它的当前价值如何?
/ proc/net/tcp给我一个套接字的本地地址,端口和inode号(例如0.0.0.0:5432和9289).
鉴于上述信息,我想找到特定过程的PID.
可以打开/ proc中的每个编号文件夹,然后使用shell命令检查符号链接以查找套接字/ inode编号,例如"$ sudo ls -l/proc/*/fd/2>/dev/null | grep socket".但是,这似乎比必要的计算成本更高,因为任何给定系统上<5%的进程都有开放的TCP套接字.
查找已打开给定套接字的PID的最有效方法是什么?我更喜欢使用标准库,而我目前正在使用Python 3.2.3进行开发.
编辑:从问题中删除了代码示例,因为它们现在包含在下面的答案中.
我目前正在尝试创建一个内核模块,它将根据内核事件生成数据并将它们推送到文件中.在读到这很糟糕(并且我同意)之后,我认为将数据放在/ proc文件中会更有意义,用户程序可以在必要时从中获取数据.但是,这个想法导致了各种各样的问题,特别是何时以及如何清除这个文件.所以我想......"为什么我不在/ proc中创建命名管道并从中读取?"
我已经掌握了为proc文件设置读取函数和写入函数的一般要点,但是我仍然遇到了如何解决这个问题的概念性问题.也就是说,我如何编写这样一个函数来获取任意数据并将其从内核写入这样的管道?有没有人知道如何将数据从内核空间推送到命名管道?最后,它不具备成为一个/ proc文件(特别是如果这是我的错,这样做),但是这是我得出的结论.然后我将不得不弄清楚如何从用户空间程序附加到它,但我觉得这是一个单独的问题.
我正在尝试使用cmdline中的数据提取调用应用程序的参数.
如果我启动这样的应用程序实例:
myapp 1 2
然后cat我myapp的cmdline我会看到类似myapp12的东西.
我需要提取这些值,并使用这段代码来完成它
pid_t proc_id = getpid();
sprintf(buf,"/proc/%i/cmdline",proc_id);
FILE * pFile;
pFile = fopen (buf,"r");
if (pFile!=NULL)
{
fread(buf,100,100,pFile);
cout << "PID " << proc_id << endl;
string str = buf;
cout << buf << endl;
size_t found=str.find_last_of("/\\");
cout << " file: " << str.substr(found+1) << endl;
fclose (pFile);
}
Run Code Online (Sandbox Code Playgroud)
但我得到的只是应用程序名称,没有参数......
来自答案的更新:
好吧,我现在的问题似乎是如何在没有停在第一个NULL字符的情况下读取cmdline文件...
fopen(cmdline, "rb")
Run Code Online (Sandbox Code Playgroud)
没有做任何其他事情......
在 Linux 中,我可以通过检查 /proc/pid/status 文件并查找一行:Threads: 1(或任何数字)来完成此操作。我怎样才能在 FreeBSD 中达到同样的效果?我对任何交互工具都不感兴趣。有没有C函数或者系统文件?我尝试过 BSD 的 procfs 和 linprocfs,但找不到任何类似的功能。
在玩弄user_namespaces(7)的示例时,我遇到了一种奇怪的行为。
应用程序user-ns-ex使用 CLONE_NEWUSER 调用clone(2),从而在新的用户命名空间中创建一个新进程。父进程将映射 ( 0 1000 1) 写入 /proc//uid_map 文件并告诉(通过管道)子进程可以继续。然后子进程执行bash。
我在这里复制了源代码。
如果我不设置任何功能或设置所有功能,应用程序将打开 /proc//uid_map 进行写入。
当我仅设置 set_capuid、set_capgid 和可选的 cap_sys_admin 时,对 open(2) 的调用失败:
设置上限:
arksnote linux-namespaces # setcap 'cap_setuid,cap_setgid,cap_sys_admin=epi' ./user-ns-ex
arksnote linux-namespaces # getcap ./user-ns-ex
./user-ns-ex = cap_setgid,cap_setuid,cap_sys_admin+eip
Run Code Online (Sandbox Code Playgroud)
尝试运行:
kamyshev@arksnote ~/workspace/personal/linux-kernel/linux-namespaces $ ./user-ns-ex -v -U -M '0 1000 1' bash
./user-ns-ex: PID of child created by clone() is 19666
ERROR: open /proc/19666/uid_map: Permission denied
About to exec bash
Run Code Online (Sandbox Code Playgroud)
无能力:
arksnote …Run Code Online (Sandbox Code Playgroud) 我做节目,如果页面错误发生在一些流程,可以看到,我的方法做,这是获得所有进程的PID和看到rss,maj_flt寻求在每一个等/proc/[PID],检查是否有在总的变化maj_flt。
但为了得到所有正在运行的进程的PID的,我需要直接从我的C程序得到这些,而无需使用像现有的shell命令ps,top等等。
有谁知道正在运行的 PID 数据存在于/proc何处或其他地方?或者如果有另一种方法可以做到这一点,比如通过我的 C 程序中的系统调用函数来获取它?
基本上我想要所有已经休眠超过一小时的进程。
我知道 ps 中有 etime,但遗憾的是它显示了整体生命周期。
在linux下如何做到这一点(最好用ps)?
我现在正在研究proc文件系统.我现在知道,在读取校样文件时会调用read_proc_t函数,因此在写入校样文件时会调用write_proc_t函数.但我也在proc_dir_entry的定义中找到了file_operaitons*字段,以及这个示例代码(http://linux.die.net/lkmpg/x810.html).
所以我很困惑,如果我在file_operations结构中同时提供read_proc_t函数和read函数的实现会发生什么?哪个优先于另一个?一个人可以被另一个人覆盖吗?非常感谢.
我正在编写可加载内核模块(LKM).如果刚执行cat/proc /的用户是当前用户,那么这个LKM需要做一些特殊的事情.所以我想弄清楚如何找到这个信息.我的第一次尝试是使用cred.h中定义的get_current_user().但这没有成功.http://lxr.linux.no/linux+*/include/linux/cred.h#L290我不是在寻找其他方法这是我发现的似乎没有工作如何在编写Linux内核模块时获取用户ID 如何做我从内核空间调用Linux系统调用?
有问题的功能:
static int getuid()
{
return get_current_user()->uid;
}
Run Code Online (Sandbox Code Playgroud)
gcc输出:
make -C /lib/modules/2.6.32-358.11.1.el6.x86_64/build M=/root/git_prj1 modules
make[1]: Entering directory `/usr/src/kernels/2.6.32-358.11.1.el6.x86_64'
CC [M] /root/git_prj1/proc_setup.o
/root/git_prj1/proc_setup.c:37: warning: function declaration isn???t a prototype
/root/git_prj1/proc_setup.c: In function ???getuid???:
/root/git_prj1/proc_setup.c:39: error: dereferencing pointer to incomplete type
/root/git_prj1/proc_setup.c:39: error: implicit declaration of function ???get_uid???
/root/git_prj1/proc_setup.c:39: warning: assignment makes pointer from integer without a cast
/root/git_prj1/proc_setup.c:39: warning: return makes integer from pointer without a cast
/root/git_prj1/proc_setup.c: In function ???read_key???:
/root/git_prj1/proc_setup.c:52: warning: format ???%s??? …Run Code Online (Sandbox Code Playgroud) 您编写的用于提供procfs接口的函数只是LKM源代码中的一部分。
http://linux.die.net/lkmpg/x769.html有一个使用procfs的简单示例,在此处复制:
我从上面的链接中复制了代码-您可以在http://www.cyberciti.biz/tips/compiling-linux-kernel-module.html上找到构建内核模块的教程。总结如下:
1)确保在/ usr / src中安装了内核源。
2)创建一个如下所示的makefile:
obj-m = procfs2.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
Run Code Online (Sandbox Code Playgroud)
3)使用命令make构建模块4)使用命令insmod procfs2.ko将模块加载到内存中(以root用户身份执行)
我复制了代码并创建了MAKEFILE,稍后,如果我从控制台发出make命令,则该命令将显示为:make:所有人都无能为力。有人可以告诉我可能是什么错误吗?
我正在尝试实现我自己的ps命令,称为psmod.我可以使用linux系统调用和/proc目录的所有实用程序.
我发现目录中的所有目录都/proc以数字作为名称,是系统中的进程.我的问题是:如何只选择那些在psmod被调用时处于活动状态的进程?我知道/proc/<pid>/stat有一封信代表了这个过程的现状; 无论如何,对于每一个进程来说/proc,这封信就是S在睡觉.
我还试图向每个进程发送一个信号0,从0到maximumnumberofprocesses(在我的例子中,32768),但是这样它发现的进程远远多于进程中的进程/proc.
所以,我的问题是,ps工作怎么样?源码对我来说有点复杂,所以如果有人能解释我,我将不胜感激.
procfs ×13
linux ×10
c ×4
kernel ×3
linux-kernel ×3
process ×2
ps ×2
bash ×1
c++ ×1
fifo ×1
freebsd ×1
makefile ×1
pid ×1
pipe ×1
python-3.2 ×1
python-3.x ×1
sockets ×1
system-calls ×1
unix ×1