-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Use logind instead of utmp because of Y2038 #2300
base: master
Are you sure you want to change the base?
Conversation
This approach is using macros to share the code, but maybe is cleaner if the function is split in two: one for utmp and other for logind. Is there any preference? |
50d5199
to
89b2d18
Compare
Mmmm... what a tricky problem. In order to reproduce the problem I've tried setting the system time to year 2050, then calling
How about the other platforms? Are they affected as well?
|
Uhm ... try to set the date and reboot. IIUC the issue is when the As you can see the
It is a glibc issue, so that depends if they are using the same struct with
That is the one that I fixed here! : ) For the rest of the platforms, if they are affected (not sure about that), this solution is not applicable as it depends on systemd. |
Some more documentation why this is necessary: So for linux using systemd, coreutils. procps-ng, shadow, util-linux and more already implemented support to use logind instead of utmp or accepted PRs for this. |
If binaries / wheels are produced with systemd support, but the Linux system installing the wheel doesn't have systemd, are we sure that this patch won't cause a I remember we had a similar problem with I'm not sure if the same problem may arise here as well. Are there Linux distros without systemd support and / or where |
It will produce this error indeed. One solution can be what you describes:
Would this a preferred approach? |
Yes, ctypes sounds like the safest bet at the time of writing, but it has a cost: slower speed + extra and convoluted code to maintain (I am also thinking about the dual unit tests). I am skeptical how much of a problem this is in reality. Who sets the system date to >= 2035? If done, it looks like a user error. After setting the system date to 2050 all my browser tabs automatically logged out and I could not establish new HTTPS connections, so basically a system with a date that far in the future is not usable in general. |
It will happen automatically in < I mean, the issue to fix is not that an user will set the date to 2050 by accident or because a specific use case, it is that a system that will be build in the next Edit: math is hard |
On a second thought I think that |
af91ac8
to
20fe497
Compare
@giampaolo I updated the PR using dlopen(). Now there is no link to libsystemd, so a Linux system without the library will no produce the error of the missing symbol. Those are now dynamically loaded. |
@giampaolo ping? |
@giampaolo did you have a chance to evaluate the new approach here? Meanwhile we added in openSUSE the patch in the package |
Hi there.
I'm afraid this is the case only if you install psutil from sources. In the C code you do: #ifdef SYSTEMD_LINUX
#include <dlfcn.h>
#endif ...but You should somehow avoid the |
Yes. Dropped. |
But now that I recall ... this part is not true. If the library is not present in the system, the The new macro The SYSTEMD_LINUX condition is used only to remove this part in case that we want a source code that never checks for systemd. So, the confusion matrix is like this (C = Compile time; R = At runtime; S = Systemd is present; N = No systemd present)
I re-added it for now to have the same code-base for discussion. We can drop all the systemd checks and make the systemd code path always present (with the fallback to utmp) but the reason will not be for avoiding the "symbol not found" error, as it is already not present. |
I'm confused now. :) Can you commit the "final" code? |
Also can you please avoid to squash commits and force push? It's more clear to see the individual commits and how they evolve. |
Done, I also rebased on top of the aplanas-utmp branch, that contains your code |
From Github CI https://github.com/giampaolo/psutil/actions/runs/6614641177/job/17968190988?pr=2300:
This means that the new code is currently not tested. I also cannot test it locally on Ubuntu 22.04 for the same reason (missing 'sd_session_get_leader'). What distro are you on? Can you run |
openSUSE Tumbleweed, but I guess Arch will also have the systemd v254 there.
That fails a lot. Some of the fails are assumptions about partitions, mount points (I am using btrfs with subvolumes, etc). But from the one that is related with this PR I see one:
|
I tried playing with it a bit more and other than |
All those are already present in v254 |
Let's not rush this. Considering these new APIs are literally 5 months old, it seems unlikely to me that we may cause issues to long-term support distros if we don't do this right now. We don't have to wait years, but the minimum requirement here should be that the default Github Linux image has systemd >= v254, so that both utmp and systemd code paths are covered by unit tests. We can leave this PR open 'till then. In the meantime, another couple of suggestions I can give for this PR:
|
FYI I did this in 0c3a1c5, so you need to update your branch again. |
Bi-arch systems line x86-64 present the Y2038 problem, where an overflow can be produced because some glibc compatibility decissions (see https://github.com/thkukuk/utmpx/blob/main/Y2038.md for more information) This patch uses logind from systemd instead of utmp on Linux systems, if the systemd version is support the new API (>= 254). Signed-off-by: Alberto Planas <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
Signed-off-by: Giampaolo Rodola <[email protected]>
Signed-off-by: Giampaolo Rodola <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
This will leak the handle, as the dlclose() cannot be called. Would this be OK? |
Mmm no I don't think so. It will slightly increase memory usage the first time it's called, then it will just stay loaded in memory until the python process is terminated. The important thing is not to open a new handle on each call. |
Done. |
@giampaolo I found what I think is a bug: if there is an error in the _utmp or _systemd version it will return NULL without setting the exception. The last commit is addressing this |
The test is also fixed: the issue was not code related. For now I will partially update the patch living in the openSUSE package, and we will revisit this PR in some time in the future then. Thanks a lot for the detailed review and all your patience working with me. |
Signed-off-by: Alberto Planas <[email protected]>
Signed-off-by: Alberto Planas <[email protected]>
There's one last thing. From the man page https://manpages.debian.org/testing/libsystemd-dev/sd_session_get_username.3.en.html:
Right now on failure we get #include <stdlib.h> // abs()
void set_systemd_errno(const char *syscall, int neg_errno) {
PyObject *exc;
int pos_errno;
pos_errno = abs(neg_errno);
sprintf(
fullmsg, "%s (originated from %s)", strerror(pos_errno), syscall
);
exc = PyObject_CallFunction(PyExc_OSError, "(is)", pos_errno, fullmsg);
PyErr_SetObject(PyExc_OSError, exc);
Py_XDECREF(exc);
}
PyObject *
psutil_users_systemd(PyObject *self, PyObject *args) {
int ret;
...
ret = sd_session_get_username(session_id, &username);
if (ret < 0) {
set_systemd_errno("sd_session_get_username", ret);
goto error;
}
error:
...
return NULL; // NOT RuntimeError |
Signed-off-by: Alberto Planas <[email protected]>
Adapted the code and tested it a bit. Done. |
Summary
Description
Bi-arch systems line x86-64 present the Y2038 problem, where an overflow can be produced because some glibc compatibility decissions (see https://github.com/thkukuk/utmpx/blob/main/Y2038.md for more information)
This patch uses logind from systemd instead of utmp on Linux systems, if the systemd version is support the new API (>= 254).