diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
index 4bdb5c3e9e..9bc866dc68 100644
--- a/man/sd_get_seats.xml
+++ b/man/sd_get_seats.xml
@@ -46,7 +46,8 @@
sd_get_seats
sd_get_sessions
sd_get_uids
- Determine available seats, sessions and logged in users
+ sd_get_machine_names
+ Determine available seats, sessions, logged in users and virtual machines/containers
@@ -68,6 +69,11 @@
uid_t** users
+
+ int sd_get_machine_names
+ char*** machines
+
+
@@ -90,6 +96,11 @@
Similar, sd_get_uids() may
be used to determine all Unix users who currently have login sessions.
+ Similar,
+ sd_get_machine_names() may be
+ used to determine all current virtual machines and
+ containers on the system.
+
Note that the returned lists are not sorted and in an undefined order.
@@ -97,18 +108,20 @@
Return Value
On success sd_get_seats(),
- sd_get_sessions() and
- sd_get_uids() return the number
- of entries in the arrays. On failure, these calls
- return a negative errno-style error code.
+ sd_get_sessions(),
+ sd_get_uids() and
+ sd_get_machine_names() return the
+ number of entries in the arrays. On failure, these
+ calls return a negative errno-style error code.
Notes
The sd_get_seats(),
- sd_get_sessions() and
- sd_get_uids() interfaces
+ sd_get_sessions(),
+ sd_get_uids() and
+ sd_get_machine_names() interfaces
are available as shared library, which can be compiled
and linked to with the
libsystemd-login
diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
index f4cd209700..925fb91095 100644
--- a/src/login/libsystemd-login.sym
+++ b/src/login/libsystemd-login.sym
@@ -70,3 +70,8 @@ global:
sd_pid_get_user_unit;
sd_pid_get_machine_name;
} LIBSYSTEMD_LOGIN_201;
+
+LIBSYSTEMD_LOGIN_203 {
+global:
+ sd_get_machine_names;
+} LIBSYSTEMD_LOGIN_202;
diff --git a/src/login/sd-login.c b/src/login/sd-login.c
index 157b7e0fb4..35deb85f2d 100644
--- a/src/login/sd-login.c
+++ b/src/login/sd-login.c
@@ -591,6 +591,43 @@ _public_ int sd_get_uids(uid_t **users) {
return r;
}
+int sd_get_machine_names(char ***machines) {
+ _cleanup_closedir_ DIR *d = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ _cleanup_free_ char *md = NULL;
+ char *n;
+ int c = 0, r;
+
+ r = cg_get_machine_path(&md);
+ if (r < 0)
+ return r;
+
+ r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, md, &d);
+ if (r < 0)
+ return r;
+
+ while ((r = cg_read_subgroup(d, &n)) > 0) {
+
+ r = strv_push(&l, n);
+ if (r < 0) {
+ free(n);
+ return -ENOMEM;
+ }
+
+ c++;
+ }
+
+ if (r < 0)
+ return r;
+
+ if (machines) {
+ *machines = l;
+ l = NULL;
+ }
+
+ return c;
+}
+
static inline int MONITOR_TO_FD(sd_login_monitor *m) {
return (int) (unsigned long) m - 1;
}
diff --git a/src/login/test-login.c b/src/login/test-login.c
index e4d0c93378..945cb38be9 100644
--- a/src/login/test-login.c
+++ b/src/login/test-login.c
@@ -35,7 +35,7 @@ int main(int argc, char* argv[]) {
char *state;
char *session2;
char *t;
- char **seats, **sessions;
+ char **seats, **sessions, **machines;
uid_t *uids;
unsigned n;
struct pollfd pollfd;
@@ -180,10 +180,18 @@ int main(int argc, char* argv[]) {
printf("n_uids = %i\n", r);
assert_se(sd_get_uids(NULL) == r);
+ r = sd_get_machine_names(&machines);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(machines));
+ assert_se(t = strv_join(machines, ", "));
+ strv_free(machines);
+ printf("n_machines = %i\n", r);
+ printf("machines = %s\n", t);
+ free(t);
+
r = sd_login_monitor_new("session", &m);
assert_se(r >= 0);
-
for (n = 0; n < 5; n++) {
usec_t timeout, nw;
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
index 1083742beb..2415039410 100644
--- a/src/systemd/sd-login.h
+++ b/src/systemd/sd-login.h
@@ -150,6 +150,9 @@ int sd_get_sessions(char ***sessions);
* users. If users is NULL only returns the number of users. */
int sd_get_uids(uid_t **users);
+/* Get all running virtual machines/containers */
+int sd_get_machine_names(char ***machines);
+
/* Monitor object */
typedef struct sd_login_monitor sd_login_monitor;