Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return an error if udev is not running/available #858

Open
bmr-cymru opened this issue May 25, 2023 · 2 comments
Open

Return an error if udev is not running/available #858

bmr-cymru opened this issue May 25, 2023 · 2 comments
Assignees

Comments

@bmr-cymru
Copy link
Member

Currently if the systemd-udevd daemon is not running or is unable to respond to uevents the udev synchronization code in devicemapper will hang indefinitely:

[2023-05-25T12:04:11Z DEBUG devicemapper::core::dm] Resuming device stratis-1-private-e00449c6a59b43e48a1187473064225d-physical-originsub
[2023-05-25T12:04:11Z DEBUG devicemapper::core::dm_udev_sync::sync_semaphore] Created UdevSync { cookie: 5114325, semid: 0 }
[2023-05-25T12:04:11Z TRACE devicemapper::core::dm_udev_sync::sync_semaphore] Waiting on UdevSync { cookie: 5114325, semid: Some(0) }
<< blocks here >>

It would be better to test the state of udev and to report an error like "The udev daemon is not running".

The libdevmapper library detects this state by calling the udev API:

static int _check_udev_is_running(void)
{
        struct udev *udev;
        struct udev_queue *udev_queue;
        int r;

        if (!(udev = udev_new()))
                goto_bad;

        if (!(udev_queue = udev_queue_new(udev))) {
                udev_unref(udev);
                goto_bad;
        }

        if (!(r = udev_queue_get_udev_is_active(udev_queue)))
                log_debug_activation("Udev is not running. "
                                     "Not using udev synchronisation code.");

        udev_queue_unref(udev_queue);
        udev_unref(udev);

        return r;

bad:
        log_error("Could not get udev state. Assuming udev is not running.");
        return 0;
}

There are Rust bindings for libudev available so we can potentially implement the same check in devicemapper.

@bmr-cymru
Copy link
Member Author

Looking at libudev-rs it does not seem to implement the queue API that is required for the check, so that may be a dead end.

@bmr-cymru
Copy link
Member Author

Looking at libudev sources the check that libdevmapper is doing actually amounts to:

_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) {
        return access("/run/udev/control", F_OK) >= 0;
}

And indeed when we hit the problem in emergency.target that socket is absent.

@bmr-cymru bmr-cymru self-assigned this May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant