Skip to content

Commit cb3a49a

Browse files
committed
Add a new '--with-runagent-socket' option to cf-execd
Allowing specification of directory where to create the runagent.socket or "no" to disable the runagent socket functionality. Use the new option to avoid issues with the runagent socket in cf-execd acceptance tests. Ticket: ENT-6182 Changelog: None
1 parent 9dc32cd commit cb3a49a

File tree

2 files changed

+77
-47
lines changed

2 files changed

+77
-47
lines changed

cf-execd/cf-execd.c

Lines changed: 76 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static int NO_FORK = false; /* GLOBAL_A */
7474
static int ONCE = false; /* GLOBAL_A */
7575
static int WINSERVICE = true; /* GLOBAL_A */
7676

77+
static char *RUNAGENT_SOCKET_DIR = NULL;
78+
7779
static pthread_attr_t threads_attrs; /* GLOBAL_T, initialized by pthread_attr_init */
7880

7981
/*******************************************************************/
@@ -126,6 +128,7 @@ static const struct option OPTIONS[] =
126128
{"color", optional_argument, 0, 'C'},
127129
{"timestamp", no_argument, 0, 'l'},
128130
{"skip-db-check", optional_argument, 0, 0 },
131+
{"with-runagent-socket", required_argument, 0, 0},
129132
{NULL, 0, 0, '\0'}
130133
};
131134

@@ -150,6 +153,7 @@ static const char *const HINTS[] =
150153
"Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'",
151154
"Log timestamps on each line of log output",
152155
"Do not run database integrity checks and repairs at startup",
156+
"Specify the directory for the socket for runagent requests or 'no' to disable the socket",
153157
NULL
154158
};
155159

@@ -198,6 +202,7 @@ int main(int argc, char *argv[])
198202
GenericAgentFinalize(ctx, config);
199203
ExecConfigDestroy(exec_config);
200204
ExecdConfigDestroy(execd_config);
205+
free(RUNAGENT_SOCKET_DIR);
201206
CallCleanupFunctions();
202207
return 0;
203208
}
@@ -370,6 +375,12 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv)
370375
DoCleanupAndExit(EXIT_FAILURE);
371376
}
372377
}
378+
else if (StringEqual(option_name, "with-runagent-socket"))
379+
{
380+
assert(optarg != NULL); /* required_argument */
381+
RUNAGENT_SOCKET_DIR = xstrdup(optarg);
382+
}
383+
373384
break;
374385
}
375386
default:
@@ -528,6 +539,69 @@ static void CFExecdMainLoop(EvalContext *ctx, Policy **policy, GenericAgentConfi
528539
}
529540
}
530541

542+
static int SetupRunagentSocket()
543+
{
544+
int runagent_socket = -1;
545+
546+
struct sockaddr_un sock_info;
547+
memset(&sock_info, 0, sizeof(sock_info));
548+
549+
/* This can easily fail if GetStateDir() returns some long path,
550+
* 'sock_info.sun_path' is limited to 140 characters or even
551+
* fewer. "/var/cfengine/state" is fine, crazy long temporary state
552+
* directories used in the tests are too long. */
553+
int ret;
554+
if (RUNAGENT_SOCKET_DIR == NULL)
555+
{
556+
ret = snprintf(sock_info.sun_path, sizeof(sock_info.sun_path) - 1,
557+
"%s/cf-execd.sockets/"CF_EXECD_RUNAGENT_SOCKET_NAME, GetStateDir());
558+
}
559+
else
560+
{
561+
ret = snprintf(sock_info.sun_path, sizeof(sock_info.sun_path) - 1,
562+
"%s/"CF_EXECD_RUNAGENT_SOCKET_NAME, RUNAGENT_SOCKET_DIR);
563+
}
564+
if (ret <= (sizeof(sock_info.sun_path) - 1))
565+
{
566+
sock_info.sun_family = AF_LOCAL;
567+
568+
MakeParentDirectory(sock_info.sun_path, true, NULL);
569+
570+
/* Remove potential left-overs from old processes. */
571+
unlink(sock_info.sun_path);
572+
573+
runagent_socket = socket(AF_LOCAL, SOCK_STREAM, 0);
574+
assert(runagent_socket >= 0);
575+
}
576+
if (runagent_socket < 0)
577+
{
578+
Log(LOG_LEVEL_ERR, "Failed to create socket for runagent requests");
579+
}
580+
else
581+
{
582+
ret = bind(runagent_socket, (const struct sockaddr *) &sock_info, sizeof(sock_info));
583+
assert(ret == 0);
584+
if (ret == -1)
585+
{
586+
Log(LOG_LEVEL_ERR, "Failed to bind the runagent socket: %s", GetErrorStr());
587+
close(runagent_socket);
588+
runagent_socket = -1;
589+
}
590+
else
591+
{
592+
ret = listen(runagent_socket, CF_EXECD_RUNAGENT_SOCKET_LISTEN_QUEUE);
593+
assert(ret == 0);
594+
if (ret == -1)
595+
{
596+
Log(LOG_LEVEL_ERR, "Failed to listen on runagent socket: %s", GetErrorStr());
597+
close(runagent_socket);
598+
runagent_socket = -1;
599+
}
600+
}
601+
}
602+
return runagent_socket;
603+
}
604+
531605
#else /* ! __MINGW32__ */
532606

533607
// msg should include exactly one reference to unsigned int.
@@ -623,53 +697,9 @@ void StartServer(EvalContext *ctx, Policy *policy, GenericAgentConfig *config, E
623697
int runagent_socket = -1;
624698

625699
#ifndef __MINGW32__
626-
/* TODO: --with-runagent-socket, "am_policy_server" ??? */
627-
struct sockaddr_un sock_info;
628-
memset(&sock_info, 0, sizeof(sock_info));
629-
630-
/* This can easily fail if GetStateDir() returns some long path,
631-
* 'sock_info.sun_path' is limited to 140 characters or even
632-
* fewer. "/var/cfengine/state" is fine, crazy long temporary state
633-
* directories used in the tests are too long. */
634-
int ret = snprintf(sock_info.sun_path, sizeof(sock_info.sun_path) - 1,
635-
"%s/cf-execd.sockets/"CF_EXECD_RUNAGENT_SOCKET_NAME, GetStateDir());
636-
if (ret <= (sizeof(sock_info.sun_path) - 1))
637-
{
638-
sock_info.sun_family = AF_LOCAL;
639-
640-
MakeParentDirectory(sock_info.sun_path, true, NULL);
641-
642-
/* Remove potential left-overs from old processes. */
643-
unlink(sock_info.sun_path);
644-
645-
runagent_socket = socket(AF_LOCAL, SOCK_STREAM, 0);
646-
assert(runagent_socket >= 0);
647-
}
648-
if (runagent_socket < 0)
649-
{
650-
Log(LOG_LEVEL_ERR, "Failed to create socket for runagent requests");
651-
}
652-
else
700+
if ((RUNAGENT_SOCKET_DIR == NULL) || (!StringEqual_IgnoreCase(RUNAGENT_SOCKET_DIR, "no")))
653701
{
654-
ret = bind(runagent_socket, (const struct sockaddr *) &sock_info, sizeof(sock_info));
655-
assert(ret == 0);
656-
if (ret == -1)
657-
{
658-
Log(LOG_LEVEL_ERR, "Failed to bind the runagent socket: %s", GetErrorStr());
659-
close(runagent_socket);
660-
runagent_socket = -1;
661-
}
662-
else
663-
{
664-
ret = listen(runagent_socket, CF_EXECD_RUNAGENT_SOCKET_LISTEN_QUEUE);
665-
assert(ret == 0);
666-
if (ret == -1)
667-
{
668-
Log(LOG_LEVEL_ERR, "Failed to listen on runagent socket: %s", GetErrorStr());
669-
close(runagent_socket);
670-
runagent_socket = -1;
671-
}
672-
}
702+
runagent_socket = SetupRunagentSocket();
673703
}
674704
#endif
675705

tests/acceptance/25_cf-execd/mailfilter_common.cf.sub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ bundle agent prepare_mailfilter_test(reports, includes, excludes)
3636
bundle agent run_cf_execd(wanted, unwanted)
3737
{
3838
vars:
39-
"cmd" string => "$(this.promise_dirname)/cf-execd-test --once";
39+
"cmd" string => "$(this.promise_dirname)/cf-execd-test --once --with-runagent-socket no";
4040

4141
commands:
4242
"$(cmd) >> $(G.testfile).output"

0 commit comments

Comments
 (0)