Skip to content

Commit

Permalink
Replace github.com/s-urbaniak/uevent.go with github.com/pilebones/go-…
Browse files Browse the repository at this point in the history
…udev/netlink

github.com/s-urbaniak/uevent.go is unable to handle errors from udev
netlik listener. It just panics.

Issue #155
  • Loading branch information
anatol committed Aug 13, 2022
1 parent 679d6d2 commit c6be5be
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 55 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ go 1.17
require (
github.com/anatol/clevis.go v0.0.0-20220328171009-4f94523e7d17
github.com/anatol/devmapper.go v0.0.0-20211210164347-f67e20c4e7f7
github.com/anatol/go-udev v0.0.0-20220806124306-5f28d899f64f
github.com/anatol/luks.go v0.0.0-20211210165108-5d9a15b4f614
github.com/anatol/smart.go v0.0.0-20220218195151-5ee9e8fa73f0
github.com/anatol/tang.go v0.0.0-20220401181244-14a5a12378ca
github.com/anatol/uevent.go v1.0.1-0.20210811163347-3e166d38c549
github.com/anatol/vmtest v0.0.0-20211215032353-afd7b1dd38ef
github.com/cavaliergopher/cpio v1.0.1
github.com/google/go-tpm v0.3.3
Expand Down
9 changes: 5 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ github.com/anatol/clevis.go v0.0.0-20220328171009-4f94523e7d17 h1:LvgvJVXupc8Jxv
github.com/anatol/clevis.go v0.0.0-20220328171009-4f94523e7d17/go.mod h1:bVIookcLF8+u6k6BwaAJwB/CyKbYRwUfDSF1hvdp8Bs=
github.com/anatol/devmapper.go v0.0.0-20211210164347-f67e20c4e7f7 h1:/7MxcPFdUY7VZFuLQ/qOaQhBzOE96mOtSAQKW9EvHj0=
github.com/anatol/devmapper.go v0.0.0-20211210164347-f67e20c4e7f7/go.mod h1:zrna3BRNXKHSyOiw0ynGV2ASklN+IQBl4A4J+mXghCY=
github.com/anatol/go-udev v0.0.0-20220806124306-5f28d899f64f h1:Dxki5W8sSFVyPkoYut11RXlIzouHVM5dX99qUL8xsGA=
github.com/anatol/go-udev v0.0.0-20220806124306-5f28d899f64f/go.mod h1:xM57GU8ntwu+q88yo/exYza/WG1fKGxhJUtvtebxdXg=
github.com/anatol/luks.go v0.0.0-20211210165108-5d9a15b4f614 h1:6nOeQoay/QVdEippGzfI9TxBTqPXV2EEfsY4jOBHJLc=
github.com/anatol/luks.go v0.0.0-20211210165108-5d9a15b4f614/go.mod h1:88QkZxTPcAlsKkZvVVTs8YMn2Avp5H5itbmFNjGusaY=
github.com/anatol/smart.go v0.0.0-20220218195151-5ee9e8fa73f0 h1:rnURfQKi7StDt+WxNWW0LSHZp4sexCTwV+QOFEEZJjg=
github.com/anatol/smart.go v0.0.0-20220218195151-5ee9e8fa73f0/go.mod h1:mPog5NmM5znyLbUO9WQPJ4xQdVtuHPptPavY0055POc=
github.com/anatol/tang.go v0.0.0-20220401181244-14a5a12378ca h1:60FgDd7iZj00Ggcm2VLkzRAuUSAMZrHqDcUqYApSG5A=
github.com/anatol/tang.go v0.0.0-20220401181244-14a5a12378ca/go.mod h1:eehwvW8/vkT20kR75KYthbNZYCXyQVt4T6XGSLplJQ0=
github.com/anatol/uevent.go v1.0.1-0.20210811163347-3e166d38c549 h1:CPuCjtWK5UI9KQPDhylGHfZe7Pp8j58WK7i3wpLemA0=
github.com/anatol/uevent.go v1.0.1-0.20210811163347-3e166d38c549/go.mod h1:yO7hm0VhhOujsh+j0nn8ExPhAqIJh50MZOcKetKhAPA=
github.com/anatol/vmtest v0.0.0-20211215032353-afd7b1dd38ef h1:YQzm9r8/ArTsQ6C3/h+w4Dz5dfkYkQbK/3ETLWW2i7Q=
github.com/anatol/vmtest v0.0.0-20211215032353-afd7b1dd38ef/go.mod h1:JiDFhD1zjgMx9ONsHhhucGwMvCLrJMl/yu/l5qP4XFw=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
Expand Down Expand Up @@ -108,11 +108,11 @@ github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
Expand Down Expand Up @@ -158,6 +158,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
Expand Down
2 changes: 2 additions & 0 deletions init/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ func switchRoot() error {

// Cleanup the state before handing off the machine to the new init
func cleanup() {
close(udevQuitLoop)
udevConn.Close()
shutdownNetwork()
}

Expand Down
101 changes: 52 additions & 49 deletions init/udev.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@ package main

import (
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/anatol/devmapper.go"
"github.com/anatol/uevent.go"
"github.com/anatol/go-udev/netlink"
"golang.org/x/sys/unix"
)

// validDmEvent checks whether this udev event has correct flags.
// This is similar to checks done by /usr/lib/udev/rules.d/10-dm.rules udev rules.
func validDmEvent(ev *uevent.Uevent) bool {
dmCookie := ev.Vars["DM_COOKIE"]
func validDmEvent(ev netlink.UEvent) bool {
dmCookie := ev.Env["DM_COOKIE"]
if dmCookie == "" {
info("udev event does not contain DM_COOKIE")
return false
Expand Down Expand Up @@ -62,57 +61,61 @@ func validDmEvent(ev *uevent.Uevent) bool {
return true
}

var udevReader io.ReadCloser
var (
udevQuitLoop chan struct{}
udevConn *netlink.UEventConn
)

func udevListener() error {
defer func() {
// uevent.NewDecoder uses bufio.ReadString() that is blocking. If we try to close the underlying udev file descriptor
// while bufio tries to read from it then bufio panics. See issues #22, #31 and #153
// There is no clear way to prevent the panic so we just recover from it here and then safely exit the goroutine.
if r := recover(); r != nil {
warning("recovered udevListener panic: %v", r)
}
}()

var err error
udevReader, err = uevent.NewReader()
if err != nil {
return err
udevConn = new(netlink.UEventConn)
if err := udevConn.Connect(netlink.KernelEvent); err != nil {
return fmt.Errorf("unable to connect to Netlink Kobject UEvent socket")
}
defer udevReader.Close()
defer udevConn.Close()

dec := uevent.NewDecoder(udevReader)
queue := make(chan netlink.UEvent)
errors := make(chan error)
udevQuitLoop = udevConn.Monitor(queue, errors, nil)

exit:
for {
ev, err := dec.Decode()
if err == io.EOF {
// EOF is returned if uevent reader is closed concurrently
return nil
}
if err != nil {
return err
}
debug("udev event %+v", *ev)

// TODO: run each udev in a separate goroutine
if modalias, ok := ev.Vars["MODALIAS"]; ok {
go func() { check(loadModalias(modalias)) }()
} else if ev.Subsystem == "block" {
go func() { check(handleBlockDeviceUevent(ev)) }()
} else if ev.Subsystem == "net" {
go func() { check(handleNetworkUevent(ev)) }()
} else if ev.Subsystem == "hidraw" && ev.Action == "add" {
go func() { hidrawDevices <- ev.Vars["DEVNAME"] }()
select {
case ev, ok := <-queue:
if !ok {
break exit
}
handleUdevEvent(ev)
case err, ok := <-errors:
if !ok {
break exit
}
warning("udev: %+v", err)
}
}

return nil
}

func handleUdevEvent(ev netlink.UEvent) {
debug("udev event %+v", ev)

if modalias, ok := ev.Env["MODALIAS"]; ok {
go func() { check(loadModalias(modalias)) }()
} else if ev.Env["SUBSYSTEM"] == "block" {
go func() { check(handleBlockDeviceUevent(ev)) }()
} else if ev.Env["SUBSYSTEM"] == "net" {
go func() { check(handleNetworkUevent(ev)) }()
} else if ev.Env["SUBSYSTEM"] == "hidraw" && ev.Action == "add" {
go func() { hidrawDevices <- ev.Env["DEVNAME"] }()
}
}

func handleNetworkUevent(ev *uevent.Uevent) error {
func handleNetworkUevent(ev netlink.UEvent) error {
if ev.Action != "add" {
return nil
}

ifname := ev.Vars["INTERFACE"]
ifname := ev.Env["INTERFACE"]
if ifname == "lo" {
return nil
}
Expand All @@ -127,8 +130,8 @@ func handleNetworkUevent(ev *uevent.Uevent) error {

var dmNameRe = regexp.MustCompile(`dm-\d+`)

func handleBlockDeviceUevent(ev *uevent.Uevent) error {
devName := ev.Vars["DEVNAME"]
func handleBlockDeviceUevent(ev netlink.UEvent) error {
devName := ev.Env["DEVNAME"]

if dmNameRe.MatchString(devName) {
// mapper devices should not be added on "add" uevent
Expand All @@ -146,10 +149,10 @@ func handleBlockDeviceUevent(ev *uevent.Uevent) error {

devPath := "/dev/" + devName

isPartition := ev.Vars["DEVTYPE"] == "partition"
isPartition := ev.Env["DEVTYPE"] == "partition"
if isPartition {
// if this device represents a partition inside a table (like GPT) then wait till the table is processed
parts := strings.Split(ev.Devpath, "/")
parts := strings.Split(ev.KObj, "/")
tablePath := "/dev/" + parts[len(parts)-2]
waitForDeviceToProcess(tablePath)
}
Expand All @@ -160,14 +163,14 @@ func handleBlockDeviceUevent(ev *uevent.Uevent) error {
// handleMapperDeviceUevent handles device mapper related uevent
// if udev event is valid then it return non-empty string that contains
// new mapper device name (e.g. /dev/mapper/name)
func handleMapperDeviceUevent(ev *uevent.Uevent) error {
devName := ev.Vars["DEVNAME"]
func handleMapperDeviceUevent(ev netlink.UEvent) error {
devName := ev.Env["DEVNAME"]

major, err := strconv.Atoi(ev.Vars["MAJOR"])
major, err := strconv.Atoi(ev.Env["MAJOR"])
if err != nil {
return fmt.Errorf("udev['MAJOR']: %v", err)
}
minor, err := strconv.Atoi(ev.Vars["MINOR"])
minor, err := strconv.Atoi(ev.Env["MINOR"])
if err != nil {
return fmt.Errorf("udev['MAJOR']: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func TestVfio(t *testing.T) {
require.Contains(t, dmesg, "vfio_pci: add [1002:67df[ffffffff:ffffffff]] class 0x000000/00000000", "expecting vfio_pci 1002:67df device")
require.Contains(t, dmesg, "vfio_pci: add [1002:aaf0[ffffffff:ffffffff]] class 0x000000/00000000", "expecting vfio_pci 1002:aaf0 device")

re := regexp.MustCompile(`booster: udev event {Header:add@/bus/pci/drivers/vfio-pci Action:add Devpath:/bus/pci/drivers/vfio-pci Subsystem:drivers Seqnum:\d+ Vars:map\[ACTION:add DEVPATH:/bus/pci/drivers/vfio-pci SEQNUM:\d+ SUBSYSTEM:drivers]}`)
re := regexp.MustCompile(`booster: udev event {Action:add KObj:/bus/pci/drivers/vfio-pci Env:map\[ACTION:add DEVPATH:/bus/pci/drivers/vfio-pci SEQNUM:\d+ SUBSYSTEM:drivers]}`)
require.Regexp(t, re, dmesg, "expecting vfio_pci module loading udev event")
}

Expand Down

0 comments on commit c6be5be

Please sign in to comment.