Apa perbedaan antara / tmp dan / run?

42

Menurut FHS-3.0 , /tmpuntuk file sementara dan /rununtuk data variabel run-time. Data masuk /runharus dihapus pada boot berikutnya, yang tidak diperlukan /tmp, tetapi program tetap tidak boleh berasumsi bahwa data masuk /tmpakan tersedia pada awal program berikutnya. Semua ini tampaknya sangat mirip dengan saya.

Jadi, apa perbedaan keduanya? Kriteria mana yang harus diputuskan oleh suatu program untuk memasukkan data sementara ke dalam /tmpatau ke dalam /run?

Menurut FHS:

Program mungkin memiliki subdirektori dari /run; ini dianjurkan untuk program yang menggunakan lebih dari satu file run-time.

Ini menunjukkan bahwa perbedaan antara "program sistem" dan "program biasa" bukan kriteria, juga tidak seumur hidup program (seperti, proses jangka panjang vs proses jangka pendek).

Meskipun alasan berikut tidak diberikan dalam FHS, /rundiperkenalkan untuk mengatasi masalah yang /vardipasang terlambat sehingga trik kotor diperlukan untuk menyediakan /var/runcukup awal. Namun, sekarang dengan /rundiperkenalkan, dan diberikan uraiannya di FHS, tampaknya tidak ada alasan yang jelas untuk memiliki keduanya /rundan /tmp.

Dirk Herrmann
sumber
11
/ tmp adalah lokasi standar * nix untuk data sementara. / run adalah lokasi standar Poettering untuk data sementara.
Markus
Kompatibilitas mundur selalu menjadi alasan ...
Bakuriu

Jawaban:

16

Tidak ada alasan untuk memiliki keduanya / run dan / tmp

Saya pikir kamu benar. /tmppada dasarnya sudah usang sekarang /run. Jika program Anda berada dalam posisi untuk melakukannya (yang mengharuskannya diinstal sebagai operasi istimewa), maka saat ini Anda akan menggunakan subdirektori dari /run. Ini untuk alasan keamanan.

Misalnya daemon pencetakan CUPS tidak berjalan sebagai root, tetapi umumnya diinstal dari paket OS. Paket menginstal /usr/lib/tmpfiles.d/cups.conf, dan systemd-tmpfilesmembuat direktori yang dapat diakses. Karena direktori berada di bawah /run, nama tersebut tidak dapat diklaim secara jahat oleh pengguna yang tidak berhak, tidak seperti /tmpyang dapat ditulis oleh dunia.

"Program tidak terjangkau" yang tidak dapat digunakan /runsecara langsung

Perbedaan sebenarnya adalah jika program Anda dijalankan oleh pengguna yang tidak memiliki hak sewenang-wenang, di bawah ID pengguna mereka sendiri. Tetapi Anda umumnya masih tidak ingin menggunakan /tmp, karena itu dapat diakses oleh pengguna yang tidak terjangkau lainnya. Anda lebih suka menggunakan $XDG_RUNTIME_DIR. Biasanya ini diimplementasikan sebagai /run/user/$(id -u)- sehingga kebetulan juga merupakan subdirektori /run. Lokasi tidak dijamin; program harus selalu menggunakan variabel lingkungan.

/tmphanya akan berguna untuk kerjasama ad-hoc antara berbagai pengguna yang tidak terjangkau pada sistem. Sistem ad-hoc seperti itu rentan terhadap pengguna jahat yang menolak untuk bekerja sama dan merusak hal-hal untuk semua orang :). Salah satu contohnya adalah pengguna yang tidak berhak memutuskan untuk menjalankan versi talkdaemon, menggunakan soket unix.

Informasi asli dari Lennart Poettering

Catatan, daftar periksa Poettering di bawah ini menyatakan bahwa /tmpakan berguna untuk "file kecil", sedangkan /runseharusnya hanya digunakan untuk "komunikasi primitif". Saya pikir perbedaan ini juga tidak benar. Untuk poster-boy /runadalah udev, dan saya cukup yakin /run/udevmenyertakan database internal. Setelah Anda memiliki /rundirektori, saya tidak berpikir ada orang yang ingin mengikuti perbedaan yang diklaim dan membuat direktori lain , menjadi berantakan /tmp. Jadi dalam praktiknya kami hanya menggunakan /runsaat ini.

Penggunaan ruang nama bersama yang dapat ditulisi dunia [seperti / tmp] untuk tujuan komunikasi selalu bermasalah, karena untuk membangun komunikasi Anda memerlukan nama yang stabil, tetapi nama yang stabil membuka pintu untuk serangan DoS. Ini dapat diperbaiki sebagian, dengan membuat direktori per aplikasi yang dilindungi untuk layanan tertentu selama boot awal (seperti yang kami lakukan untuk X11), tetapi ini hanya memperbaiki masalah sebagian, karena ini hanya berfungsi dengan benar jika setiap instalasi paket diikuti dengan reboot.

...

Fitur Fedora lain (untuk Fedora 17) mengubah semantik / tmp untuk banyak layanan sistem untuk membuatnya lebih aman, dengan mengisolasi ruang nama / tmp dari berbagai layanan

...

Karena / tmp tidak lagi perlu ruang nama bersama, biasanya tidak cocok sebagai lokasi komunikasi primitif.

...

[/ run] dijamin menjadi tmpfs dan karenanya secara otomatis memerah saat booting. Tidak ada pembersihan otomatis yang dilakukan selain itu.

...

Berikut ini panduan kasar bagaimana kami menyarankan Anda (pengembang aplikasi Linux) memilih direktori yang tepat untuk digunakan:

  1. Anda memerlukan tempat untuk meletakkan soket (atau primitif komunikasi lainnya) dan kode Anda berjalan dengan istimewa: gunakan subdirektori di bawah / jalankan. (Atau di bawah / var / run untuk kompatibilitas ekstra.)
  2. Anda memerlukan tempat untuk meletakkan soket Anda (atau primitif komunikasi lainnya) dan kode Anda berjalan tanpa hak: gunakan subdirektori di bawah $ XDG_RUNTIME_DIR.
  3. Anda memerlukan tempat untuk membuat unduhan dan unduhan Anda yang lebih besar dalam proses dan menjalankan undrivileged: gunakan $ XDG_DOWNLOAD_DIR.
  4. Anda memerlukan tempat untuk meletakkan file cache yang harus persisten dan dijalankan tanpa hak: gunakan $ XDG_CACHE_HOME.
  5. Tidak ada satu pun dari hal di atas yang berlaku dan Anda perlu menempatkan file kecil yang tidak membutuhkan persistensi: gunakan $ TMPDIR dengan fallback on / tmp. Dan gunakan mkstemp (), dan mkdtemp () dan tidak ada homegrown.
  6. Kalau tidak gunakan $ TMPDIR dengan fallback pada / var / tmp. Juga gunakan mkstemp () / mkdtemp ().

Perhatikan bahwa aturan di atas hanya disarankan oleh kami. Aturan-aturan ini memperhitungkan semua yang kita ketahui tentang topik ini dan menghindari masalah dengan distribusi saat ini dan masa depan, sejauh yang kita bisa melihatnya. Harap pertimbangkan untuk memperbarui proyek Anda untuk mengikuti aturan ini, dan ingatlah jika Anda menulis kode baru.

Satu hal yang kami ingin tekankan adalah bahwa / tmp dan / var / tmp lebih sering daripada tidak sebenarnya bukan pilihan yang tepat untuk usecase Anda. Ada kegunaan direktori ini yang valid, tetapi seringkali direktori lain mungkin merupakan tempat yang lebih baik. Jadi, berhati-hatilah, pertimbangkan opsi lain, tetapi jika Anda menggunakan / tmp atau / var / tmp maka setidaknya pastikan untuk menggunakan mkstemp () / mkdtemp ().

Kami agak lolos dengan legacy /tmpsocket yang digunakan oleh sistem X window, seperti dijelaskan di atas. Saya salah membaca tmpfiles.d/x11.conf. Sepertinya lebih bergantung pada kerjasama :). Saya menganggap kode itu sudah diaudit, sehingga penolakan layanan adalah yang terburuk yang bisa terjadi.

sourcejedi
sumber
8
Jawaban ini semua salah.
R ..
@R .., ingin memperluas itu?
Wildcard
Ya, saya sudah menjawabnya. (Dimulai sebagai komentar tetapi saya menyadari itu lebih merupakan jawaban.)
R ..
Saya pikir kelemahan utama dalam jawaban saya saat ini, yang saya pikir sedang Anda kerjakan, adalah bahwa sementara secara teknis , penanganan XDG_RUNTIME_DIR yang benar diperlukan untuk portabel ke semua * nix ("mundur ke direktori pengganti dengan kemampuan yang sama"), sangat kabur apa artinya ini dalam praktik. Untuk program utilitas portabel, lebih baik menggunakan standar yang terdefinisi dengan baik untuk /tmp("API hanya untuk menggunakannya harus mkstemp (), mkdtemp () (dan teman-teman) sepenuhnya aman").
sourcejedi
Kehilangan jawaban juga merupakan kasus umum: /var/runapakah sistem luas (mis. Untuk berkomunikasi ke basis data lokal), /tmp/sekarang sering dibuat per pengguna . Secara historis, kuota / tmp juga disetel berbeda. Dan jawabannya kehilangan bahwa perbedaan penggunaan semantik juga penting.
Giacomo Catenazzi
23

Direktori /tmpdan /usr/tmp(nanti /var/tmp) dulunya adalah tempat pembuangan segala sesuatu dan semua orang. Satu-satunya mekanisme perlindungan untuk file dalam direktori ini adalah bit sticky yang membatasi penghapusan atau penggantian nama file di sana untuk pemiliknya. Seperti yang ditunjukkan marcelm dalam komentar, pada prinsipnya tidak ada yang mencegah seseorang membuat file dengan nama yang digunakan oleh layanan (seperti nginx.pidatau sshd.pid). (Dalam praktiknya, skrip startup dapat menghapus file palsu seperti itu terlebih dahulu.)

/rundidirikan untuk data runtime non-persisten layanan berumur panjang seperti kunci, soket, file pid dan sejenisnya. Karena tidak dapat ditulisi untuk umum, ia melindungi data runtime layanan dari kekacauan /tmpdan pekerjaan yang membersihkan di sana. Memang: Dua distribusi yang saya jalankan (tidak ada permainan yang dimaksudkan) memiliki izin 755 pada /run, sementara /tmpdan /var/tmp(dan /dev/shmdalam hal ini) memiliki izin 1777.

countermode
sumber
3
itu hanya ada untuk memisahkan layanan runtime data dari kekacauan di/tmp - Juga untuk menyediakan pelabuhan yang aman untuk data tersebut dari berbagai pekerjaan pembersihan yang menginjak-injak seluruh /tmp.
Satō Katsura
Terima kasih atas info tentang izinnya. Namun, menurut FHS "Program mungkin memiliki subdirektori / run; ini dianjurkan untuk program yang menggunakan lebih dari satu file run-time." - ini tampaknya bertentangan dengan kriteria "layanan berumur panjang" serta ketidakmampuan program untuk membuat subdirektori mereka karena izin yang terbatas.
Dirk Herrmann
@DirHerrmann Tidak, tidak. Lihat /rundan periksa struktur direktori yang rumit (well ...) yang disebabkan oleh udev, udiskdll. Saya bukan ahli dalam masalah khusus ini, tapi saya kira skrip boot (yang dijalankan sebagai superuser) mengatur semuanya.
countermode
2
"/ run secara teknis tidak perlu, itu hanya ada untuk memisahkan data runtime layanan dari kekacauan di / tmp." - Untung juga, jadi proses yang tidak terjangkau tidak dapat menggunakan nama sistem yang ingin digunakan oleh layanan sistem. Agak menyebalkan jika nginx ingin menggunakan /tmp/nginx.pidtetapi sudah ada karena beberapa program nakal. /run/mencegah hal ini dengan meminta hak istimewa untuk menulis.
marcelm
18

/tmpadalah lokasi untuk pembuatan file dan direktori sementara. Ini tidak dapat digunakan untuk menyimpan "nama-nama terkenal" (yaitu nama-nama proses lain dapat disadari tanpa Anda harus menyampaikan nama itu entah bagaimana) karena tidak ada yang memiliki kepemilikan atas namespace; siapa pun dapat membuat file di sana. Dengan demikian Anda biasanya menggunakannya ketika Anda memiliki utilitas yang memerlukan file (yaitu bukan pipa atau semacamnya) sebagai input atau output, di mana nama (dibuat secara acak) akan bekerja selama Anda memasukkan nama.

Secara historis, beberapa hal (seperti X) melanggar prinsip ini dan memasukkan nama-nama terkenal (seperti .X11-unix) ke dalam /tmp. Ini tentu saja buggy dan memungkinkan setiap pengguna untuk melakukan layanan yang perlu melakukannya hanya dengan berlomba untuk membuat file dengan nama yang diinginkan terlebih dahulu. Hal-hal seperti itu termasuk di bawah /run(atau yang setara /var/runjika Anda tidak berlangganan revisionisme Freedesktop.org). Tentu saja yang lebih baik adalah memperbaikinya untuk tidak menggunakan nama-nama terkenal di namespace global tetapi sebaliknya memberikan pathname.

R ..
sumber
Terima kasih atas beberapa definisi lebih lanjut tentang "file sementara". Meskipun saya tidak berpikir "menyampaikan nama jalan" menjelaskan bagaimana cara menetapkan titik koordinasi. Yaitu biasanya Anda akan menggunakan variabel lingkungan. Sepertinya ada beberapa soket dan pipa yang cukup (untuk penggunaan umum) agar berfungsi. (Sebagian karena banyak hal akan berjalan di soket dbus yang sama). Sepertinya itu akan mengganggu untuk mengatur lingkungan jika program tidak default ke jalur hardcoded sekalipun. Anda dapat menambahkan kunci baru ke .socketfile systemd ... tetapi itu tidak membantu untuk seluruh direktori, atau untuk layanan yang baru diinstal
sourcejedi
2
/run/itu sendiri diadopsi oleh FHS, saya tidak bisa melihat bagaimana itu ada hubungannya dengan fd.o. Kecuali jika kita benar-benar bermaksud mengeluh tentang upaya pembangunan yang tidak ditentukan yang berkontribusi pada keduanya.
sourcejedi
Saya pikir jawaban awal di sini adalah jawaban terbaik untuk pertanyaan yang ditulis. Saya pikir itu akan ditingkatkan lebih lanjut dengan mempertimbangkan: _ Ketika perangkat lunak memiliki akses tulis ke direktori khusus misalnya di bawah /run, mungkin memilih untuk menghindari mengacaukan /tmpdirektori bersama dengan file lebih banyak lagi.
sourcejedi
Apa itu "fd.o"?
TRiG
7

Menurut Standar Hierarki Filesystem,

  • /run adalah untuk data variabel runtime yaitu informasi tentang sistem yang berjalan sejak reboot
  • /tmp adalah tempat umum untuk file sementara.

Jadi segala sesuatu yang berkaitan dengan status daemon, pengguna yang masuk, perangkat yang dapat dilepas, dll. Akan masuk /runsementara file sementara yang dibuat oleh suatu program akan dimasukkan /tmp.

Sunting: seperti yang ditunjukkan oleh @JdeBP dalam komentar di bawah,

FHS memungkinkan untuk hal-hal seperti pengaturan konvensional pekerjaan cron yang secara teratur membersihkan /tmpfile "lama"; tanpa mekanisme yang dimaksudkan untuk itu /run. Oleh karena itu batas kejam pada program apa yang bisa diharapkan dari masa pakai apa pun dimasukkan /tmp. Sementara program dapat mengharapkan file untuk hidup lebih lama /runpada sistem yang terus-menerus naik, mereka juga diharapkan untuk merapikan diri mereka sendiri di sana.

dr01
sumber
4
Satu hal yang tidak ditunjukkan dalam jawaban ini atau lainnya, tetapi dicatat dalam FHS, dan yang Anda mungkin ingin meningkatkan jawaban Anda dengan: FHS memungkinkan untuk hal-hal seperti pengaturan konvensional pekerjaan cron yang secara teratur membersihkan /tmpfile "lama"; tanpa mekanisme yang dimaksudkan untuk itu /run. Oleh karena itu batas kejam pada program apa yang bisa diharapkan dari masa pakai apa pun dimasukkan /tmp. Sementara program dapat mengharapkan file untuk hidup lebih lama /runpada sistem yang terus-menerus naik, mereka juga diharapkan untuk merapikan diri mereka sendiri di sana.
JdeBP
1
Akan menyenangkan untuk memiliki direktori per-proses dari hal-hal yang hilang (atau diizinkan untuk dihapus oleh beberapa daemon sampah keliling) segera setelah proses mati.
Mahakuasa
1
@Omnifarious Anda sekarang bisa mendapatkan perilaku itu untuk layanan systemd, dengan menggunakan RuntimeDirectory = :-).
sourcejedi