In our example we will use libvirt VM with Container Linux and run systemd unit on disk attach event. First of all we have to create systemd unit file /etc/systemd/system/device-attach.service:
[Service]
Type=oneshot
ExecStart=/usr/bin/echo 'device has been attached'
This unit file will be triggered by our udev rule.
Then we have to start udevadm monitor --environment to monitor kernel events.
Once you've attached virtio libvirt device (i.e. virsh attach-disk coreos /dev/VG/test vdc) you'll see similar udevadm output:
UDEV [545.954641] add /devices/pci0000:00/0000:00:18.0/virtio4/block/vdb (block)
.ID_FS_TYPE_NEW=
ACTION=add
DEVNAME=/dev/vdb
DEVPATH=/devices/pci0000:00/0000:00:18.0/virtio4/block/vdb
DEVTYPE=disk
ID_FS_TYPE=
MAJOR=254
MINOR=16
SEQNUM=1327
SUBSYSTEM=block
USEC_INITIALIZED=545954447
According to text above udev generates event which contains directives (ACTION=add and SUBSYSTEM=block) we will use in our rule. It should look this way:
ACTION=="add", SUBSYSTEM=="block", TAG+="systemd", ENV{SYSTEMD_WANTS}="device-attach.service"
That rule means that udev will trigger device-attach.service systemd unit on any block device attachment. Now when we use this command virsh attach-disk coreos /dev/VG/test vdc on host machine, we should see device has been attached message in Container Linux node's journal. This example should be similar to USB/SAS/SATA device attach.
To use the unit and udev rule with a Container Linux Config, modify this example as needed:
# This config is meant to be consumed by the config transpiler, which will
# generate the corresponding Ignition config. Do not pass this config directly
# to instances of Container Linux.
storage:
files:
- path: /etc/udev/rules.d/01-block.rules
filesystem: root
mode: 0644
contents:
inline: |
ACTION=="add", SUBSYSTEM=="block", TAG+="systemd", ENV{SYSTEMD_WANTS}="device-attach.service"
systemd:
units:
- name: device-attach.service
contents: |
[Unit]
Description=Notify about attached device
[Service]
Type=oneshot
ExecStart=/usr/bin/echo 'device has been attached'
{
"ignition": {
"config": {},
"timeouts": {},
"version": "2.1.0"
},
"networkd": {},
"passwd": {},
"storage": {
"files": [
{
"filesystem": "root",
"group": {},
"path": "/etc/udev/rules.d/01-block.rules",
"user": {},
"contents": {
"source": "data:,ACTION%3D%3D%22add%22%2C%20SUBSYSTEM%3D%3D%22block%22%2C%20TAG%2B%3D%22systemd%22%2C%20ENV%7BSYSTEMD_WANTS%7D%3D%22device-attach.service%22%0A",
"verification": {}
},
"mode": 420
}
]
},
"systemd": {
"units": [
{
"contents": "[Unit]\nDescription=Notify about attached device\n\n[Service]\nType=oneshot\nExecStart=/usr/bin/echo 'device has been attached'",
"name": "device-attach.service"
}
]
}
}
For more systemd examples, check out these documents:
Customizing Docker Customizing the SSH Daemon Using systemd Drop-In Units
systemd.service Docs systemd.unit Docs systemd.target Docs udev Docs