]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
status: dump per-share profile counters
authorShachar Sharon <ssharon@redhat.com>
Mon, 28 Apr 2025 18:30:22 +0000 (21:30 +0300)
committerAnoop C S <anoopcs@samba.org>
Mon, 23 Jun 2025 13:04:31 +0000 (13:04 +0000)
When dumping profile information, try to iterate also on per-share
profile entries and emit (json format).

Signed-off-by: Shachar Sharon <ssharon@redhat.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Anoop C S <anoopcs@samba.org>
source3/utils/status_json.c
source3/utils/status_json.h
source3/utils/status_json_dummy.c
source3/utils/status_profile.c

index f7727b4c39d5232b0eefa08701b3f7f5f108a3e9..22606439b78ef6e49e580437a5b7571ddd1cc5b8 100644 (file)
@@ -184,50 +184,76 @@ static const struct mask2txt lease_mask[] = {
        {0, NULL}
 };
 
-int add_profile_item_to_json(struct traverse_state *state,
-                            const char *section,
-                            const char *subsection,
-                            const char *key,
-                            uintmax_t value)
+/* Add nested json key:value entry, up to 4 levels deep */
+static int add_nested_item_to_json(struct json_object *root_json,
+                                  const char **subs,
+                                  size_t nsubs,
+                                  const char *key,
+                                  uintmax_t value)
 {
-       struct json_object section_json = {
-               .valid = false,
-       };
-       struct json_object subsection_json = {
-               .valid = false,
-       };
+       struct json_object jobj_sub[4] = {0};
+       struct json_object *jo[5] = {root_json,
+                                    &jobj_sub[0],
+                                    &jobj_sub[1],
+                                    &jobj_sub[2],
+                                    &jobj_sub[3]};
+       size_t i = 0;
        int result = 0;
 
-       section_json = json_get_object(&state->root_json, section);
-       if (json_is_invalid(&section_json)) {
-               goto failure;
-       }
-       subsection_json = json_get_object(&section_json, subsection);
-       if (json_is_invalid(&subsection_json)) {
-               goto failure;
+       if (nsubs > ARRAY_SIZE(jobj_sub)) {
+               return -1;
        }
 
-       result = json_add_int(&subsection_json, key, value);
-       if (result < 0) {
-               goto failure;
+       for (i = 0; i < nsubs; ++i) {
+               *(jo[i + 1]) = json_get_object(jo[i], subs[i]);
+               if (json_is_invalid(jo[i + 1])) {
+                       goto failure;
+               }
        }
 
-       result = json_update_object(&section_json, subsection,  &subsection_json);
+       result = json_add_int(jo[nsubs], key, value);
        if (result < 0) {
                goto failure;
        }
-       result = json_update_object(&state->root_json, section, &section_json);
-       if (result < 0) {
-               goto failure;
+
+       for (i = nsubs; i > 0; --i) {
+               result = json_update_object(jo[i - 1], subs[i - 1], jo[i]);
+               if (result < 0) {
+                       goto failure;
+               }
        }
 
        return 0;
 failure:
-       json_free(&section_json);
-       json_free(&subsection_json);
+       for (i = 0; i < nsubs; ++i) {
+               json_free(&jobj_sub[i]);
+       }
        return -1;
 }
 
+int add_profile_item_to_json(struct traverse_state *state,
+                            const char *section,
+                            const char *subsection,
+                            const char *key,
+                            uintmax_t value)
+{
+       const char *subs[] = {section, subsection};
+
+       return add_nested_item_to_json(&state->root_json, subs, 2, key, value);
+}
+
+int add_profile_persvc_item_to_json(struct traverse_state *state,
+                                   const char *section1,
+                                   const char *section2,
+                                   const char *section3,
+                                   const char *key,
+                                   uintmax_t value)
+{
+       const char *subs[] = {"Extended Profile", section1, section2, section3};
+
+       return add_nested_item_to_json(&state->root_json, subs, 4, key, value);
+}
+
 int add_section_to_json(struct traverse_state *state,
                        const char *key)
 {
index ef5d18139be85777281af70ebf734a3bca9c890a..70cd00992ac81651b0a9cabba4c3f1754e03f471 100644 (file)
@@ -34,6 +34,13 @@ int add_profile_item_to_json(struct traverse_state *state,
                             const char *key,
                             uintmax_t value);
 
+int add_profile_persvc_item_to_json(struct traverse_state *state,
+                                   const char *section1,
+                                   const char *section2,
+                                   const char *section3,
+                                   const char *key,
+                                   uintmax_t value);
+
 int traverse_connections_json(struct traverse_state *state,
                              const struct connections_data *crec,
                              const char *encryption_cipher,
index 3cd8531c2de2553917fdbff4c8c8bbf7472d9eb0..262b3c28054930d11501d2cc4ef35eba136b03ff 100644 (file)
@@ -44,6 +44,16 @@ int add_profile_item_to_json(struct traverse_state *state,
        return 0;
 }
 
+int add_profile_persvc_item_to_json(struct traverse_state *state,
+                                   const char *section1,
+                                   const char *section2,
+                                   const char *section3,
+                                   const char *key,
+                                   uintmax_t value)
+{
+       return 0;
+}
+
 int traverse_connections_json(struct traverse_state *state,
                              const struct connections_data *crec,
                              const char *encryption_cipher,
index 299731b48136bed8ccbb1152cc920ad1d4817055..32b9ada598f4608cee3e29717f82de1d7afdec9f 100644 (file)
@@ -76,6 +76,102 @@ static void print_buckets(struct traverse_state *state,
                 s->buckets[9]);
 }
 
+/*******************************************************************
+ dump the elements of the persvc profile structure
+  ******************************************************************/
+
+static void status_profile_dump_persvc_stats(struct traverse_state *state,
+                                            const char *secname,
+                                            const struct profile_stats *pstats)
+{
+       const char *latest_section = NULL;
+
+#define __PRINT_FIELD_LINE(name, _stats, field)                           \
+       do {                                                              \
+               uintmax_t val = (uintmax_t)(*pstats).values._stats.field; \
+               if (!state->json_output) {                                \
+                       d_printf("%s %-59s%20ju\n",                       \
+                                secname,                                 \
+                                name "_" #field ":",                     \
+                                val);                                    \
+               } else {                                                  \
+                       add_profile_persvc_item_to_json(state,            \
+                                                       secname,          \
+                                                       latest_section,   \
+                                                       name,             \
+                                                       #field,           \
+                                                       val);             \
+               }                                                         \
+       } while (0);
+#define SMBPROFILE_STATS_START
+#define SMBPROFILE_STATS_SECTION_START(name, display) \
+       do {                                          \
+               latest_section = display;             \
+               profile_separator(display, state);    \
+       } while (0);
+#define SMBPROFILE_STATS_COUNT(name)                            \
+       do {                                                    \
+               __PRINT_FIELD_LINE(#name, name##_stats, count); \
+       } while (0);
+#define SMBPROFILE_STATS_TIME(name)                            \
+       do {                                                   \
+               __PRINT_FIELD_LINE(#name, name##_stats, time); \
+       } while (0);
+#define SMBPROFILE_STATS_BASIC(name)                            \
+       do {                                                    \
+               __PRINT_FIELD_LINE(#name, name##_stats, count); \
+               __PRINT_FIELD_LINE(#name, name##_stats, time);  \
+       } while (0);
+#define SMBPROFILE_STATS_BYTES(name)                            \
+       do {                                                    \
+               __PRINT_FIELD_LINE(#name, name##_stats, count); \
+               __PRINT_FIELD_LINE(#name, name##_stats, time);  \
+               __PRINT_FIELD_LINE(#name, name##_stats, idle);  \
+               __PRINT_FIELD_LINE(#name, name##_stats, bytes); \
+       } while (0);
+#define SMBPROFILE_STATS_IOBYTES(name)                                       \
+       do {                                                                 \
+               __PRINT_FIELD_LINE(#name, name##_stats, count);              \
+               __PRINT_FIELD_LINE(#name, name##_stats, failed_count);       \
+               __PRINT_FIELD_LINE(#name, name##_stats, time);               \
+               print_buckets(state, #name, &(*pstats).values.name##_stats); \
+               __PRINT_FIELD_LINE(#name, name##_stats, idle);               \
+               __PRINT_FIELD_LINE(#name, name##_stats, inbytes);            \
+               __PRINT_FIELD_LINE(#name, name##_stats, outbytes);           \
+       } while (0);
+#define SMBPROFILE_STATS_SECTION_END
+#define SMBPROFILE_STATS_END
+       SMBPROFILE_STATS_ALL_SECTIONS
+#undef __PRINT_FIELD_LINE
+#undef SMBPROFILE_STATS_START
+#undef SMBPROFILE_STATS_SECTION_START
+#undef SMBPROFILE_STATS_COUNT
+#undef SMBPROFILE_STATS_TIME
+#undef SMBPROFILE_STATS_BASIC
+#undef SMBPROFILE_STATS_BYTES
+#undef SMBPROFILE_STATS_IOBYTES
+#undef SMBPROFILE_STATS_SECTION_END
+#undef SMBPROFILE_STATS_END
+}
+
+static int status_profile_dump_persvc_cb(const char *key,
+                                        const struct profile_stats *stats,
+                                        void *private_data)
+{
+       struct traverse_state *state = private_data;
+
+       status_profile_dump_persvc_stats(state, key, stats);
+       return 0;
+}
+
+static void status_profile_dump_persvc(struct traverse_state *state)
+{
+       if (!state->json_output) {
+               return;
+       }
+       smbprofile_persvc_collect(status_profile_dump_persvc_cb, state);
+}
+
 /*******************************************************************
  dump the elements of the profile structure
   ******************************************************************/
@@ -146,6 +242,7 @@ bool status_profile_dump(bool verbose,
 #undef SMBPROFILE_STATS_SECTION_END
 #undef SMBPROFILE_STATS_END
 
+       status_profile_dump_persvc(state);
        return True;
 }