CFEngine Internals: How cf-agent executes a policy?

1. Start GDB
[root@infra01 unixguy]# gdb /var/cfengine/bin/cf-agent
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-64.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /var/cfengine/bin/cf-agent...done.

2. show the entry point of the program
(gdb) list
207 "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'",
208 "Disable extension loading (used while upgrading)",
209 "Log timestamps on each line of log output",
210 NULL
211 };
212
213 /*******************************************************************/
214
215 int main(int argc, char *argv[])
216 {

3. put a break point at main() function
(gdb) break main
Breakpoint 1 at 0x409f30: file cf-agent.c, line 216.

4. run the program with arguments

(gdb) run -IKC -f ./test.cf
Starting program: /var/cfengine/bin/cf-agent -IKC -f ./test.cf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, main (argc=4, argv=0x7fffffffe658) at cf-agent.c:216
216 {

5. Bird's eye-view analysis of overall execution of cf-agent:

(gdb) next
220 struct timespec start = BeginMeasure(); ---> BeginMeasure() is in libpromises/instrumentation.c it uses clock_gettime() which in turn uses time() of time.h to set the start time of the execution. This time is in seconds from epoch
(gdb)
222 GenericAgentConfig *config = CheckOpts(argc, argv); ---> CheckOpts() parses command line arguments of cf-agent
(gdb)
223 EvalContext *ctx = EvalContextNew(); ---> EvalContextNew() is defined in libpromises/eval_context.c. It initializes EvalContext structure with data like memory allocation for global classes (ClassTable structures in
a RedBlack tree), global variables, uid/gid/pid of the process etc. among
others. In other words, it saves current execution context.
(gdb)
224 GenericAgentConfigApply(ctx, config); ---> sets soft classes
defined via -D option, these classes are set with "default namespace" scope i.e they
are set until the agent exits.
(gdb)
223 EvalContext *ctx = EvalContextNew();
(gdb)
224 GenericAgentConfigApply(ctx, config);
(gdb)
226 GenericAgentDiscoverContext(ctx, config); ---> defined in
libpromises/generic_agent.c, it discovers hard classes using functions like
DetectEnvironment() defined in libenv/sysinfo.c
(gdb)
Detaching after fork from child process 15648.
228 Policy *policy = SelectAndLoadPolicy(config, ctx, ALWAYS_VALIDATE,
true); ---> defined in libpromises/generic_agent.c, checks validity of the
policies and writes /var/cfengine/state/cf_promises_validated with the
current timestamp on success
(gdb)
Detaching after fork from child process 15650.
230 if (!policy)
(gdb)
228 Policy *policy = SelectAndLoadPolicy(config, ctx, ALWAYS_VALIDATE, true);
(gdb)
230 if (!policy)
(gdb)
236 GenericAgentPostLoadInit(ctx); ---> initializes a TLS client
(gdb)
237 ThisAgentInit(); ---> sets umask to 077
(gdb)
239 BeginAudit(); ---> sets END_AUDIT_REQUIRED to true
(gdb)
240 KeepPromises(ctx, policy, config); ---> evaluates control
promises and then evaluates bundles promises. KeepPromiseBundles() is used
for evaluating bundle promises one at a time
(gdb)
222 GenericAgentConfig *config = CheckOpts(argc, argv);
(gdb)
240 KeepPromises(ctx, policy, config);
(gdb)
R: this should not happen
242 if (ALLCLASSESREPORT) ---> if configured, writes to
allclasses.txt with names of classes from the ClassTable
(gdb)
247 Nova_TrackExecution(config->input_file);
(gdb)
250 UpdatePackagesCache(ctx, false); ---> updates cache of installed
packages
(gdb)
252 GenerateReports(config, ctx);
(gdb)
254 PurgeLocks();
(gdb)
255 BackupLockDatabase();
(gdb)
257 PolicyDestroy(policy); /* Can we safely do this earlier ? */
(gdb)
259 if (config->agent_specific.agent.bootstrap_policy_server && !VerifyBootstrap())
(gdb)
258 int ret = 0;
(gdb)
266 EndAudit(ctx, CFA_BACKGROUND);
(gdb)
268 Nova_NoteAgentExecutionPerformance(config->input_file, start);
(gdb)
270 GenericAgentFinalize(ctx, config); ---> destroys TLS channel,
frees datastructures like config and EvalContext
(gdb)
277 }
(gdb)

Advertisements

About admin_xor

Un*x/Linux junkie, loves to program, automate, automate and automate
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s