summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter Doekes <walter+github@wjd.nu>2016-09-19 21:21:23 +0200
committerWalter Doekes <walter+asterisk@wjd.nu>2016-09-20 02:05:27 -0500
commit9372d32100b82669d56fcb147b0f8b2fa10ab529 (patch)
tree4459e554fa98545db15c8e6186208ac99bb61110
parent34461b89ace3742056100bb226a3c0c2d90ca5ff (diff)
asterisk.c: Non-root users also get the astcanary after core restart.
Without this change, a 'core restart' would kill the astcanary forever if you're not running as root. Both with and without this patch, the scheduling priority was still SCHED_RR after restart. Additionally, the astcanary is now spawned if you start with high priority and Asterisk doesn't get a chance to lower it. For example through: `chrt -r 10 sudo -u asterisk asterisk -c` Also reap killed astcanary processes on core restart. ASTERISK-26352 #close Change-Id: Iacb49f26491a0717084ad46ed96b0bea5f627a55
-rw-r--r--main/asterisk.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/main/asterisk.c b/main/asterisk.c
index 69f1d7140..e4c793147 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -1863,6 +1863,26 @@ static void set_icon(char *text)
fprintf(stdout, "\033]1;%s\007", text);
}
+/*! \brief Check whether we were set to high(er) priority. */
+static int has_priority(void)
+{
+ /* Neither of these calls should fail with these arguments. */
+#ifdef __linux__
+ /* For SCHED_OTHER, SCHED_BATCH and SCHED_IDLE, this will return
+ * 0. For the realtime priorities SCHED_RR and SCHED_FIFO, it
+ * will return something >= 1. */
+ return sched_getscheduler(0);
+#else
+ /* getpriority() can return a value in -20..19 (or even -INF..20)
+ * where negative numbers are high priority. We don't bother
+ * checking errno. If the query fails and it returns -1, we'll
+ * assume that we're running at high prio; a safe assumption
+ * that will enable the resource starvation monitor (canary)
+ * just in case. */
+ return (getpriority(PRIO_PROCESS, 0) < 0);
+#endif
+}
+
/*! \brief Set priority on all known threads. */
static int set_priority_all(int pri)
{
@@ -3884,8 +3904,11 @@ static void *canary_thread(void *unused)
/* Used by libc's atexit(3) function */
static void canary_exit(void)
{
- if (canary_pid > 0)
+ if (canary_pid > 0) {
+ int status;
kill(canary_pid, SIGKILL);
+ waitpid(canary_pid, &status, 0);
+ }
}
/* Execute CLI commands on startup. Run by main() thread. */
@@ -4392,8 +4415,16 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou
__ast_mm_init_phase_1();
#endif /* defined(__AST_DEBUG_MALLOC) */
+ /* Check whether high prio was succesfully set by us or some
+ * other incantation. */
+ if (has_priority()) {
+ ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
+ } else {
+ ast_clear_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
+ }
+
/* Spawning of astcanary must happen AFTER the call to daemon(3) */
- if (isroot && ast_opt_high_priority) {
+ if (ast_opt_high_priority) {
snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
/* Don't let the canary child kill Asterisk, if it dies immediately */