Linux programming series-system and process information

/proc file system

  • Get information about the process: /proc/PID

In the old version of UNIX, privileged programs are allowed to penetrate the data structure in the kernel memory to obtain kernel information, such as:
1. How many processes are running in the system and who is the owner?
2. How many files does a process open?
3. What files are currently locked,
4. Which processes hold these locks? What socket is being used by the system?

In order to provide a more convenient way to access kernel information, many modern UNIX implementations provide a /proc virtual file system.
The file system resides in the /proc directory, contains various files used to display kernel information, and allows processes to pass Conventional file I/O system calls to facilitate reading, and sometimes you can modify this information.
The /proc file system is called virtual because the files and subdirectories it contains are not stored on the disk, but are dynamically created by the kernel when the process accesses such information

  1. Get information related to the process: /proc/PID

    For each process in the system, the kernel provides a corresponding directory, the command is /proc/PID, where PID is the process ID. Various files and subdirectories in this directory contain information about the process.

    1)./Proc/PID/status result parameter description

    There is a file named satus in each /proc/PID directory, which provides series information of the process,

    $ cat /proc/1/status
    Name:	systemd			 # name of command run by this process(进程名)	
    Umask:	0000
    State:	S (sleeping)	 # State of this process (进程状态)
    Tgid:	1				 # Thread group ID(traditional PID, getpid()) 线程组ID	
    Ngid:	0	
    Pid:	1				 # Actually,thread ID(gettid()) 进程ID(实际线程ID)
    PPid:	0				 # Parent process ID (父进程ID)
    TracerPid:	0 			 # PID of tracing process(0 if not traced)(接收跟踪该进程信息的进程的ID号)
    Uid:	0	0	0	0	 # Real, offective, saved set, and FS UIDS
    Gid:	0	0	0	0	 # Real, offective, saved set, and FS GIDS
    FDSize:	128				 # of file descriptor slots currently allocated(当前分配的文件描述符插槽最大个数)
    Groups:	 				 # supplementary group IDs(补充组ID)
    NStgid:	1	
    NSpid:	1
    NSpgid:	1
    NSsid:	1
    VmPeak:	  270708 kB		 # Peak virtual memory size(峰值虚拟内存大小)
    VmSize:	  205172 kB		 # Current virtual memory size(当前虚拟内存大小,其中total_vm为进程的地址空间的大小,reserved_vm:进程在预留或特殊的内存间的物理页 )
    VmLck:	       0 kB		 # Locked memory (锁定存储器, 任务已经锁住的物理内存的大小。锁住的物理内存不能交换到硬盘 (locked_vm) 
    VmPin:	       0 kB		 
    VmHWM:	    7440 kB		 # Peak resident set size (峰值驻留集大小)
    VmRSS:	    7440 kB		 # Current resident set size (当前峰值驻留集大小, 应用程序正在使用的物理内存的大小,就是用ps命令的参数rss的值 (rss) )
    RssAnon:	    2208 kB	 # 
    RssFile:	    5232 kB
    RssShmem:	       0 kB
    VmData:	   18556 kB		 # Data segment size (数据段大小)
    VmStk:	     132 kB		 # Stack size(栈大小)
    VmExe:	     948 kB		 # Text(executable code)size (代码段大小,程序所拥有的可执行虚拟内存的大小,代码段,不包括任务使用的库 (end_code-start_code) )
    VmLib:	    6816 kB		 # Shared library size (共享库大小,被映像到任务的虚拟内存空间的库的大小 (exec_lib)
    VmPTE:	     160 kB		 # Size of page table(since 2.6.10) (页表大小, 该进程的所有页表的大小,单位:kb )
    VmSwap:	       0 kB 	 # 
    HugetlbPages:	       0 kB
    CoreDumping:	0
    Threads:	1		  	 #  of threads in this thread's thread group (此线程的线程组中的线程数)
    SigQ:	0/31144			 # Current/max,queued signals(since 2.6.10) (当前/最大,信号队列(从2.6.12开始))
    SigPnd:	0000000000000000 # Signals pending for thread (线程的挂起信号, 屏蔽位,存储了该线程的待处理信号)
    ShdPnd:	0000000000000000 # Signals pending for process(since 2.6) (等待处理的信号, 屏蔽位,存储了该线程组的待处理信号 )
    SigBlk:	7be3c0fe28014a03 # Blocked signals(阻塞信号, 存放被阻塞的信号)
    SigIgn:	0000000000001000 # Ignored singals(忽略的信号, 存放被忽略的信号 )
    SigCgt:	00000001800004ec # Caught signals (捕捉到的信号, 存放被捕获到的信号)
    CapInh:	0000000000000000 # Inheritable capabilities (可继承能力, 能被当前进程执行的程序的继承的能力 )
    CapPrm:	0000003fffffffff # Permitted capabilities (进程能够使用的能力,可以包含CapEff中没有的能力,这些能力是被进程自己临时放弃的,CapEff是CapPrm的一个子集,进程放弃没有必要的能力有利于提高安全性)
    CapEff:	0000003fffffffff # Effective capabilities (进程的有效能力)
    CapBnd:	0000003fffffffff # Capability boundings set(since 2.6.26) (能力边界集)
    CapAmb:	0000000000000000
    NoNewPrivs:	0
    Seccomp:	0
    Speculation_Store_Bypass:	vulnerable
    Cpus_allowed:	f		 # CPUs allowed, mask	(since 2.6.24)
    Cpus_allowed_list:	0-3  # Same as above, list format(since 2.6.24) (与上面相同, 列表格式)
    
    # Mems_allowed:	 Memory nodes allowed, mask (允许内存节点,掩码) since 2.6.24
    Mems_allowed:	00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001	
    Mems_allowed_list:	0 # Same as above, list format
    voluntary_ctxt_switches:	1383	# Voluntary context switches (自动上下文切换) since 2.6.23
    nonvoluntary_ctxt_switches:	576 	# Involuntary context switches (非自愿上下文切换)since 2.6.23
    Statck usage: 8kb	# Stack usage high-water mark (堆栈使用的量最高水位线) since 2.6.23	
    

    The content of this file changes over time, and this fact reveals the main points about the use of the /proc file. When these files
    are composed of multiple entries, their parsing should be done carefully. In this case, you should find
    matching rows that contain special strings (e.g., PPid) instead of processing them according to (logical) row numbers. file

    2). Other contents in /Proc/PID directory
    Excerpts from files in the /proc/PID directory
    a. /proc/PID/fd directory:

    The /proc/PID/fd directory contains a symbolic link for each file descriptor opened by the process, and the
    name of each symbolic link matches the value of the descriptor. For example, /proc/1968/1 is the symbolic
    link to standard output in the process with ID 1968. For more information, see section 5.11.
    For convenience, any process can use the symbolic link /proc/self to access its own /proc/PID directory

    b. Thread: /proc/PID/task directory:

    Linux 2.4 adds the concept of thread group and officially supports the POSIX thread model. Because some attributes in the thread group
    are unique to the thread, Linux 2.4 adds a task subdirectory under the /proc/PID directory. For
    each thread in the process , the kernel provides a subdirectory named /proc/PID/task/TID, where TID is the thread ID of the thread.
    (This
    value is equivalent to the return value of calling the gettid() function in the thread.)
    Each /proc/PID/task/TID subdirectory contains a set of files and directories similar to the contents of the /proc/PID directory. Because threads
    share multiple attributes, much of the information in these files is the same for each thread in the process. However,
    these files also display unique information for each thread, so it is reasonable. For example, in the /proc/PID/task/TID/status
    file of the thread group , there are fields that may have different contents for each thread, State, Pid, ​​SigPnd, SigBlk,
    CapInh, CapPrm, CapEff And CapBnd are listed here.

  2. System information in the /proc directory

    • System information accessed by various files and subdirectories in the /proc directory
      System information accessed by various files and subdirectories in the /proc directory
    1. Excerpts from the purpose of the /proc subdirectory
       Excerpts from the purpose of the /proc subdirectory
  3. Access /proc file

Use regular I/O system calls to access files in the /proc directory, but there are the following restrictions when accessing:
1. Some files in the /proc directory are read-only, that is, these files are only used to display kernel information, but cannot Modify it. Most files in the /proc/PID directory belong to this type

. 2. Some files in the /proc directory can only be read by the file owner (or privileged process). For example, / proc / all files in the PID / directory belong to the user with appropriate process, and even the owner of the file, where the part of the file (such as: / proc / PID / environ file) is only granted read access

3 . Except the files in the /proc/PID subdirectory, most of the files in the /proc directory belong to the root user, and only the root user can modify the files that can be modified.

Sample program: modify /proc/sys/kernel/pid_max

#define MAX_LINE 100

int main(int argc, char **argv)
{
    
    
    int fd;
    char line[MAX_LINE];
    ssize_t n;

    fd = open("/proc/sys/kernel/pid_max",
            (argc > 1) ? O_RDWR : O_RDONLY);

    if (fd == -1) {
    
    
        perror("open");
        exit(1);
    }

    n = read(fd, line, MAX_LINE);
    if (n == -1) {
    
    
        perror("read");
        exit(1);
    }

    if (argc > 1) {
    
    
        printf("Old value: ");
        printf("%.*s", (int)n, line);
    }

    if (argc > 1) {
    
    
        if (lseek(fd, 0, SEEK_SET) == -1) {
    
    
            perror("lseek");
        }
        if ( write(fd, argv[1], strlen(argv[1])) != strlen(argv[1]) ) {
    
    
            perror("write()");
        }

        system("echo /proc/sys/kernel/pid_max now_contains "
               " `cat /proc/sys/kernel/pid_max`");
    }

    exit(EXIT_SUCCESS);
    return 0;
}

The contents of the proc/PID directory may vary. Each directory is created as the process with the corresponding process ID is created, and then disappears as the process terminates. This means that to determine the existence of a specific /proc/PID directory, you need to cleanly handle the following possibilities: when opening a file in this directory, the process has been terminated, and the corresponding /proc/PID directory has also been deleted

System ID: uname()

The uname() system call returns a series of marking information about the host system, which is stored in the structure pointed to by utsbuf

  • The utsname structure
    utsbuf parameter is a pointer to the utsname structure, which is defined as follows
#define _UTSNAME_LENGTH 65
struct utsname {
    
    
    char sysname[_UTSNAME_LENGTH];  /* Implementation name 实现名称*/
    char nodename[_UTSNAME_LENGTH]; /* Node name on network 网络上的节点名 */
    char release[_UTSNAME_LENGTH];  /* Implementation release 实施发布级别 */
    char version[_UTSNAME_LENGTH];  /* Release version level 版本级别 */
    char machine[_UTSNAME_LENGTH];  /* Hardware on which system
                                        is running  运行系统的硬件 */
#ifdef _GNU_SOURCE                  /* Following is Linux-specific */
    char domainname[_UTSNAME_LENGTH];   /* NIS domain name of host 主机域名 */
#endif
};

/* SUSv3规范了uname(),但对utsname结构中各种字段的长度未加定义,
仅要求字符串以空子节终止。在Linux中,这些字段长度均为65个字节,
其中包括了空字节终止符所占用的空间。而在一些UNIX实现中,这些长度更短,
但在其他操作系统(如Solaris)中,这些字段的长度长达257个字节
*/
/* utsname结构中的sysname、release、version、和machine字段
由内核自动设置 */

In Linux, the three files in the /proc/sys/kernel directory provide the same information as the return values ​​of the sysname and version fields of the utsname structure. These read-only files are ostype , osrelease and version respectively . Another file, / proc/version , also contains this information, and also contains information about the steps of kernel compilation (ie, the user name that executes the compilation, the host name used for the compilation, and the gcc version used).

  • uname related system calls
    1.sethostname()

    Set the value of the nodename field in the utsname structure (for details, please refer to the manual page of this system call). Usually, this value is similar to the prefix host name in the system DNS domain name.

  1. gethostname()

    The gethostname() system call (which is the reverse operation of the sethostname() function) is used to obtain the system hostname, and the hostname(1) command and the Linux-specific /proc/hostname file can also be used to view and set the system hostname.

  2. getdomainame() & setdomainname()

    The getdomainname() system call (the reverse operation of the setdomainname() function) is used to obtain the NIS domain name, and the
    domainname(1) command and the Linux-specific /proc/domainname file can also be used to view and set the NIS domain name

The sethostname() and setdomainname() system calls are rarely used in applications. Usually, the
startup script is run when the system starts to establish the host name and NIS domain name.

  • Use uname

#include <sys/utsname.h>
int uname(struct utsname *utsbuf);
                                  Returns 0 on sucess, or -1 on error

int main()
{
    
    
    struct utsname uts;

    if (uname(&uts) == -1) {
    
    
        perror("uname");
        exit(EXIT_FAILURE);
    }

    printf("Node name: %s\n", uts.nodename);
    printf("System name: %s\n", uts.sysname);
    printf("Release: %s\n", uts.release);
    printf("Version: %s\n", uts.version);
    printf("Machine: %s\n", uts.machine);
#ifdef _GNU_SOURCE
    printf("Domain name: %s\n", uts.domainname);
#endif
    exit(EXIT_SUCCESS);
}
  • to sum up

The /proc file system exposes a series of kernel information to the application. Each /proc/PID subdirectory contains many files and subdirectories, which are related information provided by the process whose process ID is PID. Many other files and directories in the /proc directory expose system-level information that applications can read and sometimes modify.

Using the uname system call, you can obtain the implementation information of UNIX and the type of machine the application is running on

Advanced: In-depth information about the /proc file system can be found in the proc(5) man page, the kernel source file Documentation/
filesystems/proc.txt, and various files in the Documentation/sysctl directory.

Guess you like

Origin blog.csdn.net/gripex/article/details/105737043