9.11. Hot Plugging: hotplug
Subsistem kernel hotplug secara dinamis menangani penambahan dan penghapusan perangkat, dengan memuat driver yang sesuai dan membuat berkas-berkas peranti yang sesuai (dengan bantuan udevd
). Dengan perangkat keras modern dan virtualisasi, hampir semuanya dapat di-hotplug: dari periferal PCMCIA/USB/IEEE 1394 yang biasa sampai hard drive SATA, tetapi juga CPU dan memori.
Kernel memiliki basis data yang mengaitkan setiap ID perangkat dengan driver yang diperlukan. Basis data ini digunakan selama boot untuk memuat semua driver untuk perangkat periferal yang terdeteksi pada bus berbeda, tetapi juga ketika perangkat tambahan hotplug terhubung. Setelah perangkat siap untuk digunakan, pesan dikirim ke udevd
sehingga akan dapat membuat entri yang sesuai di /dev/
.
Sebelum munculnya koneksi hotplug, mudah untuk memberikan sebuah nama tetap ke suatu perangkat. Hal ini didasarkan hanya pada posisi perangkat di bus mereka masing-masing. Tetapi hal ini tidak mungkin ketika perangkat tersebut dapat datang dan pergi pada bus. Kasus khas adalah menggunakan kamera digital dan USB flash drive, keduanya muncul ke komputer sebagai disk drive. Yang pertama yang terhubung mungkin akan/dev/sdb
dan yang kedua /dev/sdc
(dengan /dev/sda
mewakili hard drive komputer sendiri). Nama perangkat tidak tetap; itu tergantung pada urutan terhubungnya perangkat.
Selain itu, driver lebih dan lebih banyak menggunakan nilai-nilai yang dinamis untuk nomor mayor/minor perangkat, yang membuat tidak mungkin untuk memiliki entri statis untuk perangkat tertentu, karena karakteristik penting ini dapat bervariasi setelah reboot.
udev diciptakan justru untuk memecahkan masalah ini.
9.11.3. Bagaimana udev Bekerja
Ketika udev diberitahu oleh kernel atas kemunculan perangkat baru, itu mengumpulkan berbagai informasi pada perangkat tersebut dengan memeriksa entri terkait di /sys/
, terutama mereka yang secara unik mengidentifikasinya (Alamat MAC kartu jaringan, nomor seri untuk beberapa perangkat USB, dll.).
Dipersenjatai dengan semua informasi ini, udev kemudian berkonsultasi menjalani seluruh aturan yang terkandung dalam /etc/udev/rules.d/
dan /lib/udev/rules.d/
. Dalam prosesnya ini memutuskan bagaimana menamai perangkat, taut simbolik apa yang dibuat (untuk memberinya nama alternatif), dan perintah apa yang dieksekusi. Semua berkas ini diperiksa, dan aturan semua dievaluasi secara berurutan (kecuali ketika berkas menggunakan direktif "GOTO"). Dengan demikian, mungkin ada beberapa aturan yang sesuai untuk kejadian tertentu.
Sintaks berkas aturan ini cukup sederhana: setiap baris berisi kriteria pemilihan dan penetapan variabel. Yang terdahulu digunakan untuk memilih kejadian yang perlu ada reaksi, dan yang belakangan mendefinisikan tindakan yang akan diambil. Mereka semua hanya dipisahkan dengan koma, dan operator secara implisit membedakan antara kriteria seleksi (dengan operator perbandingan, seperti ==
atau !=
) atau direktif penugasan (dengan operator seperti =
, +=
, atau :=
).
Operator perbandingan yang digunakan pada variabel berikut:
KERNEL
: nama yang deberikan oleh kernel ke perangkat;
AKSI
: tindakan yang sesuai untuk acara ("add" ketika perangkat telah ditambahkan, "remove" ketika dihapus);
DEVPATH
: path entri /sys/
perangkat;
SUBSYSTEM
: subsistem kernel yang menghasilkan permintaan (ada banyak, tapi beberapa contoh adalah "usb", "ide", "net", "firmware", dll.);
ATTR {atribut}
: isi berkas dari atribut dalam direktori /sys/ $devpath/
perangkat. Ini adalah tempat Anda menemukan alamat MAC dan pengenal khusus bus lain;
KERNELS
, SUBSYSTEM
, dan ATTRS {atribut}
adalah variasi yang akan mencoba untuk mencocokkan pilihan yang berbeda pada salah satu perangkat induk dari perangkat saat ini;
PROGRAM
: mendelegasikan tes ke program ditunjukkan (true jika ia mengembalikan 0, false jika tidak). Isi dari keluaran standar program disimpan sehingga dapat digunakan kembali oleh uji RESULT
;
RESULT
: menjalankan tes pada keluaran standar yang disimpan selama pemanggilan terakhir ke PROGRAM
.
Operand kanan dapat menggunakan ekspresi pola untuk mencocokkan beberapa nilai pada waktu yang sama. Sebagai contoh, *
cocok dengan string apapun (bahkan yang kosong); ?
cocok dengan sebarang karakter, dan []
sesuai set karakter yang tercantum antara kurung (atau lawan dari itu jika karakter pertama adalah tanda seru, dan rentang karakter berturutan dituliskan seperti a-z
).
Mengenai penetapan operator, =
memberikan nilai (dan menggantikan nilai saat ini); dalam kasus sebuah daftar, itu dikosongkan dan mengandung hanya nilai yang diberikan. :=
melakukan hal yang sama, tetapi mencegah perubahan belakangan atas variabel yang sama. Adapun +=
, menambahkan item ke daftar. Variabel berikut dapat diubah:
NAME
: nama berkas perangkat yang akan dibuat di /dev/
. Hanya penugasan pertama yang penting; yang lain diabaikan;
SYMLINK
: daftar taut simbolik yang akan mengarah ke perangkat yang sama;
OWNER
, GROUP
, dan MODE
menentukan pengguna dan kelompok yang memiliki perangkat, serta izin terkait;
RUN
: daftar program-program yang akan dijalankan sebagai respon atas kejadian ini.
Nilai-nilai yang ditugaskan ke variabel ini dapat menggunakan sejumlah substitusi:
$kernel
atau %k
: setara dengan KERNEL
;
$number
atau %n
: nomor urut perangkat, misalnya, untuk sda3
, itu akan "3";
$devpath
atau %p
: setara dengan DEVPATH
;
$attr{atribut}
atau %s{atribut}
: setara dengan ATTRS {atribut}
;
$major
atau %M
: nomor mayor kernel dari perangkat;
$minor
atau %m
: nomor minor kernel dari perangkat;
$result
atau %c
: string keluaran dari program yang terakhir dipanggil oleh PROGRAM
;
dan, akhirnya, %%
dan $$
masing-masing untuk persen dan tanda dolar.
Daftar di atas ini tidak lengkap (mereka hanya menyertakan parameter-parameter terpenting), tetapi halaman manual udev(7) harus lengkap.
Mari kita mempertimbangkan kasus kunci USB sederhana dan mencoba memberikan sebuah nama tetap. Pertama, Anda harus menemukan unsur-unsur yang akan mengidentifikasi secara unik. Untuk ini, tancapkan itu dan jalankan udevadm info -a -n /dev/sdc
(menggantikan /dev/sdc dengan nama sebenarnya yang ditetapkan ke kunci).
#
udevadm info -a -n /dev/sdc
[...]
looking at device '/devices/pci0000:00/0000:00:10.0/usb2/2-1/2-1:1.0/host4/target4:0:0/4:0:0:0/block/sdc':
KERNEL=="sdc"
SUBSYSTEM=="block"
DRIVER==""
ATTR{hidden}=="0"
ATTR{events}=="media_change"
ATTR{ro}=="0"
ATTR{discard_alignment}=="0"
ATTR{removable}=="1"
ATTR{events_async}==""
ATTR{alignment_offset}=="0"
ATTR{capability}=="51"
ATTR{events_poll_msecs}=="-1"
ATTR{stat}=="130 0 6328 435 0 0 0 0 0 252 252 0 0 0 0"
ATTR{size}=="15100224"
ATTR{range}=="16"
ATTR{ext_range}=="256"
ATTR{inflight}=="0 0"
[...]
looking at parent device '/devices/pci0000:00/0000:00:10.0/usb2/2-1/2-1:1.0/host4/target4:0:0/4:0:0:0':
[...]
ATTRS{max_sectors}=="240"
[...]
looking at parent device '/devices/pci0000:00/0000:00:10.0/usb2/2-1':
KERNELS=="2-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumInterfaces}==" 1"
ATTRS{busnum}=="2"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{ltm_capable}=="no"
ATTRS{speed}=="480"
ATTRS{product}=="TF10"
ATTRS{manufacturer}=="TDK LoR"
[...]
ATTRS{serial}=="07032998B60AB777"
[...]
Untuk membuat aturan baru, Anda dapat menggunakan tes pada variabel perangkat, maupun dari salah satu perangkat induk. Kasus di atas memungkinkan kita untuk membuat dua aturan seperti ini:
KERNEL=="sd?", SUBSYSTEM=="block", ATTRS{serial}=="07032998B60AB777", SYMLINK+="usb_key/disk"
KERNEL=="sd?[0-9]", SUBSYSTEM=="block", ATTRS{serial}=="07032998B60AB777", SYMLINK+="usb_key/part%n"
Setelah aturan-aturan ini ditetapkan dalam berkas, bernama sebagai contoh /etc/udev/rules.d/010_local.rules
, Anda dapat mencabut dan menancapkan kembali kunci USB. Anda dapat melihat bahwa /dev/usb_key/disk
mewakili disk terkait kunci USB, dan /dev/usb_key/part1
adalah partisi pertamanya.