Skip to content

ENT-6511: Increase cf-monitord measurement slots from 100 to 300#6239

Open
nickanderson wants to merge 2 commits into
cfengine:masterfrom
nickanderson:CFE-612-increase-monitor-slots
Open

ENT-6511: Increase cf-monitord measurement slots from 100 to 300#6239
nickanderson wants to merge 2 commits into
cfengine:masterfrom
nickanderson:CFE-612-increase-monitor-slots

Conversation

@nickanderson

@nickanderson nickanderson commented Jul 20, 2026

Copy link
Copy Markdown
Member

Raises CF_OBSERVABLES from 100 to 300. Previously out of the box ~80 of the 100 slots are consumed by default measurements, leaving only ~19 for custom measurements: promises.

Notably, this change does increase the disk footprint required by an agent by 60MB (.27MB per slot). That storage is required even if the slots are not in active use (Ref: ENT-14329)

Ticket: ENT-6511

@nickanderson

Copy link
Copy Markdown
Member Author

@cf-bottom jenkins please.

@cf-bottom

Copy link
Copy Markdown

@nickanderson
nickanderson marked this pull request as ready for review July 20, 2026 16:27
@nickanderson
nickanderson requested a review from larsewi July 20, 2026 16:27

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Otherwise LGTM

Comment thread cf-check/dump.c Outdated
@nickanderson
nickanderson force-pushed the CFE-612-increase-monitor-slots branch from 1a91252 to 5f4e187 Compare July 21, 2026 14:41
@nickanderson
nickanderson requested a review from larsewi July 21, 2026 15:56
@nickanderson

Copy link
Copy Markdown
Member Author

@cf-bottom jenkins please.

@cf-bottom

Copy link
Copy Markdown

Comment thread cf-check/dump.c Outdated
Comment on lines +168 to +170
// Fall back to simple printing in release builds:
// Fall back to simple printing in release builds. Records written
// before CF_OBSERVABLES was raised are shorter, but a running agent
// migrates them (see dbm_migration_observations.c) before they are read.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Feels like this change does not belong here anymore

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reverted to the original // Fall back to simple printing in release builds:.

Comment thread cf-check/dump.c Outdated
Comment on lines +297 to +298
// Migration version scalar (dbm_migration_observations.c), a short
// string rather than an Averages struct.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure I understand this comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reworded. The migration stores a version bookkeeping key in these DBs; its value is a short version string, not an Averages struct, so it is printed as a string rather than falling through to print_struct_averages() (which would trip the struct-size assertion).

@@ -0,0 +1,113 @@
/*
Copyright 2024 Northern.tech AS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Copyright 2024 Northern.tech AS
Copyright 2026 Northern.tech AS

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

Comment thread cf-check/observables.c
Comment on lines +77 to +86
/* The ts_key has fewer entries than CF_OBSERVABLES -- e.g. it
* was written by an older agent with a smaller CF_OBSERVABLES.
* Fill the remaining names so the returned array keeps its
* documented non-NULL guarantee (callers index all
* CF_OBSERVABLES entries). */
for (int j = i; j < CF_OBSERVABLES; ++j)
{
snprintf(buf, CF_MAXVARSIZE, "spare[%d]", j);
temp[j] = xstrdup(buf);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this still needed post migration fix ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes — this is about the ts_key text file, which the DB migration does not touch. GetObservableNames() is documented to return a CF_OBSERVABLES-sized array of non-NULL strings. A ts_key written by an older agent has only 100 lines, so after the bump fgets hits EOF at slot 100 and, without this fill, temp[100..299] stay uninitialized (xmalloc, not zeroed); the sole caller (dump.c:179) then indexes and free()s all 300 → uninitialized read + invalid free. So it is an independent correctness fix.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

And, just FYI, I have a follow-up PR waiting to changes the storage to only require what is used

Comment on lines +62 to +64
char cmd[CF_BUFSIZE];
xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'/*", GetStateDir());
system(cmd);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I know, I know... Recursively deleting a directory is not as easy as one would think in C. However, there probably is a function you can use in libntech or libpromises so that you don't have to run a command.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Although I get the argument that the unit tests should be as lightweight as possible. Either way is fine by me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Switched to DeleteDirectoryTree() from libntech (empties the tree, keeps the top dir), plus a trailing rmdir() in teardown.

system(cmd);

DBHandle *db;
assert_int_equal(OpenDB(&db, dbid_observations), true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use assert_true instead of treating bool as an int, even though it really is. It will also give more descriptive error messages.

Suggested change
assert_int_equal(OpenDB(&db, dbid_observations), true);
assert_true(OpenDB(&db, dbid_observations));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done — converted the bool-returning assertions (OpenDB/WriteDB/ReadDB/HasKeyDB/NewDBCursor/DeleteDBCursor) to assert_true.


/* STUBS */

void FatalError(ARG_UNUSED char *s, ...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a comment explaining why this STUB is here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added a comment: OpenDB() pulls in libpromises DB code that references FatalError(), whose real implementation lives in the daemons, not the test binary — so the stub is there to let the test link, and reaching it is itself a failure.

@nickanderson
nickanderson force-pushed the CFE-612-increase-monitor-slots branch from 5f4e187 to fa550dd Compare July 22, 2026 14:23
@nickanderson
nickanderson requested a review from larsewi July 22, 2026 14:29
Comment thread cf-check/dump.c Outdated
~80 of the 100 slots are consumed by default measurements, leaving little
room for custom ones. Raise the limit to 300.

Kept in sync: CF_OBSERVABLES and the two cf-check copies of the on-disk
struct, plus the OBSERVABLES name table (GetObservable() indexes it for
unregistered slots, so a short table crashes cf-monitord). cf-check also pads
a pre-upgrade ts_key that has fewer entries than CF_OBSERVABLES.

Ticket: ENT-6511
Changelog: Increased the maximum number of cf-monitord measurement slots (CF_OBSERVABLES) from 100 to 300
Raising CF_OBSERVABLES enlarges the fixed-size Averages record, so records
written by an older agent are shorter than the current struct. Added a
migration (modelled on dbm_migration_lastseen.c) that rewrites old records to
the current size, zero-filling the new slots, registered for the observations
and history DBs. cf-check dump only needs to recognise the new "version" key
the migration writes.

Ticket: ENT-6511
Changelog: None
@nickanderson
nickanderson force-pushed the CFE-612-increase-monitor-slots branch from fa550dd to d278e7e Compare July 22, 2026 15:39
@nickanderson
nickanderson requested a review from larsewi July 22, 2026 15:42
Comment thread cf-check/dump.c
if (structs)
{
if (StringContains(file, "cf_lastseen.lmdb")
if ((StringContains(file, "cf_observations.lmdb")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pre-existing. But, should probably be StringEndsWith()? Could be a follow-up commit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

in this PR or completely separately?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Up to you. I'm OK with leaving it as is as well

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think I will leave it for now. Seems to have been intentionally changed from StringsEndsWith to StringContains 3e98366c3

@larsewi

larsewi commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@cf-bottom Jenkins please :)

@cf-bottom

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants