11/* SPDX-License-Identifier: LGPL-2.1-or-later */
2-
32#include <assert.h>
43#include <stdbool.h>
54#include <string.h>
6-
75#include "hashmap.h"
86#include "install.h"
97#include "json-util.h"
1614#include "unit-def.h"
1715#include "varlink-metrics.h"
1816
19- static int unit_states_total_build_json_one (
17+ static int units_by_state_total_build_json_one (
2018 sd_varlink * link ,
2119 UnitActiveState state ,
2220 unsigned count ,
@@ -27,13 +25,12 @@ static int unit_states_total_build_json_one(
2725 assert (link );
2826
2927 r = METRIC_JSON_BUILD_UNSIGNED (
30- & v ,
31- METRIC_IO_SYSTEMD_MANAGER_UNIT_STATES_TOTAL ,
32- /* object= */ NULL ,
33- count ,
34- /* fields */
35- "state" ,
36- unit_active_state_to_string (state ));
28+ & v ,
29+ METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_STATE_TOTAL ,
30+ /* object= */ NULL ,
31+ count ,
32+ /* fields */ "state" ,
33+ unit_active_state_to_string (state ));
3734 if (r < 0 )
3835 return r ;
3936
@@ -43,7 +40,29 @@ static int unit_states_total_build_json_one(
4340 return sd_varlink_reply (link , v );
4441}
4542
46- static int unit_types_total_build_json_one (sd_varlink * link , Manager * manager , UnitType * type , bool more ) {
43+ static int units_by_state_total_build_json (sd_varlink * link , void * userdata , bool more ) {
44+ int r ;
45+ Manager * manager = ASSERT_PTR (userdata );
46+
47+ assert (link );
48+
49+ r = units_by_state_total_build_json_one (
50+ link ,
51+ UNIT_ACTIVE ,
52+ hashmap_size (manager -> units ),
53+ more );
54+
55+ if (r < 0 )
56+ return r ;
57+
58+ return units_by_state_total_build_json_one (
59+ link ,
60+ UNIT_FAILED ,
61+ set_size (manager -> failed_units ),
62+ more );
63+ }
64+
65+ static int units_by_type_total_build_json_one (sd_varlink * link , Manager * manager , UnitType * type , bool more ) {
4766 int r ;
4867 unsigned count = 0 ;
4968 _cleanup_ (sd_json_variant_unrefp ) sd_json_variant * v = NULL ;
@@ -58,11 +77,11 @@ static int unit_types_total_build_json_one(sd_varlink *link, Manager *manager, U
5877
5978 r = METRIC_JSON_BUILD_UNSIGNED (
6079 & v ,
61- METRIC_IO_SYSTEMD_MANAGER_UNIT_TYPES_TOTAL ,
80+ METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_TYPE_TOTAL ,
6281 /* object= */ NULL ,
6382 count ,
64- /* fields */
65- "type" , unit_type_to_string (* type ));
83+ /* fields */ "type" ,
84+ unit_type_to_string (* type ));
6685 if (r < 0 )
6786 return r ;
6887
@@ -72,25 +91,43 @@ static int unit_types_total_build_json_one(sd_varlink *link, Manager *manager, U
7291 return sd_varlink_reply (link , v );
7392}
7493
75- static int unit_state_build_json_one (sd_varlink * link , Unit * unit , bool more ) {
94+ static int units_by_type_total_build_json (sd_varlink * link , void * userdata , bool more ) {
95+ int r ;
96+ Manager * manager = ASSERT_PTR (userdata );
97+
98+ assert (link );
99+
100+ UnitType * t , * previous_type = NULL ;
101+ UnitType type ;
102+ for (int i = 0 ; i < _UNIT_TYPE_MAX ; i ++ ) {
103+ type = (UnitType ) i ;
104+ t = & type ;
105+
106+ if (previous_type ) {
107+ r = units_by_type_total_build_json_one (link , manager , previous_type , more );
108+ if (r < 0 )
109+ return r ;
110+ }
111+
112+ previous_type = t ;
113+ }
114+
115+ return units_by_type_total_build_json_one (link , manager , previous_type , more );
116+ }
117+
118+ static int unit_active_state_build_json_one (sd_varlink * link , Unit * unit , bool more ) {
76119 _cleanup_ (sd_json_variant_unrefp ) sd_json_variant * v = NULL ;
77120 int r ;
78121
79122 assert (link );
80123 assert (unit );
81124
82-
83- r = METRIC_JSON_BUILD_UNSIGNED (
125+ r = METRIC_JSON_BUILD_STRING (
84126 & v ,
85- METRIC_IO_SYSTEMD_MANAGER_UNIT_STATE ,
127+ METRIC_IO_SYSTEMD_MANAGER_UNIT_ACTIVE_STATE ,
86128 unit -> id ,
87- /* value= */ 0 , /* 0 is a placeholder and has no meaning */
88- /* fields */
89- "state" , unit_active_state_to_string (unit_active_state (unit )),
90- "load_state" , unit_load_state_to_string (unit -> load_state ),
91- "sub_state" , unit_sub_state_to_string (unit ),
92- "freezer_state" , freezer_state_to_string (unit -> freezer_state ),
93- "unit_file_state" , unit_file_state_to_string (unit_get_unit_file_state (unit )));
129+ unit_active_state_to_string (unit_active_state (unit )),
130+ /* fields */ NULL );
94131 if (r < 0 )
95132 return r ;
96133
@@ -100,71 +137,69 @@ static int unit_state_build_json_one(sd_varlink *link, Unit *unit, bool more) {
100137 return sd_varlink_reply (link , v );
101138}
102139
103- static int unit_types_total_build_json (sd_varlink * link , void * userdata , bool more ) {
140+ static int unit_active_state_build_json (sd_varlink * link , void * userdata , bool more ) {
104141 int r ;
142+ const char * k ;
143+ Unit * u , * previous = NULL ;
105144 Manager * manager = ASSERT_PTR (userdata );
106145
107146 assert (link );
108- assert (manager );
109-
110- UnitType * t , * previous_type = NULL ;
111- for (int i = 0 ; i < _UNIT_TYPE_MAX ; i ++ ) {
112- UnitType type = (UnitType ) i ;
113- t = & type ;
114147
115- if (previous_type ) {
116- r = unit_types_total_build_json_one (link , manager , previous_type , more );
148+ HASHMAP_FOREACH_KEY (u , k , manager -> units ) {
149+ /* ignore aliases */
150+ if (k != u -> id )
151+ continue ;
152+ if (previous ) {
153+ r = unit_active_state_build_json_one (link , previous , /* more = */ true);
117154 if (r < 0 )
118155 return r ;
119156 }
120157
121- previous_type = t ;
122- }
158+ previous = u ;
159+ }
123160
124- if (previous_type ) {
125- r = unit_types_total_build_json_one (link , manager , previous_type , more );
126- if (r < 0 )
127- return r ;
128- } else
129- return sd_varlink_error (link , VARLINK_ERROR_METRICS_NO_SUCH_METRIC , NULL );
161+ if (previous )
162+ return unit_active_state_build_json_one (link , previous , more );
130163
131- return 0 ;
164+ return sd_varlink_error ( link , VARLINK_ERROR_METRICS_NO_SUCH_METRIC , NULL ) ;
132165}
133166
134- static int unit_states_total_build_json (sd_varlink * link , void * userdata , bool more ) {
167+ static int unit_load_state_build_json_one (sd_varlink * link , Unit * unit , bool more ) {
168+ _cleanup_ (sd_json_variant_unrefp ) sd_json_variant * v = NULL ;
135169 int r ;
136- Manager * manager = ASSERT_PTR (userdata );
137170
138171 assert (link );
172+ assert (unit );
139173
140- r = unit_states_total_build_json_one (
141- link ,
142- UNIT_ACTIVE ,
143- hashmap_size (manager -> units ),
144- more );
174+ r = METRIC_JSON_BUILD_STRING (
175+ & v ,
176+ METRIC_IO_SYSTEMD_MANAGER_UNIT_LOAD_STATE ,
177+ unit -> id ,
178+ unit_load_state_to_string (unit -> load_state ),
179+ /* fields */ NULL );
145180 if (r < 0 )
146181 return r ;
147182
148- return unit_states_total_build_json_one (
149- link ,
150- UNIT_FAILED ,
151- set_size (manager -> failed_units ),
152- more );
183+ if (more )
184+ return sd_varlink_notify (link , v );
185+
186+ return sd_varlink_reply (link , v );
153187}
154188
155- static int unit_state_build_json (sd_varlink * link , void * userdata , bool more ) {
189+ static int unit_load_state_build_json (sd_varlink * link , void * userdata , bool more ) {
156190 int r ;
157191 const char * k ;
158192 Unit * u , * previous = NULL ;
159193 Manager * manager = ASSERT_PTR (userdata );
160194
195+ assert (link );
196+
161197 HASHMAP_FOREACH_KEY (u , k , manager -> units ) {
162198 /* ignore aliases */
163199 if (k != u -> id )
164200 continue ;
165-
166201 if (previous ) {
167- r = unit_state_build_json_one (link , previous , /* more = */ true);
202+ r = unit_load_state_build_json_one (link , previous , /* more = */ true);
168203 if (r < 0 )
169204 return r ;
170205 }
@@ -173,7 +208,7 @@ static int unit_state_build_json(sd_varlink *link, void *userdata, bool more) {
173208 }
174209
175210 if (previous )
176- return unit_state_build_json_one (link , previous , more );
211+ return unit_load_state_build_json_one (link , previous , more );
177212
178213 return sd_varlink_error (link , VARLINK_ERROR_METRICS_NO_SUCH_METRIC , NULL );
179214}
@@ -185,7 +220,6 @@ static int vtable_describe_metrics_build_json_one(sd_varlink *link, const Metric
185220 assert (link );
186221 assert (metric_family );
187222
188-
189223 r = metric_family_json_build (& v , metric_family );
190224 if (r < 0 )
191225 return r ;
@@ -198,23 +232,26 @@ static int vtable_describe_metrics_build_json_one(sd_varlink *link, const Metric
198232
199233const MetricFamily metric_family_table [] = {
200234 METRIC_FAMILY (
201- METRIC_IO_SYSTEMD_MANAGER_UNIT_STATES_TOTAL ,
202-
235+ METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_STATE_TOTAL ,
203236 "Total counts of units of different states" ,
204237 METRIC_FAMILY_TYPE_GAUGE ,
205- unit_states_total_build_json ),
238+ units_by_state_total_build_json ),
206239 METRIC_FAMILY (
207- METRIC_IO_SYSTEMD_MANAGER_UNIT_TYPES_TOTAL ,
240+ METRIC_IO_SYSTEMD_MANAGER_UNITS_BY_TYPE_TOTAL ,
208241 "Total counts of units of different types" ,
209242 METRIC_FAMILY_TYPE_GAUGE ,
210- unit_types_total_build_json ),
243+ units_by_type_total_build_json ),
211244 METRIC_FAMILY (
212- METRIC_IO_SYSTEMD_MANAGER_UNIT_STATE ,
213- "Per unit metrics" ,
214- METRIC_FAMILY_TYPE_GAUGE ,
215- unit_state_build_json ),
245+ METRIC_IO_SYSTEMD_MANAGER_UNIT_ACTIVE_STATE ,
246+ "Per unit metrics: active state" ,
247+ METRIC_FAMILY_TYPE_STRING ,
248+ unit_active_state_build_json ),
249+ METRIC_FAMILY (
250+ METRIC_IO_SYSTEMD_MANAGER_UNIT_LOAD_STATE ,
251+ "Per unit metrics: load state" ,
252+ METRIC_FAMILY_TYPE_STRING ,
253+ unit_load_state_build_json ),
216254 {},
217-
218255};
219256
220257int vl_method_list (
@@ -237,7 +274,7 @@ int vl_method_list(
237274 const MetricFamily * previous = NULL ;
238275 for (const MetricFamily * mf = metric_family_table ; mf && mf -> name ; mf ++ ) {
239276 if (previous ) {
240- r = previous -> cb (link , userdata , true);
277+ r = previous -> cb (link , userdata , /* more */ true);
241278 if (r < 0 )
242279 return log_debug_errno (r , "Failed to list metrics for metric family '%s': %m" , previous -> name );
243280 }
@@ -246,7 +283,7 @@ int vl_method_list(
246283 }
247284
248285 if (previous ) {
249- r = previous -> cb (link , userdata , false);
286+ r = previous -> cb (link , userdata , /* more */ false);
250287 if (r < 0 )
251288 return log_debug_errno (r , "Failed to list metrics for metric family '%s': %m" , previous -> name );
252289 }
@@ -274,7 +311,7 @@ int vl_method_describe(
274311 const MetricFamily * previous = NULL ;
275312 for (const MetricFamily * mf = metric_family_table ; mf && mf -> name ; mf ++ ) {
276313 if (previous ) {
277- r = vtable_describe_metrics_build_json_one (link , previous , true);
314+ r = vtable_describe_metrics_build_json_one (link , previous , /* more */ true);
278315 if (r < 0 )
279316 return log_debug_errno (r , "Failed to describe metric family '%s': %m" , previous -> name );
280317 }
@@ -283,7 +320,7 @@ int vl_method_describe(
283320 }
284321
285322 if (previous ) {
286- r = vtable_describe_metrics_build_json_one (link , previous , false);
323+ r = vtable_describe_metrics_build_json_one (link , previous , /* more */ false);
287324 if (r < 0 )
288325 return log_debug_errno (r , "Failed to describe metric family '%s': %m" , previous -> name );
289326 }
0 commit comments