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

Linux: add meter showing the current active user sessions #1364

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

cgzones
Copy link
Member

@cgzones cgzones commented Jan 9, 2024

Display the active user sessions either via systemd-logind or utmp.

Suggested in #1363.

@cgzones cgzones added Linux 🐧 Linux related issues FreeBSD 👹 FreeBSD related issues new feature Completely new feature labels Jan 9, 2024
@BenBE BenBE added this to the 3.4.0 milestone Jan 9, 2024
Copy link
Member

@BenBE BenBE left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What re OpenBSD/NetBSD/Solaris?

@fraggerfox Can you help here?

UserSessionsMeter.c Outdated Show resolved Hide resolved
UserSessionsMeter.c Outdated Show resolved Hide resolved
UserSessionsMeter.c Outdated Show resolved Hide resolved
@fraggerfox
Copy link
Contributor

What re OpenBSD/NetBSD/Solaris?

@fraggerfox Can you help here?

I can check this out in the coming weekend and see if I can make the changes work in NetBSD.

ret = updateViaUtmp();
#else
ret = updateViaUtmp();
#endif /* !BUILD_STATIC || HAVE_LIBSYSTEMD */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Can the systemd code depend only on HAVE_LIBSYSTEMD? People who build htop without systemd support would likely not want the systemd code even when it's dynamically loaded and linked.
  2. Code simplification suggestion:
   int ret = -1; // Or maybe -ENOSYS for better diagnostic message
#if defined(HAVE_LIBSYSTEMD)
   ret = update_via_sd_login();
#endif /* HAVE_LIBSYSTEMD */
   if (ret < 0)
      ret = updateViaUtmp();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. There is a systemd meter. Linking should be done accordingly as it's already done there.

  2. This looks a bit cleaner, but has a dead store in ret.

UserSessionsMeter.c Outdated Show resolved Hide resolved
@cgzones cgzones force-pushed the user_count branch 3 times, most recently from 9499ecb to e3f970c Compare January 10, 2024 16:27
Display the active user sessions either via systemd-logind or utmp.

On Linux try to query systemd-login first, and otherwise count only the
number of distinct sessions.  On other platforms the number of unique
sessions can not be determined and the number of all user entries are
returned.

Suggested in htop-dev#1363.
@cgzones
Copy link
Member Author

cgzones commented Jan 10, 2024

What re OpenBSD/NetBSD/Solaris?

According to manual pages only OpenBSD does have not support for it.

if (!found) {
ret++;

if (sessions_size +1 >= sessions_cap) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (sessions_size +1 >= sessions_cap) {
if (sessions_size + 1 >= sessions_cap) {

Comment on lines +26 to +29
#ifndef BUILD_STATIC
#include <dlfcn.h>
#include "linux/Platform.h"
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be a platform-specific reference in the platform-independent code section.

Comment on lines +107 to +116
int ret;
#if (!defined(BUILD_STATIC) && defined(HTOP_LINUX)) || defined(HAVE_LIBSYSTEMD)
ret = update_via_sd_login();
if (ret < 0)
ret = Generic_utmpx_get_users();
#else
ret = Generic_utmpx_get_users();
#endif /* (!BUILD_STATIC && HTOP_LINUX) || HAVE_LIBSYSTEMD */

users = ret;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this code into a platform-specific function. For everything aside from Linux this can be a direct forward to Generic_utmpx_get_users; on Linux that's mostly the above block of code.

Comment on lines +118 to +119
if (users >= 0) {
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%d", ret);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why distinguish here between ret and users?

int len = xSnprintf(buffer, sizeof(buffer), "%d", users);
RichString_appendnAscii(out, CRT_colors[METER_VALUE], buffer, len);
} else {
RichString_appendAscii(out, CRT_colors[METER_VALUE], "N/A");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe shadow the value if not available?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For meter text, I don't think shadowing is a good idea. IMHO.

static void* libsystemd_handle;
static size_t libsystemd_loaded;

void* Platform_load_libsystemd(void) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I write some ideas just in case you are planning to refactor this further:

  1. The LibSystemd init code can become its own C files, LibSystemd.c and LibSystemd.h. Within it the LibSystemd_init() function would perform what you have Platform_load_libsystemd() here. Look at the existing linux/LibSensors.c file for what I mean. Dynamically loaded libraries should have the init and unload functions like that.
  2. When a libsystemd handle has been dlopen'd, all the symbols htop requires should resolve all at once. No need to have the resolve() code in different places for the same library.
  3. Make the resolved function pointers publicly assessible. That is, put these in linux/LibSystemd.h when needed:
// In "linux/LibSystemd.h"
#ifdef BUILD_STATIC

#define sym_sd_bus_open_system sd_bus_open_system
#define sym_sd_bus_open_user sd_bus_open_user
#define sym_sd_bus_get_property_string sd_bus_get_property_string
#define sym_sd_bus_get_property_trivial sd_bus_get_prope
rty_trivial
#define sym_sd_bus_unref sd_bus_unref
#define sym_sd_get_sessions sd_get_sessions

#else

extern int (*sym_sd_bus_open_system)(sd_bus**);
extern int (*sym_sd_bus_open_user)(sd_bus**);
extern int (*sym_sd_bus_get_property_string)(sd_bus*, const char*, const char*, const char*, const char*, sd_bus_error*, char**);
extern int (*sym_sd_bus_get_property_trivial)(sd_bus*, const char*, const char*, const char*, const char*, sd_bus_error*, char, void*);
extern sd_bus* (*sym_sd_bus_unref)(sd_bus*);
extern int (*sym_sd_get_sessions)(char***);

#endif

@cgzones cgzones added the needs-rebase Pull request needs to be rebased and conflicts to be resolved label Jan 20, 2024
@cgzones cgzones marked this pull request as draft April 13, 2024 19:41
@cgzones cgzones removed this from the 3.4.0 milestone Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FreeBSD 👹 FreeBSD related issues Linux 🐧 Linux related issues needs-rebase Pull request needs to be rebased and conflicts to be resolved new feature Completely new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants