Skip to content

Commit f5529bb

Browse files
committed
Share NetIPC C service initialization
1 parent f5eca1e commit f5529bb

7 files changed

Lines changed: 211 additions & 102 deletions

.agents/sow/current/SOW-0015-20260605-codacy-scope-and-maintainability.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,46 @@ Validation for this increment:
904904
- `cd src/go && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go test -run '^$' ./pkg/netipc/transport/windows ./pkg/netipc/service/raw ./pkg/netipc/service/apps_lookup ./pkg/netipc/service/cgroups_lookup ./pkg/netipc/service/cgroups_snapshot`: passed.
905905
- `git diff --check`: passed.
906906

907+
### 2026-06-08 - Netdata PR Sonar C Service Duplication Refresh
908+
909+
Fresh Netdata PR #22649 SonarCloud evidence after vendoring plugin-ipc commit `f5eca1e`:
910+
911+
- SonarCloud analyzed Netdata PR head `08fcd6594fec0f5f3fa323946e35cf7354f0fe0f`.
912+
- SonarCloud new-code duplication improved from 1024 lines / 5.903378300472731% to:
913+
- new duplicated lines: 666.
914+
- new duplicated blocks: 33.
915+
- new duplicated line density: 3.768247142695485%.
916+
- The remaining Quality Gate failure is still `new_duplicated_lines_density > 3%`.
917+
- Top remaining production contributors are C POSIX/Windows service pairs:
918+
- `netipc_service_posix_server.c`: 61 duplicated lines.
919+
- `netipc_service_win_server.c`: 61 duplicated lines.
920+
- `netipc_service_posix_client.c`: 33 duplicated lines.
921+
- `netipc_service_win_client.c`: 33 duplicated lines.
922+
- `netipc_service_posix_client_call.c`: 32 duplicated lines.
923+
- `netipc_service_win_client_call.c`: 32 duplicated lines.
924+
925+
Implemented SDK follow-up:
926+
927+
- Added common C service helpers for:
928+
- client/server transport field conversion from typed service config.
929+
- server base field initialization.
930+
- server session-slot allocation.
931+
- Updated POSIX and Windows service client/server files to reuse those helpers.
932+
- Preserved platform-specific behavior:
933+
- POSIX and Windows listener creation remains platform-specific.
934+
- POSIX mutex and Windows critical-section setup remains platform-specific.
935+
- POSIX UDS, POSIX SHM, Windows Named Pipe, and Windows SHM code paths remain platform-specific.
936+
- No protocol, wire-format, or runtime contract changed.
937+
938+
Validation for this increment:
939+
940+
- `git diff --check`: passed.
941+
- `cmake --build build`: passed.
942+
- `/usr/bin/ctest --test-dir build --output-on-failure`: 46/46 tests passed.
943+
- Win11 MSYS focused C service validation from a temporary copy:
944+
- `cmake --build build-msys --target test_win_service test_win_service_payload_limits test_win_service_extra`: passed.
945+
- `/usr/bin/ctest --output-on-failure -R '^(test_win_service|test_win_service_payload_limits|test_win_service_extra)$'`: 3/3 tests passed.
946+
907947
## Validation
908948

909949
Acceptance criteria evidence:
@@ -921,6 +961,7 @@ Acceptance criteria evidence:
921961
- Go apps/cgroups lookup unknown codec paths now have canonical fast paths and regression tests.
922962
- POSIX and Windows benchmark runners now distinguish floor/correctness failures from scheduler-stability noise using documented repeated-sample policies.
923963
- Netdata PR #22649 SonarCloud duplication gate was rechecked; the current SDK increment removes duplicated Go transport/service flow before re-vendoring.
964+
- Netdata PR #22649 SonarCloud duplication gate was rechecked after the Go increment; the remaining production C service duplication was reduced through shared service helpers.
924965

925966
Tests or equivalent validation:
926967

@@ -940,6 +981,9 @@ Tests or equivalent validation:
940981
- `cd src/go && go test -count=1 ./pkg/netipc/...`: passed on 2026-06-08.
941982
- `cd src/go && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go test -run '^$' ./pkg/netipc/transport/windows ./pkg/netipc/service/raw ./pkg/netipc/service/apps_lookup ./pkg/netipc/service/cgroups_lookup ./pkg/netipc/service/cgroups_snapshot`: passed on 2026-06-08.
942983
- `git diff --check`: passed on 2026-06-08 after the Go duplication-reduction increment.
984+
- `cmake --build build`: passed on 2026-06-08 after the C service duplication-reduction increment.
985+
- `/usr/bin/ctest --test-dir build --output-on-failure`: 46/46 passed on 2026-06-08 after the C service duplication-reduction increment.
986+
- Win11 MSYS focused C service validation: 3/3 passed on 2026-06-08 after the C service duplication-reduction increment.
943987

944988
Real-use evidence:
945989

src/libnetdata/netipc/src/service/netipc_service_common.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,42 @@ void nipc_service_common_copy_cstr_field(char *dst, size_t dst_size, const char
8181
dst[len] = '\0';
8282
}
8383

84+
bool nipc_service_common_client_transport_fields(
85+
nipc_service_common_transport_fields_t *fields,
86+
const nipc_client_config_t *config)
87+
{
88+
memset(fields, 0, sizeof(*fields));
89+
if (!config)
90+
return false;
91+
92+
fields->supported_profiles = config->supported_profiles;
93+
fields->preferred_profiles = config->preferred_profiles;
94+
fields->max_request_batch_items = config->max_request_batch_items;
95+
fields->max_response_payload_bytes = config->max_response_payload_bytes;
96+
fields->max_response_batch_items =
97+
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
98+
fields->auth_token = config->auth_token;
99+
return true;
100+
}
101+
102+
bool nipc_service_common_server_transport_fields(
103+
nipc_service_common_transport_fields_t *fields,
104+
const nipc_server_config_t *config)
105+
{
106+
memset(fields, 0, sizeof(*fields));
107+
if (!config)
108+
return false;
109+
110+
fields->supported_profiles = config->supported_profiles;
111+
fields->preferred_profiles = config->preferred_profiles;
112+
fields->max_request_batch_items = config->max_request_batch_items;
113+
fields->max_response_payload_bytes = config->max_response_payload_bytes;
114+
fields->max_response_batch_items =
115+
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
116+
fields->auth_token = config->auth_token;
117+
return true;
118+
}
119+
84120
void nipc_service_common_client_init(nipc_client_ctx_t *ctx,
85121
const char *run_dir,
86122
const char *service_name)
@@ -303,6 +339,60 @@ nipc_error_t nipc_service_common_call_with_retry(
303339
}
304340
}
305341

342+
nipc_error_t nipc_service_common_server_init_base(
343+
nipc_managed_server_t *server,
344+
const char *run_dir,
345+
const char *service_name,
346+
int worker_count,
347+
uint16_t expected_method_code,
348+
nipc_server_handler_fn handler,
349+
void *user,
350+
uint32_t max_request_payload_bytes,
351+
uint32_t max_response_payload_bytes)
352+
{
353+
if (!run_dir || !service_name || !handler)
354+
return NIPC_ERR_BAD_LAYOUT;
355+
356+
if (worker_count < 1)
357+
worker_count = 1;
358+
359+
nipc_service_common_copy_cstr_field(server->run_dir, sizeof(server->run_dir),
360+
run_dir);
361+
nipc_service_common_copy_cstr_field(server->service_name,
362+
sizeof(server->service_name),
363+
service_name);
364+
365+
server->handler = handler;
366+
server->handler_user = user;
367+
server->worker_count = worker_count;
368+
server->expected_method_code = expected_method_code;
369+
server->learned_request_payload_bytes =
370+
max_request_payload_bytes > 0
371+
? max_request_payload_bytes
372+
: NIPC_MAX_PAYLOAD_DEFAULT;
373+
server->learned_response_payload_bytes =
374+
max_response_payload_bytes > 0
375+
? max_response_payload_bytes
376+
: NIPC_MAX_PAYLOAD_DEFAULT;
377+
server->session_capacity = worker_count * 2;
378+
if (server->session_capacity < 16)
379+
server->session_capacity = 16;
380+
server->session_count = 0;
381+
server->next_session_id = 1;
382+
return NIPC_OK;
383+
}
384+
385+
nipc_error_t nipc_service_common_server_alloc_sessions(
386+
nipc_managed_server_t *server,
387+
nipc_service_common_calloc_fn calloc_fn,
388+
int fault_site)
389+
{
390+
server->sessions = calloc_fn((size_t)server->session_capacity,
391+
sizeof(nipc_session_ctx_t *),
392+
fault_site);
393+
return server->sessions ? NIPC_OK : NIPC_ERR_OVERFLOW;
394+
}
395+
306396
void nipc_service_common_server_note_request_capacity(nipc_managed_server_t *server,
307397
uint32_t payload_len)
308398
{

src/libnetdata/netipc/src/service/netipc_service_common.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@ typedef struct {
4545
uint32_t reconnect_retry_interval_ms;
4646
} nipc_service_common_client_ops_t;
4747

48+
typedef void *(*nipc_service_common_calloc_fn)(size_t count,
49+
size_t size,
50+
int fault_site);
51+
52+
typedef struct {
53+
uint32_t supported_profiles;
54+
uint32_t preferred_profiles;
55+
uint32_t max_request_batch_items;
56+
uint32_t max_response_payload_bytes;
57+
uint32_t max_response_batch_items;
58+
uint64_t auth_token;
59+
} nipc_service_common_transport_fields_t;
60+
61+
#define NIPC_SERVICE_COMMON_APPLY_TRANSPORT_FIELDS(dst, fields) do { \
62+
(dst)->supported_profiles = (fields)->supported_profiles; \
63+
(dst)->preferred_profiles = (fields)->preferred_profiles; \
64+
(dst)->max_request_batch_items = (fields)->max_request_batch_items; \
65+
(dst)->max_response_payload_bytes = (fields)->max_response_payload_bytes; \
66+
(dst)->max_response_batch_items = (fields)->max_response_batch_items; \
67+
(dst)->auth_token = (fields)->auth_token; \
68+
} while (0)
69+
4870
uint32_t nipc_service_common_next_power_of_2_u32(uint32_t n);
4971
bool nipc_service_common_header_payload_len(size_t payload_len,
5072
size_t *msg_len_out);
@@ -55,6 +77,12 @@ uint32_t nipc_service_common_request_payload_default(void);
5577
uint32_t nipc_service_common_response_payload_default(void);
5678
uint32_t nipc_service_common_typed_response_batch_items(uint32_t max_request_batch_items);
5779
void nipc_service_common_copy_cstr_field(char *dst, size_t dst_size, const char *src);
80+
bool nipc_service_common_client_transport_fields(
81+
nipc_service_common_transport_fields_t *fields,
82+
const nipc_client_config_t *config);
83+
bool nipc_service_common_server_transport_fields(
84+
nipc_service_common_transport_fields_t *fields,
85+
const nipc_server_config_t *config);
5886

5987
void nipc_service_common_client_init(nipc_client_ctx_t *ctx,
6088
const char *run_dir,
@@ -89,6 +117,20 @@ void nipc_service_common_server_note_request_capacity(nipc_managed_server_t *ser
89117
uint32_t payload_len);
90118
void nipc_service_common_server_note_response_capacity(nipc_managed_server_t *server,
91119
uint32_t payload_len);
120+
nipc_error_t nipc_service_common_server_init_base(
121+
nipc_managed_server_t *server,
122+
const char *run_dir,
123+
const char *service_name,
124+
int worker_count,
125+
uint16_t expected_method_code,
126+
nipc_server_handler_fn handler,
127+
void *user,
128+
uint32_t max_request_payload_bytes,
129+
uint32_t max_response_payload_bytes);
130+
nipc_error_t nipc_service_common_server_alloc_sessions(
131+
nipc_managed_server_t *server,
132+
nipc_service_common_calloc_fn calloc_fn,
133+
int fault_site);
92134
void nipc_service_common_prepare_response_header(const nipc_header_t *request_hdr,
93135
nipc_header_t *resp_hdr);
94136
void nipc_service_common_apply_dispatch_result(nipc_managed_server_t *server,

src/libnetdata/netipc/src/service/netipc_service_posix_client.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,12 @@ static nipc_uds_client_config_t service_client_config_to_transport(
1818
const nipc_client_config_t *config)
1919
{
2020
nipc_uds_client_config_t transport = {0};
21+
nipc_service_common_transport_fields_t fields;
2122

22-
if (!config)
23+
if (!nipc_service_common_client_transport_fields(&fields, config))
2324
return transport;
2425

25-
transport.supported_profiles = config->supported_profiles;
26-
transport.preferred_profiles = config->preferred_profiles;
27-
transport.max_request_batch_items = config->max_request_batch_items;
28-
transport.max_response_payload_bytes = config->max_response_payload_bytes;
29-
transport.max_response_batch_items =
30-
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
31-
transport.auth_token = config->auth_token;
32-
26+
NIPC_SERVICE_COMMON_APPLY_TRANSPORT_FIELDS(&transport, &fields);
3327
return transport;
3428
}
3529

@@ -56,17 +50,12 @@ void nipc_service_platform_server_config_from_service(
5650
const nipc_server_config_t *config)
5751
{
5852
memset(transport, 0, sizeof(*transport));
53+
nipc_service_common_transport_fields_t fields;
5954

60-
if (!config)
55+
if (!nipc_service_common_server_transport_fields(&fields, config))
6156
return;
6257

63-
transport->supported_profiles = config->supported_profiles;
64-
transport->preferred_profiles = config->preferred_profiles;
65-
transport->max_request_batch_items = config->max_request_batch_items;
66-
transport->max_response_payload_bytes = config->max_response_payload_bytes;
67-
transport->max_response_batch_items =
68-
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
69-
transport->auth_token = config->auth_token;
58+
NIPC_SERVICE_COMMON_APPLY_TRANSPORT_FIELDS(transport, &fields);
7059
}
7160

7261
/* ------------------------------------------------------------------ */

src/libnetdata/netipc/src/service/netipc_service_posix_server.c

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -111,43 +111,21 @@ nipc_error_t nipc_service_platform_server_init_raw(
111111
__atomic_store_n(&server->running, false, __ATOMIC_RELAXED);
112112
server->acceptor_started = false;
113113

114-
if (!run_dir || !service_name || !config || !handler)
114+
if (!config)
115115
return NIPC_ERR_BAD_LAYOUT;
116116

117-
if (worker_count < 1)
118-
worker_count = 1;
119-
120-
nipc_service_common_copy_cstr_field(server->run_dir, sizeof(server->run_dir),
121-
run_dir);
122-
nipc_service_common_copy_cstr_field(server->service_name,
123-
sizeof(server->service_name),
124-
service_name);
125-
126-
server->handler = handler;
127-
server->handler_user = user;
128-
server->worker_count = worker_count;
129-
server->expected_method_code = expected_method_code;
117+
nipc_error_t ierr = nipc_service_common_server_init_base(
118+
server, run_dir, service_name, worker_count, expected_method_code,
119+
handler, user, config->max_request_payload_bytes,
120+
config->max_response_payload_bytes);
121+
if (ierr != NIPC_OK)
122+
return ierr;
130123
server->base_config = *config;
131-
server->learned_request_payload_bytes =
132-
config->max_request_payload_bytes > 0
133-
? config->max_request_payload_bytes
134-
: NIPC_MAX_PAYLOAD_DEFAULT;
135-
server->learned_response_payload_bytes =
136-
config->max_response_payload_bytes > 0
137-
? config->max_response_payload_bytes
138-
: NIPC_MAX_PAYLOAD_DEFAULT;
139-
140-
/* Initialize session tracking */
141-
server->session_capacity = worker_count * 2; /* room for slots being reaped */
142-
if (server->session_capacity < 16)
143-
server->session_capacity = 16;
144-
server->sessions = nipc_service_posix_calloc((size_t)server->session_capacity,
145-
sizeof(nipc_session_ctx_t *),
146-
NIPC_POSIX_SERVICE_TEST_FAULT_SERVER_SESSIONS_CALLOC_INTERNAL);
147-
if (!server->sessions)
148-
return NIPC_ERR_OVERFLOW;
149-
server->session_count = 0;
150-
server->next_session_id = 1; /* spec: monotonic counter starting at 1 */
124+
ierr = nipc_service_common_server_alloc_sessions(
125+
server, nipc_service_posix_calloc,
126+
NIPC_POSIX_SERVICE_TEST_FAULT_SERVER_SESSIONS_CALLOC_INTERNAL);
127+
if (ierr != NIPC_OK)
128+
return ierr;
151129
pthread_mutex_init(&server->sessions_lock, NULL);
152130

153131
/* Clean up stale SHM regions from previous crashes (spec requirement:

src/libnetdata/netipc/src/service/netipc_service_win_client.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,12 @@ static nipc_np_client_config_t service_client_config_to_transport(
2121
const nipc_client_config_t *config)
2222
{
2323
nipc_np_client_config_t transport = {0};
24+
nipc_service_common_transport_fields_t fields;
2425

25-
if (!config)
26+
if (!nipc_service_common_client_transport_fields(&fields, config))
2627
return transport;
2728

28-
transport.supported_profiles = config->supported_profiles;
29-
transport.preferred_profiles = config->preferred_profiles;
30-
transport.max_request_batch_items = config->max_request_batch_items;
31-
transport.max_response_payload_bytes = config->max_response_payload_bytes;
32-
transport.max_response_batch_items =
33-
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
34-
transport.auth_token = config->auth_token;
35-
29+
NIPC_SERVICE_COMMON_APPLY_TRANSPORT_FIELDS(&transport, &fields);
3630
return transport;
3731
}
3832

@@ -59,17 +53,12 @@ void nipc_service_platform_server_config_from_service(
5953
const nipc_server_config_t *config)
6054
{
6155
memset(transport, 0, sizeof(*transport));
56+
nipc_service_common_transport_fields_t fields;
6257

63-
if (!config)
58+
if (!nipc_service_common_server_transport_fields(&fields, config))
6459
return;
6560

66-
transport->supported_profiles = config->supported_profiles;
67-
transport->preferred_profiles = config->preferred_profiles;
68-
transport->max_request_batch_items = config->max_request_batch_items;
69-
transport->max_response_payload_bytes = config->max_response_payload_bytes;
70-
transport->max_response_batch_items =
71-
nipc_service_common_typed_response_batch_items(config->max_request_batch_items);
72-
transport->auth_token = config->auth_token;
61+
NIPC_SERVICE_COMMON_APPLY_TRANSPORT_FIELDS(transport, &fields);
7362
}
7463

7564
/* ------------------------------------------------------------------ */

0 commit comments

Comments
 (0)