Apa yang terjadi ketika saya menjalankan perintah cat / proc / cpuinfo?

Jawaban:

72

Setiap kali Anda membaca file di bawah /proc, ini meminta beberapa kode dalam kernel yang menghitung teks untuk dibaca sebagai konten file. Fakta bahwa konten dihasilkan dengan cepat menjelaskan mengapa hampir semua file dilaporkan waktunya seperti sekarang dan ukurannya dilaporkan sebagai 0 - di sini Anda harus membaca 0 sebagai “tidak tahu”. Tidak seperti filesystem biasa, filesystem yang di-mount /proc, yang disebut procfs , tidak memuat data dari disk atau media penyimpanan lainnya (seperti FAT, ext2, zfs, ...) atau melalui jaringan (seperti NFS, Samba, ...) dan tidak memanggil kode pengguna (tidak seperti FUSE ).

Procfs hadir di sebagian besar kesatuan non-BSD. Ini memulai kehidupannya di Bell Labs AT&T dalam edisi ke-8 UNIX sebagai cara untuk melaporkan informasi tentang proses (dan pssering kali merupakan printer yang cukup untuk informasi yang dapat dibaca /proc). Sebagian besar implementasi procfs memiliki file atau direktori yang dipanggil /proc/123untuk melaporkan informasi tentang proses dengan PID 123. Linux memperluas sistem file proc dengan lebih banyak entri yang melaporkan keadaan sistem, termasuk contoh Anda /proc/cpuinfo.

Di masa lalu, Linux /procmengakuisisi berbagai file yang menyediakan informasi tentang driver, tetapi penggunaan ini sekarang tidak lagi mendukung /sys, dan /procsekarang berevolusi secara lambat. Entri menyukai /proc/busdan /proc/fs/ext4tetap di tempatnya untuk kompatibilitas mundur, tetapi antarmuka serupa yang lebih baru dibuat di bawah /sys. Dalam jawaban ini, saya akan fokus pada Linux.

Titik masuk pertama dan kedua Anda untuk dokumentasi tentang /procdi Linux adalah:

  1. yang proc(5)halaman manual ;
  2. Sistem /procfile dalam dokumentasi kernel .

Titik masuk ketiga Anda, ketika dokumentasi tidak membahasnya, sedang membaca sumbernya . Anda dapat mengunduh sumbernya di komputer Anda, tetapi ini adalah program yang sangat besar, dan LXR , referensi silang Linux, sangat membantu. (Ada banyak varian LXR; yang berjalan pada lxr.linux.noadalah yang terbaik sejauh ini tetapi sayangnya situs sering turun.) Sedikit pengetahuan tentang C diperlukan, tetapi Anda tidak perlu menjadi seorang programmer untuk melacak nilai misterius .

Inti penanganan /procentri ada di fs/procdirektori. Driver apa pun dapat mendaftarkan entri /proc(meskipun seperti yang ditunjukkan di atas ini sekarang sudah tidak berlaku lagi /sys), jadi jika Anda tidak menemukan apa yang Anda cari fs/proc, lihat di tempat lain. Fungsi panggilan driver dinyatakan dalam include/linux/proc_fs.h. Versi kernel hingga 3,9 menyediakan fungsi create_proc_entrydan beberapa pembungkus (terutama create_proc_read_entry), dan versi kernel 3,10 dan di atasnya hanya menyediakan proc_createdan proc_create_data(dan beberapa lagi).

Mengambil /proc/cpuinfosebagai contoh, pencarian akan "cpuinfo"mengarahkan Anda ke panggilan proc_create("cpuinfo, …")masuk fs/proc/cpuinfo.c. Anda dapat melihat bahwa kode ini adalah kode boilerplate: karena sebagian besar file /prochanya membuang beberapa data teks, ada fungsi pembantu untuk melakukan itu. Hanya ada seq_operationsstruktur, dan daging asli ada di cpuinfo_opstruktur data, yang bergantung pada arsitektur, biasanya didefinisikan dalam arch/<architecture>/kernel/setup.c(atau kadang-kadang file yang berbeda). Mengambil x86 sebagai contoh, kita dituntun ke arch/x86/kernel/cpu/proc.c. Di sana fungsi utamanya adalahshow_cpuinfo, yang mencetak konten file yang diinginkan; infrastruktur lainnya ada untuk memberi makan data ke proses membaca dengan kecepatan yang diminta. Anda dapat melihat data yang sedang dikumpulkan dengan cepat dari data dalam berbagai variabel di kernel, termasuk beberapa angka yang dihitung saat itu juga seperti frekuensi CPU .

Sebagian besar /procadalah informasi per proses di /proc/<PID>. Entri-entri ini terdaftar di fs/proc/base.cdalam tgid_base_stuffarray ; beberapa fungsi yang terdaftar di sini didefinisikan dalam file lain. Mari kita lihat beberapa contoh bagaimana entri ini dihasilkan:

  • cmdlinedihasilkan oleh proc_pid_cmdlinedalam file yang sama. Ini menempatkan data te dalam proses dan mencetaknya.
  • clear_refs, tidak seperti entri yang kami lihat sejauh ini, dapat ditulis tetapi tidak dapat dibaca. Oleh karena itu proc_clear_refs_operationsstruktur mendefinisikan clear_refs_writefungsi tetapi tidak ada fungsi baca.
  • cwdadalah tautan simbolik (yang agak ajaib), dideklarasikan oleh proc_cwd_link, yang mencari direktori proses saat ini dan mengembalikannya sebagai konten tautan.
  • fdadalah subdirektori. Operasi pada direktori itu sendiri didefinisikan dalam proc_fd_operationsstruktur data (mereka boilerplate kecuali untuk fungsi yang menyebutkan entri proc_readfd,, yang menyebutkan file proses terbuka) sementara operasi pada entri berada di operasi `proc_fd_inode_ .

Area penting lainnya /procadalah /proc/sys, yang merupakan antarmuka langsung ke sysctl. Membaca dari entri dalam hierarki ini mengembalikan nilai nilai sysctl yang sesuai, dan tulisan menetapkan nilai sysctl. Titik masuk untuk sysctl ada di fs/proc/proc_sysctl.c. Sysctl memiliki sistem registrasi register_sysctldan teman mereka sendiri .

Gilles
sumber
59

Saat mencoba mendapatkan wawasan tentang jenis sihir apa yang terjadi di balik layar, sahabatmu itu strace. Belajar mengoperasikan alat ini adalah salah satu hal terbaik yang dapat Anda lakukan untuk mendapatkan penghargaan yang lebih baik atas apa yang terjadi dengan sihir gila di balik layar.

$ 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
...

Dari output di atas, Anda dapat melihat bahwa /proc/cpuinfoitu hanya file biasa, atau setidaknya akan muncul sebagai file biasa. Jadi mari kita gali lebih dalam.

Menyelam lebih dalam

# 1 - dengan ls ..

Melihat file itu sendiri tampaknya "hanya file".

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

Tapi lihat lebih dekat. Kami mendapatkan petunjuk pertama kami bahwa khusus, perhatikan ukuran file adalah 0 byte.

# 2 - dengan stat ..

Jika sekarang kita melihat file menggunakan statkita bisa mendapatkan petunjuk selanjutnya bahwa ada sesuatu yang istimewa /proc/cpuinfo.

jalankan # 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: -
jalankan # 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: -

Perhatikan Akses, Ubah, & Ubah waktu? Mereka terus berubah untuk setiap akses. Ini sangat tidak biasa bahwa ketiganya akan berubah seperti itu. Kecuali jika atribut timestamp file yang diedit biasanya tetap sama.

# 3 - dengan file ..

Namun petunjuk lain bahwa file ini adalah file biasa:

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

Jika itu adalah manifestasi dari pipa bernama itu akan menunjukkan mirip dengan salah satu file ini:

$ 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

Jika kita menyentuh emptyfile, /proc/cpuinfotampaknya lebih seperti file daripada pipa:

$ touch emptyfile
$ ls -l emptyfile 
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile 
emptyfile: empty
# 4 - dengan mount ..

Jadi pada titik ini kita perlu mengambil langkah mundur dan memperkecil sedikit. Kami sedang melihat file tertentu, tetapi mungkin kita harus melihat sistem file tempat file ini berada. Dan untuk ini kita bisa menggunakan mountperintah.

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

OK, jadi tipe sistem file adalah tipe proc. Begitu /procjuga dengan tipe sistem file yang berbeda, itulah petunjuk kami bahwa file-file di bawah /procini spesial. Mereka bukan hanya Anda menjalankan file pabrik. Jadi mari kita cari tahu lebih banyak info tentang apa yang membuat sistem procfile istimewa.

Lihatlah mounthalaman manual:

Sistem file proc tidak dikaitkan dengan perangkat khusus, dan ketika memasangnya, kata kunci yang sewenang-wenang, seperti proc dapat digunakan sebagai ganti spesifikasi perangkat. (Pilihan biasa tidak ada yang kurang beruntung: pesan kesalahan `tidak sibuk 'dari umount dapat membingungkan.)

Dan jika kita melihat prochalaman manual:

Sistem file proc adalah sistem file pseudo yang digunakan sebagai antarmuka untuk struktur data kernel. Biasanya dipasang di / proc. Sebagian besar hanya-baca, tetapi beberapa file memungkinkan variabel kernel untuk diubah.

Sedikit lebih jauh di halaman manual yang sama:

/ proc / cpuinfo

Ini adalah kumpulan item yang tergantung pada arsitektur sistem dan CPU, untuk setiap arsitektur yang didukung daftar yang berbeda. Dua entri umum adalah prosesor yang memberikan nomor CPU dan bogomips; konstanta sistem yang dihitung selama inisialisasi kernel. Mesin SMP memiliki informasi untuk setiap CPU. Perintah lscpu (1) mengumpulkan informasinya dari file ini.

Di bagian bawah halaman manual adalah referensi ke dokumen kernel yang dapat Anda temukan di sini, berjudul: THE / proc FILESYSTEM . Mengutip dari dokumen itu:

Sistem file proc bertindak sebagai antarmuka ke struktur data internal di kernel. Ini dapat digunakan untuk memperoleh informasi tentang sistem dan untuk mengubah parameter kernel tertentu saat runtime (sysctl).

Kesimpulan

Jadi apa yang kita pelajari di sini? Baik diberikan yang /procdisebut sebagai sistem file semu dan juga "antarmuka ke struktur data internal" mungkin aman untuk menganggap bahwa item di dalamnya bukan file yang sebenarnya, tetapi lebih dari sekadar manifestasi yang dibuat terlihat seperti file, tetapi sebenarnya tidak.

Saya akan menutup dengan kutipan ini yang tampaknya digunakan dalam versi sebelumnya man 5 procdari sekitar tahun 2004 tetapi untuk alasan apa pun tidak lagi disertakan. CATATAN: Saya tidak yakin mengapa itu dihapus karena itu menjelaskan dengan sangat baik apa /procitu:

Direktori / proc pada sistem GNU / Linux menyediakan antarmuka seperti sistem file ke kernel. Ini memungkinkan aplikasi dan pengguna untuk mengambil informasi dari dan menetapkan nilai dalam kernel menggunakan operasi I / O sistem file normal.

Sistem file proc kadang-kadang disebut sebagai proses pseudo-file sistem informasi. Ini tidak mengandung file `` nyata '' melainkan informasi sistem runtime (misalnya memori sistem, perangkat yang dipasang, konfigurasi perangkat keras, dll). Untuk alasan ini dapat dianggap sebagai pusat kontrol dan informasi untuk kernel. Bahkan, cukup banyak utilitas sistem hanya panggilan ke file di direktori ini. Sebagai contoh, perintah lsmod, yang mencantumkan modul yang dimuat oleh kernel, pada dasarnya sama dengan 'cat / proc / modules' sementara lspci, yang mencantumkan perangkat yang terhubung ke bus PCI sistem, sama dengan 'cat / proc / pci '. Dengan mengubah file yang terletak di direktori ini Anda dapat mengubah parameter kernel saat sistem sedang berjalan.

Sumber: Sistem file pseudo proc

Referensi

slm
sumber
1
Keren, :) ini adalah hal pertama yang saya coba ketika saya melihat pertanyaan:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Jawaban bagus! Di linux, jika Anda ingin menggali lebih dalam, sumber untuk sistem file proc ada di fs / proc di sumber kernel. Anda akan melihat bahwa ada fs / proc / cpuinfo.c tetapi, sayangnya, ini agak kosong karena pengangkatan yang berat tersebar di seluruh lengkungan / karena tergantung arsitektur. Untuk contoh yang lebih sederhana, lihat fs / proc / uptime.c. Dengan melirik file kita dapat menebak bahwa uptime_proc_show adalah pekerja keras dari apa yang membuat kita mendapatkan data yang kita inginkan dan kita bisa menjelajahinya lebih jauh dengan menyelami fungsi yang dipanggilnya. Untuk memahami antarmuka seq_file dan bagaimana ia digunakan dalam procfs lihat:
Steven D
1
@slm: +1, jawaban yang bagus. Tetapi bagi saya, petunjuk pertama itu adalah file khusus adalah ukurannya ^^ 0 byte, namun Anda dapat menyimpan banyak hal darinya (sedikit seperti beberapa file pipa).
Olivier Dulac
@OlivierDulac - poin bagus. Saya telah mengedit tambahan berdasarkan tanggapan Anda. LMK jika saya dapat melakukan perbaikan lebih lanjut. Terima kasih.
slm
14

Jawaban yang diberikan oleh @slm sangat komprehensif, tapi saya pikir penjelasan yang lebih sederhana mungkin berasal dari perubahan perspektif.

Dalam penggunaan sehari-hari kita dapat menganggap file sebagai hal-hal fisik, yaitu. potongan data yang disimpan pada beberapa perangkat. Ini membuat file seperti / proc / cpuinfo sangat misterius dan membingungkan. Namun, semuanya masuk akal jika kita menganggap file sebagai antarmuka ; cara untuk mengirim data masuk dan keluar dari beberapa program.

Program yang mengirim dan menerima data dengan cara ini adalah sistem file atau driver (tergantung pada bagaimana Anda mendefinisikan istilah-istilah ini, yang mungkin terlalu luas atau terlalu sempit definisi). Poin penting adalah bahwa beberapa program ini menggunakan perangkat perangkat keras untuk menyimpan dan mengambil data yang dikirim melalui antarmuka ini; tapi tidak semua.

Beberapa contoh filesystem yang tidak menggunakan perangkat penyimpanan (setidaknya secara langsung) adalah:

  • Sistem file menggunakan data yang dicari atau dihitung. Proc adalah contohnya, karena ia mendapat data dari berbagai modul kernel. Contoh ekstrem adalah πfs (github.com/philipl/pifs)
  • Semua filesystem FUSE, yang menangani data dengan program userspace biasa
  • Filesystem yang mentransformasikan data filesystem lain dengan cepat, misalnya menggunakan enkripsi, kompresi atau bahkan transcoding audio (khenriks.github.io/mp3fs/)

OS Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) adalah contoh ekstrem menggunakan file sebagai antarmuka pemrograman umum.

Warbo
sumber