Điều gì xảy ra khi tôi chạy lệnh cat / Proc / cpuinfo?


Câu trả lời:


72

Bất cứ khi nào bạn đọc một tệp bên dưới /proc, điều này sẽ gọi một số mã trong kernel để tính toán văn bản để đọc làm nội dung tệp. Thực tế là nội dung được tạo nhanh chóng giải thích lý do tại sao hầu hết tất cả các tệp đều có thời gian được báo cáo như bây giờ và kích thước của chúng được báo cáo là 0 - ở đây bạn nên đọc 0 vì không hiểu biết. Không giống như các hệ thống tệp thông thường, hệ thống tệp được gắn trên /proc, được gọi là Procfs , không tải dữ liệu từ đĩa hoặc phương tiện lưu trữ khác (như FAT, ext2, zfs, giật) hoặc qua mạng (như NFS, Samba, Nott) và không gọi mã người dùng (không giống như FUSE ).

Procfs có mặt trong hầu hết các đơn vị không thuộc BSD. Nó bắt đầu cuộc sống của mình tại Phòng thí nghiệm Bell của AT & T trong phiên bản UNIX 8 như một cách để báo cáo thông tin về các quy trình (và psthường là một máy in đẹp cho thông tin đọc qua /proc). Hầu hết các cài đặt Procfs đều có một tệp hoặc thư mục được gọi /proc/123để báo cáo thông tin về quy trình với PID 123. Linux mở rộng hệ thống tệp Proc với nhiều mục khác báo cáo trạng thái của hệ thống, bao gồm cả ví dụ của bạn /proc/cpuinfo.

Trước đây, Linux đã /procmua các tệp khác nhau cung cấp thông tin về trình điều khiển, nhưng việc sử dụng này hiện không được ủng hộ /sys/prochiện đang phát triển chậm. Các mục nhập thích /proc/bus/proc/fs/ext4duy trì vị trí tương thích ngược, nhưng các giao diện tương tự mới hơn được tạo bên dưới /sys. Trong câu trả lời này, tôi sẽ tập trung vào Linux.

Điểm nhập cảnh đầu tiên và thứ hai của bạn cho tài liệu về /procLinux là:

  1. các proc(5)trang người đàn ông ;
  2. Hệ /procthống tập tin trong tài liệu kernel .

Điểm vào thứ ba của bạn, khi tài liệu không bao gồm nó, đang đọc nguồn . Bạn có thể tải xuống nguồn trên máy của mình, nhưng đây là một chương trình lớn và LXR , tài liệu tham khảo chéo của Linux, là một trợ giúp lớn. (Có rất nhiều biến thể của LXR; phiên bản đang chạy lxr.linux.nolà đẹp nhất nhưng không may là trang này thường bị sập.) Cần có một ít kiến ​​thức về C, nhưng bạn không cần phải là lập trình viên để theo dõi giá trị bí ẩn .

Việc xử lý cốt lõi của /proccác mục là trong fs/procthư mục. Bất kỳ tài xế nào cũng có thể đăng ký các mục trong /proc(mặc dù như được chỉ ra ở trên, điều này hiện không được ủng hộ /sys), vì vậy nếu bạn không tìm thấy những gì bạn đang tìm kiếm fs/proc, hãy tìm mọi nơi khác. Trình điều khiển gọi các chức năng khai báo trong include/linux/proc_fs.h. Các phiên bản kernel lên tới 3.9 cung cấp các chức năng create_proc_entryvà một số trình bao bọc (đặc biệt create_proc_read_entry) và các phiên bản kernel 3.10 trở lên chỉ cung cấp thay thế proc_createproc_create_data(và một vài thứ nữa).

Lấy /proc/cpuinfoví dụ, một tìm kiếm cho "cpuinfo"dẫn bạn đến các cuộc gọi đến proc_create("cpuinfo, …")trong fs/proc/cpuinfo.c. Bạn có thể thấy rằng mã này có khá nhiều mã soạn sẵn: vì hầu hết các tệp dưới /procchỉ đổ một số dữ liệu văn bản, có các hàm trợ giúp để làm điều đó. Chỉ có một seq_operationscấu trúc và phần thịt thực sự nằm trong cpuinfo_opcấu trúc dữ liệu, phụ thuộc vào kiến ​​trúc, thường được định nghĩa trong arch/<architecture>/kernel/setup.c(hoặc đôi khi là một tệp khác). Lấy x86 làm ví dụ, chúng tôi đã dẫn đến arch/x86/kernel/cpu/proc.c. Có chức năng chính làshow_cpuinfo, trong đó in ra nội dung tập tin mong muốn; phần còn lại của cơ sở hạ tầng là để cung cấp dữ liệu cho quá trình đọc với tốc độ mà nó yêu cầu. Bạn có thể thấy dữ liệu được lắp ráp khi đang di chuyển từ dữ liệu theo các biến khác nhau trong nhân, bao gồm một vài số được tính khi đang di chuyển, chẳng hạn như tần số CPU .

Một phần lớn /proclà thông tin trên mỗi quá trình /proc/<PID>. Các mục này được đăng ký trong fs/proc/base.c, trong tgid_base_stuffmảng ; một số chức năng đăng ký ở đây được xác định trong các tập tin khác. Hãy xem xét một vài ví dụ về cách tạo ra các mục này:

  • cmdlineđược tạo bởi proc_pid_cmdlinetrong cùng một tập tin. Nó định vị dữ liệu te trong quá trình và in ra.
  • clear_refs, không giống như các mục chúng ta đã thấy cho đến nay, có thể ghi nhưng không thể đọc được. Do đó, các proc_clear_refs_operationscấu trúc xác định một clear_refs_writechức năng nhưng không có chức năng đọc.
  • cwdlà một liên kết tượng trưng (một liên kết hơi kỳ diệu), được khai báo bởi proc_cwd_link, nó tìm kiếm thư mục hiện tại của quy trình và trả về nó dưới dạng nội dung liên kết.
  • fdlà một thư mục con. Các hoạt động trên chính thư mục được xác định trong proc_fd_operationscấu trúc dữ liệu (chúng được soạn sẵn ngoại trừ chức năng liệt kê các mục, proc_readfdliệt kê các tệp đang mở của quy trình) trong khi các thao tác trên các mục nằm trong `Proc_fd_inode_operations .

Một lĩnh vực quan trọng khác /proc/proc/sys, đó là một giao diện trực tiếp sysctl. Đọc từ một mục trong hệ thống phân cấp này trả về giá trị của giá trị sysctl tương ứng và viết sẽ đặt giá trị sysctl. Các điểm vào cho sysctl là trong fs/proc/proc_sysctl.c. Sysctls có hệ thống đăng ký riêng của họ với register_sysctlvà bạn bè.


59

Khi cố gắng hiểu rõ hơn về loại phép thuật nào đang xảy ra đằng sau hậu trường, người bạn thân nhất của bạn strace. Học cách vận hành công cụ này là một trong những điều tốt nhất bạn có thể làm để có được sự đánh giá tốt hơn cho những gì ma thuật điên rồ đang xảy ra đằng sau hậu trường.

$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536)                      = 0
close(3)                                = 0
...

Từ đầu ra trên, bạn có thể thấy đó /proc/cpuinfochỉ là một tệp thông thường, hoặc ít nhất sẽ xuất hiện là một tệp. Vì vậy, hãy đào sâu hơn.

Lặn sâu hơn

# 1 - với ls ..

Nhìn vào tập tin, nó có vẻ như "chỉ là một tập tin".

$ ls -l /proc/cpuinfo 
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo

Nhưng hãy xem xét kỹ hơn. Chúng tôi nhận được gợi ý đầu tiên của chúng tôi rằng nó đặc biệt, lưu ý kích thước của tệp là 0 byte.

# 2 - với chỉ số ..

Nếu bây giờ chúng ta xem tệp bằng cách sử dụng, statchúng ta có thể nhận được gợi ý tiếp theo rằng có gì đó đặc biệt /proc/cpuinfo.

chạy số 1
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
 Birth: -
chạy số 2
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
 Birth: -

Lưu ý thời gian truy cập, sửa đổi và thay đổi? Họ tiếp tục thay đổi cho mỗi lần truy cập. Điều này rất bất thường khi cả 3 sẽ thay đổi như thế. Trừ khi chỉnh sửa các thuộc tính dấu thời gian của tệp thường giữ nguyên.

# 3 - với tệp ..

Một manh mối khác cho thấy tệp này là bất cứ thứ gì ngoại trừ một tệp thông thường:

$ file /proc/cpuinfo 
/proc/cpuinfo: empty

Nếu đó là một số biểu hiện của một đường ống có tên, nó sẽ hiển thị tương tự như một trong các tệp sau:

$ ls -l /dev/initctl /dev/zero 
prw-------. 1 root root    0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero

$ file /dev/initctl /dev/zero 
/dev/initctl: fifo (named pipe)
/dev/zero:    character special

Nếu chúng ta chạm vào một emptyfile, /proc/cpuinfocó vẻ giống như một tập tin hơn thì một đường ống:

$ touch emptyfile
$ ls -l emptyfile 
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile 
emptyfile: empty
# 4 - với thú cưỡi ..

Vì vậy, tại thời điểm này chúng ta cần lùi lại một bước và thu nhỏ một chút. Chúng tôi đang xem một tệp cụ thể nhưng có lẽ chúng ta nên xem hệ thống tệp mà tệp này nằm trong đó. Và để làm điều này, chúng ta có thể sử dụng mountlệnh.

$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

OK, vì vậy loại hệ thống tập tin là loại proc. Vì vậy, /procmột loại hệ thống tệp khác nhau, đó là gợi ý của chúng tôi rằng các tệp bên dưới /proclà đặc biệt. Chúng không chỉ là việc bạn chạy các tập tin mill. Vì vậy, hãy tìm hiểu thêm một số thông tin về những gì làm cho prochệ thống tập tin đặc biệt.

Hãy xem mounttrang người đàn ông của:

Hệ thống tập tin Proc không được liên kết với một thiết bị đặc biệt và khi gắn nó, một từ khóa tùy ý, chẳng hạn như Proc có thể được sử dụng thay vì một đặc điểm kỹ thuật của thiết bị. (Lựa chọn thông thường không có gì kém may mắn hơn: thông báo lỗi 'không bận rộn' từ umount có thể gây nhầm lẫn.)

Và nếu chúng ta xem proctrang của người đàn ông:

Hệ thống tệp Proc là một hệ thống tệp giả được sử dụng làm giao diện cho các cấu trúc dữ liệu kernel. Nó thường được gắn tại / Proc. Hầu hết trong số đó là chỉ đọc, nhưng một số tệp cho phép thay đổi các biến nhân.

Một chút nữa xuống trong cùng một trang người đàn ông:

/ Proc / cpuinfo

Đây là một tập hợp các mục phụ thuộc kiến ​​trúc CPU và hệ thống, cho mỗi kiến ​​trúc được hỗ trợ một danh sách khác nhau. Hai mục phổ biến là bộ xử lý cung cấp số CPU và bogomips; một hằng số hệ thống được tính trong quá trình khởi tạo kernel. Máy SMP có thông tin cho từng CPU. Lệnh lscpu (1) tập hợp thông tin của nó từ tệp này.

Ở dưới cùng của trang man là một tham chiếu đến một tài liệu kernel mà bạn có thể tìm thấy ở đây, có tiêu đề: THE / Proc FILESYSTEM . Trích dẫn từ tài liệu đó:

Hệ thống tệp Proc hoạt động như một giao diện cho các cấu trúc dữ liệu nội bộ trong kernel. Nó có thể được sử dụng để có được thông tin về hệ thống và thay đổi các tham số kernel nhất định khi chạy (sysctl).

Kết luận

Vậy chúng ta đã học được gì ở đây? Được cho /proclà được gọi là hệ thống tệp giả và cũng là "giao diện cho cấu trúc dữ liệu nội bộ", có thể an toàn khi cho rằng các mục trong đó không phải là tệp thực, mà chỉ là các biểu hiện được tạo ra trông giống như tệp, nhưng thực sự không phải vậy.

Tôi sẽ kết thúc với trích dẫn này dường như đã từng là phiên bản trước của man 5 prockhoảng năm 2004 nhưng vì bất kỳ lý do gì không còn được bao gồm. LƯU Ý: Tôi không chắc tại sao nó bị xóa vì nó mô tả rất độc đáo /proc:

Thư mục / Proc trên các hệ thống GNU / Linux cung cấp giao diện giống như hệ thống tệp cho kernel. Điều này cho phép các ứng dụng và người dùng tìm nạp thông tin từ và đặt giá trị trong kernel bằng thao tác I / O của hệ thống tệp thông thường.

Hệ thống tệp Proc đôi khi được gọi là hệ thống tệp giả thông tin quy trình. Nó không chứa các tệp `` real '' mà là thông tin hệ thống thời gian chạy (ví dụ: bộ nhớ hệ thống, các thiết bị được gắn, cấu hình phần cứng, v.v.). Vì lý do này, nó có thể được coi là một trung tâm điều khiển và thông tin cho kernel. Trong thực tế, khá nhiều tiện ích hệ thống chỉ đơn giản là gọi đến các tệp trong thư mục này. Ví dụ, lệnh lsmod, liệt kê các mô-đun được nạp bởi kernel, về cơ bản giống như 'cat / Proc / mô-đun' trong khi lspci, liệt kê các thiết bị được kết nối với bus PCI của hệ thống, giống như 'cat / Proc / pci '. Bằng cách thay đổi các tệp nằm trong thư mục này, bạn có thể thay đổi các tham số kernel trong khi hệ thống đang chạy.

Nguồn: Hệ thống tập tin giả

Người giới thiệu


1
Thật tuyệt, :) đây là điều đầu tiên tôi thử khi tôi thấy câu hỏi:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc

1
Câu trả lời tốt đẹp! Trên linux, nếu bạn muốn đào sâu hơn, nguồn cho hệ thống tập tin Proc nằm trong fs / Proc trong nguồn kernel. Bạn sẽ thấy rằng có một fs / Proc / cpuinfo.c, nhưng thật không may, nó khá trống rỗng vì việc nâng vật nặng được trải ra khắp vòm / vì nó phụ thuộc vào kiến ​​trúc. Để biết ví dụ đơn giản hơn, xem fs / Proc / uptime.c. Bằng cách liếc vào tệp, chúng ta có thể đoán rằng uptime_proc_show là đặc điểm của những gì chúng ta có được dữ liệu chúng ta muốn và chúng ta có thể khám phá nó nhiều hơn bằng cách đi sâu vào các chức năng mà nó gọi. Để hiểu giao diện seq_file và cách nó được sử dụng trong Procfs, hãy xem:
Steven D


1
@slm: +1, câu trả lời tuyệt vời. Nhưng với tôi, gợi ý đầu tiên đó là một tệp đặc biệt là kích thước của nó ^^ 0 byte, nhưng bạn có thể lấy được nhiều thứ từ nó (hơi giống một số tệp ống).
Olivier Dulac

@OlivierDulac - điểm tốt. Tôi đã thực hiện các chỉnh sửa bổ sung dựa trên phản hồi của bạn. LMK nếu tôi có thể cải thiện thêm. Cảm ơn.
slm

14

Câu trả lời được đưa ra bởi @slm là rất toàn diện, nhưng tôi nghĩ rằng một lời giải thích đơn giản hơn có thể đến từ một sự thay đổi trong quan điểm.

Trong việc sử dụng hàng ngày, chúng ta có thể coi các tập tin là những thứ vật lý, tức là. khối dữ liệu được lưu trữ trên một số thiết bị. Điều này làm cho các tệp như / Proc / cpuinfo trở nên rất bí ẩn và khó hiểu. Tuy nhiên, tất cả đều có ý nghĩa hoàn hảo nếu chúng ta nghĩ về các tệp như một giao diện ; một cách để gửi dữ liệu vào và ra khỏi một số chương trình.

Các chương trình gửi và nhận dữ liệu theo cách này là hệ thống tệp hoặc trình điều khiển (tùy thuộc vào cách bạn xác định các thuật ngữ này, có thể quá rộng hoặc quá hẹp định nghĩa). Điểm quan trọng là một số chương trình này sử dụng thiết bị phần cứng để lưu trữ và truy xuất dữ liệu được gửi qua giao diện này; nhưng không phải tất cả.

Một số ví dụ về hệ thống tệp không sử dụng thiết bị lưu trữ (ít nhất là trực tiếp) là:

  • Hệ thống tập tin sử dụng dữ liệu tra cứu hoặc tính toán. Proc là một ví dụ, vì nó lấy dữ liệu từ các mô-đun hạt nhân khác nhau. Một ví dụ cực đoan là πfs (github.com/philipl/pifs)
  • Tất cả các hệ thống tập tin FUSE, xử lý dữ liệu với chương trình không gian người dùng thông thường
  • Các hệ thống tệp chuyển đổi dữ liệu của hệ thống tệp khác đang hoạt động, ví dụ như sử dụng mã hóa, nén hoặc thậm chí chuyển mã âm thanh (khenriks.github.io/mp3fs/)

Hệ điều hành Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) là một ví dụ cực đoan về việc sử dụng các tệp làm giao diện lập trình chung.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.