Skip to content

Commit

Permalink
Change: Wait for SecInfo sync before unlocking feed lock
Browse files Browse the repository at this point in the history
The process starting the various feed sync processes with manage_sync
will now wait for the VT, CERT and SCAP sync processes to finish before
unlocking the feed lockfile.
  • Loading branch information
timopollmeier committed May 27, 2024
1 parent 5c1e51a commit 159ceaa
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 24 deletions.
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);
}
}
}
2 changes: 2 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ 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 */

0 comments on commit 159ceaa

Please sign in to comment.