Fwd: Cronie bug (handling of orphans list)
by Marcela Mašláňová
Resending to devel list. Thanks for report.
-------- Forwarded Message --------
Subject: Cronie bug (handling of orphans list)
Date: Sun, 15 Feb 2015 15:45:28 -0600
From: Matt Sheldon <msheldon(a)hostgator.com>
To: mmaslano(a)redhat.com
Hi,
I noticed a bug that seems to affect all versions of cronie since the
orphan handling was added - I could be wrong; I've seen a few changelog
notes that sound related but didn't see changes associated that would
fix it.
The problem is that whenever Cronie reloads and goes through the list of
crons, adding orphaned crons to the orphans list, it doesn't check to
see that the user is already in that list. This means that if you have
100 orphaned files, and over the time crond runs random users do 100
cron edits/updates, there will be 10,000 orphans instead of just the
100. Then check_orphans iterates the list, getpwnam()ing each user. On
servers with many users, getpwnam() can be slow, so it can cause crond
to use 5-10 or more seconds of CPU time calling getpwnam() thousands of
times due to this.
I see the main purpose of orphans originally was so that user crontabs
could be loaded if the user later appeared, instead of waiting until
another crond reload. A fix for this bug would probably be to clear the
orphans list prior to loading the database during these reloads, since
the DB is about to be loaded anyway. Of course iterating the orphans
list to check for matches each time it adds a new orphan is another
option, but may be slower. Most likely I'll be doing the database clear
as a patch for our custom RPM build at Hostgator.
Thanks,
Matt Sheldon
9 years, 2 months
Fwd: [PATCH cronie] database.c: Use POSIX NAME_MAX instead of BSD MAXNAMLEN
by Marcela Mašláňová
-------- Forwarded Message --------
Subject: [PATCH cronie] database.c: Use POSIX NAME_MAX instead of BSD
MAXNAMLEN
Date: Sat, 31 Jan 2015 18:30:10 +0100
From: Felix Janda <felix.janda(a)posteo.de>
To: mmaslano(a)redhat.com
fixes compilation with musl libc
---
Previously tried to send patch to mailing list as a nonsubscriber...
---
src/database.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/database.c b/src/database.c
index 60135ac..2a8f054 100644
--- a/src/database.c
+++ b/src/database.c
@@ -32,6 +32,7 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
@@ -252,7 +253,7 @@ process_crontab(const char *uname, const char
*fname, const char *tabname,
static int
cluster_host_is_local(void)
{
- char filename[MAXNAMLEN+1];
+ char filename[NAME_MAX+1];
int is_local;
FILE *f;
char hostname[MAXHOSTNAMELEN], myhostname[MAXHOSTNAMELEN];
@@ -348,7 +349,7 @@ void check_inotify_database(cron_db * old_db) {
}
else {
while (NULL != (dp = readdir(dir))) {
- char tabname[MAXNAMLEN + 1];
+ char tabname[NAME_MAX + 1];
if (not_a_crontab(dp))
continue;
@@ -366,12 +367,12 @@ void check_inotify_database(cron_db * old_db) {
}
else {
while (NULL != (dp = readdir(dir))) {
- char fname[MAXNAMLEN + 1], tabname[MAXNAMLEN + 1];
+ char fname[NAME_MAX + 1], tabname[NAME_MAX + 1];
if (not_a_crontab(dp))
continue;
- strncpy(fname, dp->d_name, MAXNAMLEN);
+ strncpy(fname, dp->d_name, NAME_MAX);
if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR,
dp->d_name, '/'))
@@ -492,7 +493,7 @@ int load_database(cron_db * old_db) {
}
else {
while (NULL != (dp = readdir(dir))) {
- char tabname[MAXNAMLEN + 1];
+ char tabname[NAME_MAX + 1];
if (not_a_crontab(dp))
continue;
@@ -519,12 +520,12 @@ int load_database(cron_db * old_db) {
is_local = cluster_host_is_local();
while (is_local && NULL != (dp = readdir(dir))) {
- char fname[MAXNAMLEN + 1], tabname[MAXNAMLEN + 1];
+ char fname[NAME_MAX + 1], tabname[NAME_MAX + 1];
if (not_a_crontab(dp))
continue;
- strncpy(fname, dp->d_name, MAXNAMLEN);
+ strncpy(fname, dp->d_name, NAME_MAX);
if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/'))
continue; /* XXX log? */
@@ -601,7 +602,7 @@ static int not_a_crontab(DIR_T * dp) {
len = strlen(dp->d_name);
- if (len >= MAXNAMLEN)
+ if (len >= NAME_MAX)
return (1); /* XXX log? */
if ((len > 0) && (dp->d_name[len - 1] == '~'))
@@ -628,7 +629,7 @@ static void max_mtime(const char *dir_name, struct
stat *max_st) {
}
while (NULL != (dp = readdir(dir))) {
- char tabname[MAXNAMLEN + 1];
+ char tabname[NAME_MAX + 1];
if ( not_a_crontab ( dp ) && strcmp(dp->d_name, CRON_HOSTNAME) != 0)
continue;
--
2.0.4
9 years, 2 months