Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change: Wait for SecInfo sync before unlocking feed lock #2202

Merged
merged 2 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/gvmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1179,11 +1179,13 @@ update_nvt_cache_retry ()
/**
* @brief Update the NVT cache in a child process.
*
* @param[out] child_pid_out Optional output param for child PID.
*
* @return 0 success, 1 update in progress, -1 error. Always exits with
* EXIT_SUCCESS in child.
*/
static int
fork_update_nvt_cache ()
fork_update_nvt_cache (pid_t *child_pid_out)
{
int pid;
sigset_t sigmask_all, sigmask_current;
Expand All @@ -1210,6 +1212,8 @@ fork_update_nvt_cache ()
}

pid = fork_with_handlers ();
if (child_pid_out)
*child_pid_out = pid;
switch (pid)
{
case 0:
Expand Down
13 changes: 9 additions & 4 deletions src/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -5064,7 +5064,7 @@ feed_sync_required ()
*/
void
manage_sync (sigset_t *sigmask_current,
int (*fork_update_nvt_cache) (),
int (*fork_update_nvt_cache) (pid_t*),
gboolean try_gvmd_data_sync)
{
lockfile_t lockfile;
Expand All @@ -5076,9 +5076,14 @@ manage_sync (sigset_t *sigmask_current,
{
if (feed_lockfile_lock (&lockfile) == 0)
{
manage_sync_nvts (fork_update_nvt_cache);
manage_sync_scap (sigmask_current);
manage_sync_cert (sigmask_current);
pid_t nvts_pid, scap_pid, cert_pid;
nvts_pid = manage_sync_nvts (fork_update_nvt_cache);
scap_pid = manage_sync_scap (sigmask_current);
cert_pid = manage_sync_cert (sigmask_current);

wait_for_pid (nvts_pid, "NVTs sync");
wait_for_pid (scap_pid, "SCAP sync");
wait_for_pid (cert_pid, "CERT sync");

lockfile_unlock (&lockfile);
}
Expand Down
2 changes: 1 addition & 1 deletion src/manage.h
Original file line number Diff line number Diff line change
Expand Up @@ -2853,7 +2853,7 @@ void
set_scheduled_user_uuid (const gchar* uuid);

void
manage_sync (sigset_t *, int (*fork_update_nvt_cache) (), gboolean);
manage_sync (sigset_t *, int (*fork_update_nvt_cache) (pid_t*), gboolean);

int
manage_rebuild_gvmd_data_from_feed (const char *,
Expand Down
10 changes: 7 additions & 3 deletions src/manage_sql_nvts.c
Original file line number Diff line number Diff line change
Expand Up @@ -2390,11 +2390,15 @@ manage_update_nvt_cache_osp (const gchar *update_socket)
* @brief Sync NVTs if newer NVTs are available.
*
* @param[in] fork_update_nvt_cache Function to do the update.
*
* @return PID of the forked process handling the VTs sync, -1 on error.
*/
void
manage_sync_nvts (int (*fork_update_nvt_cache) ())
pid_t
manage_sync_nvts (int (*fork_update_nvt_cache) (pid_t*))
{
fork_update_nvt_cache ();
pid_t child_pid = -1;
fork_update_nvt_cache (&child_pid);
return child_pid;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/manage_sql_nvts.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ check_db_nvts ();
int
check_config_families ();

void
manage_sync_nvts (int (*) ());
pid_t
manage_sync_nvts (int (*) (pid_t*));

int
update_or_rebuild_nvts (int);
Expand Down
28 changes: 17 additions & 11 deletions src/manage_sql_secinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2999,8 +2999,10 @@ manage_db_reinit (const gchar *name)
* @param[in] sigmask_current Sigmask to restore in child.
* @param[in] update Function to do the sync.
* @param[in] process_title Process title.
*
* @return PID of the forked process handling the SecInfo sync, -1 on error.
*/
static void
static pid_t
sync_secinfo (sigset_t *sigmask_current, int (*update) (void),
const gchar *process_title)
{
Expand Down Expand Up @@ -3038,11 +3040,11 @@ sync_secinfo (sigset_t *sigmask_current, int (*update) (void),
case -1:
/* Parent on error. Reschedule and continue to next task. */
g_warning ("%s: fork failed", __func__);
return;
return -1;

default:
/* Parent. Continue to next task. */
return;
return pid;

}

Expand Down Expand Up @@ -3439,13 +3441,15 @@ sync_cert ()
* @brief Sync the CERT DB.
*
* @param[in] sigmask_current Sigmask to restore in child.
*
* @return PID of the forked process handling the CERT sync, -1 on error.
*/
void
pid_t
manage_sync_cert (sigset_t *sigmask_current)
{
sync_secinfo (sigmask_current,
sync_cert,
"Syncing CERT");
return sync_secinfo (sigmask_current,
sync_cert,
"Syncing CERT");
}


Expand Down Expand Up @@ -3921,13 +3925,15 @@ sync_scap ()
* @brief Sync the SCAP DB.
*
* @param[in] sigmask_current Sigmask to restore in child.
*
* @return PID of the forked process handling the SCAP sync, -1 on error.
*/
void
pid_t
manage_sync_scap (sigset_t *sigmask_current)
{
sync_secinfo (sigmask_current,
sync_scap,
"Syncing SCAP");
return sync_secinfo (sigmask_current,
sync_scap,
"Syncing SCAP");
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/manage_sql_secinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@
int
secinfo_feed_version_status ();

void
pid_t
manage_sync_scap (sigset_t *);

int
manage_rebuild_scap (GSList *, const db_conn_info_t *);

void
pid_t
manage_sync_cert (sigset_t *);

int
Expand Down
53 changes: 53 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#include <gvm/base/gvm_sentry.h>
Expand Down Expand Up @@ -906,3 +907,55 @@ fork_with_handlers ()
}
return pid;
}

/**
* @brief Waits for a process with the given PID, retrying if interrupted.
*
* If the wait is interrupted or the process does not exist, only debug
* messages are logged.
*
* @param[in] pid The pid to wait for.
* @param[in] context Short context desciption for error and debug messages.
*/
void
wait_for_pid (pid_t pid, const char *context)
{
gboolean retry = TRUE;
const char *shown_context = context ? context : "unknown context";
if (pid <= 0)
{
g_message ("%s: No PID given (%s)", __func__, shown_context);
return;
}

while (retry)
{
retry = FALSE;
pid_t ret = waitpid (pid, NULL, 0);
if (ret <= 0)
{
int err = errno;
if (errno == ECHILD)
{
g_debug ("%s: process with PID %d (%s) does not exist",
__func__, pid, shown_context);
}
else if (errno == EINTR)
{
g_debug ("%s: waitpid interrupted for PID %d (%s), retrying...",
__func__, pid, shown_context);
retry = TRUE;
}
else
{
g_warning ("%s: waitpid failed for PID %d (%s): %s",
__func__, pid, shown_context, strerror(err));
}
}
else
{
g_debug ("%s: wait for PID %d (%s) successful",
__func__, pid, shown_context);
}
}
}
3 changes: 3 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,7 @@ setup_signal_handler_info (int, void (*) (int, siginfo_t *, void *), int);
int
fork_with_handlers ();

void
wait_for_pid (pid_t, const char *);

#endif /* not _GVMD_UTILS_H */
Loading