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

Fix interrupted scans #832

Merged
merged 7 commits into from
Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Deprecated
### Removed
### Fixed
Fix interrupted scan, when the process table is full. [#832](https://github.com/greenbone/openvas-scanner/pull/832)

[21.4.3]: https://github.com/greenbone/openvas-scanner/compare/v21.4.2...gvmd-21.04

Expand Down
17 changes: 14 additions & 3 deletions src/attack.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,10 @@ launch_plugin (struct scan_globals *globals, struct scheduler_plugin *plugin,
if (pid < 0)
{
plugin->running_state = PLUGIN_STATUS_UNRUN;
ret = ERR_CANT_FORK;
if (pid == ERR_NO_FREE_SLOT)
jjnicola marked this conversation as resolved.
Show resolved Hide resolved
ret = ERR_NO_FREE_SLOT;
else
ret = ERR_CANT_FORK;
goto finish_launch_plugin;
}

Expand Down Expand Up @@ -519,13 +522,21 @@ attack_host (struct scan_globals *globals, struct in6_addr *ip, GSList *vhosts,
kb_item_push_str (main_kb, "internal/results", buffer);
goto host_died;
}
else if (e == ERR_NO_FREE_SLOT)
{
g_debug (
"fork() failed for %s. Not free slot to run a plugin.",
jjnicola marked this conversation as resolved.
Show resolved Hide resolved
plugin->oid);
goto again;
}
else if (e == ERR_CANT_FORK)
{
if (forks_retry < MAX_FORK_RETRIES)
{
forks_retry++;
g_debug ("fork() failed - sleeping %d seconds (%s)",
forks_retry, strerror (errno));
g_debug (
"fork() failed for %s - sleeping %d seconds (%s)",
plugin->oid, forks_retry, strerror (errno));
fork_sleep (forks_retry);
goto again;
}
Expand Down
25 changes: 20 additions & 5 deletions src/pluginlaunch.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ simult_ports (const char *oid, const char *next_oid)
/**
* If another NVT with same port requirements is running, wait.
*
* @return -1 if MAX_PROCESSES are running, the index of the first free "slot"
* in the processes array otherwise.
* @return ERR_NO_FREE_SLOT if MAX_PROCESSES are running, the index of the first
* free "slot" in the processes array otherwise.
*/
static int
next_free_process (kb_t kb, struct scheduler_plugin *upcoming)
Expand All @@ -262,7 +262,7 @@ next_free_process (kb_t kb, struct scheduler_plugin *upcoming)
for (r = 0; r < MAX_PROCESSES; r++)
if (processes[r].pid <= 0)
return r;
return -1;
return ERR_NO_FREE_SLOT;
}

void
Expand Down Expand Up @@ -402,7 +402,15 @@ plugin_launch (struct scan_globals *globals, struct scheduler_plugin *plugin,
pluginlaunch_wait_for_free_process (main_kb);
p = next_free_process (main_kb, plugin);
if (p < 0)
return -1;
{
g_debug ("There are currently no free slot for running a new plugins, "
jjnicola marked this conversation as resolved.
Show resolved Hide resolved
"probably because the parallel check is temporally disabled. "
jjnicola marked this conversation as resolved.
Show resolved Hide resolved
"Current parallel checks: %d. Old parallel checks: %d",
max_running_processes, old_max_running_processes);
usleep (250000);
return ERR_NO_FREE_SLOT;
}

processes[p].plugin = plugin;
processes[p].timeout = plugin_timeout (nvti);
gettimeofday (&(processes[p].start), NULL);
Expand Down Expand Up @@ -461,8 +469,15 @@ pluginlaunch_wait_for_free_process (kb_t kb)
update_running_processes (kb);
/* Max number of processes are still running, wait for a child to exit or
* to timeout. */

if (num_running_processes >= max_running_processes)
g_debug ("%s. Number of running processes >= maximum running processes (%d "
">= %d). "
"Waitting for free slot for processes.",
jjnicola marked this conversation as resolved.
Show resolved Hide resolved
__func__, num_running_processes, max_running_processes);

while (
(num_running_processes == max_running_processes)
(num_running_processes >= max_running_processes)
|| (num_running_processes > 0 && (check_memory () || check_sysload ())))
{
sigset_t mask;
Expand Down
5 changes: 5 additions & 0 deletions src/pluginlaunch.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
#include "pluginload.h" /* for struct pl_class_t */
#include "pluginscheduler.h" /* for struct plugins_scheduler_t */

/**
* @brief Error for max. number of concurrent plugins per host reached.
*/
#define ERR_NO_FREE_SLOT -99

void
pluginlaunch_init (const char *);
void pluginlaunch_wait (kb_t);
Expand Down