From nobody@FreeBSD.org  Tue Nov 30 08:49:32 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 680371065673
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Nov 2010 08:49:32 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (unknown [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 56D4B8FC1A
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Nov 2010 08:49:32 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id oAU8nVTT092602
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Nov 2010 08:49:31 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id oAU8nVLX092601;
	Tue, 30 Nov 2010 08:49:31 GMT
	(envelope-from nobody)
Message-Id: <201011300849.oAU8nVLX092601@red.freebsd.org>
Date: Tue, 30 Nov 2010 08:49:31 GMT
From: Alexander Brovikov <alexander@brovikov.ru>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] net/asterisk using 100% cpu with .call files
X-Send-Pr-Version: www-3.1
X-GNATS-Notify: flo@smeets.im

>Number:         152700
>Category:       ports
>Synopsis:       [patch] net/asterisk using 100% cpu with .call files
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 30 08:50:09 UTC 2010
>Closed-Date:    Tue Nov 30 17:07:18 UTC 2010
>Last-Modified:  Tue Nov 30 17:10:11 UTC 2010
>Originator:     Alexander Brovikov
>Release:        8.1-RELEASE
>Organization:
>Environment:
FreeBSD vbox 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010     root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
When I try to initiate a call using .call-file, asterisk start eating 100% cpu.
>How-To-Repeat:
Initiate a call with call-file.
>Fix:
I googled for solution and find bug @ digium:
https://bugs.digium.com/view.php?id=18089

This patch from there fixed my problem:
https://bugs.digium.com/file_download.php?file_id=27546&type=bug

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->feedback 
State-Changed-By: edwin 
State-Changed-When: Tue Nov 30 08:50:14 UTC 2010 
State-Changed-Why:  
Awaiting maintainers feedback (via the GNATS Auto Assign Tool) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152700 

From: Edwin Groothuis <edwin@FreeBSD.org>
To: flo@smeets.im
Cc: bug-followup@FreeBSD.org
Subject: Re: ports/152700: [patch] net/asterisk using 100% cpu with .call files
Date: Tue, 30 Nov 2010 08:50:12 UT

 Maintainer of net/asterisk,
 
 Please note that PR ports/152700 has just been submitted.
 
 If it contains a patch for an upgrade, an enhancement or a bug fix
 you agree on, reply to this email stating that you approve the patch
 and a committer will take care of it.
 
 The full text of the PR can be found at:
     http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/152700
 
 -- 
 Edwin Groothuis via the GNATS Auto Assign Tool
 edwin@FreeBSD.org

From: Florian Smeets <flo@smeets.im>
To: Alexander Brovikov <alexander@brovikov.ru>
Cc: bug-followup@FreeBSD.org, Max Khon <fjoe@samodelkin.net>
Subject: Re: ports/152700: [patch] net/asterisk using 100% cpu with .call
 files
Date: Tue, 30 Nov 2010 11:37:43 +0100

 This is a multi-part message in MIME format.
 --------------000202090605060700080204
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
 Hi Max,
 
 can you please commit the attached patch to net/asterisk as a workaround
 to digium bug 18089. This will be in 1.8.1.
 
 Thanks,
 Florian
 
 -- 
 Florian Smeets
 
 --------------000202090605060700080204
 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
  name="asterisk.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="asterisk.diff"
 
 ===> Generating patch
 ===> Viewing diff with more
 diff -ruN --exclude=CVS /usr/ports/net/asterisk.orig/Makefile /usr/ports/net/asterisk/Makefile
 --- /usr/ports/net/asterisk.orig/Makefile	2010-11-30 11:31:52.000000000 +0100
 +++ /usr/ports/net/asterisk/Makefile	2010-11-30 11:32:15.000000000 +0100
 @@ -7,6 +7,7 @@
  
  PORTNAME=	asterisk
  PORTVERSION=	1.8.0
 +PORTREVISION=	1
  CATEGORIES=	net
  MASTER_SITES=	http://downloads.asterisk.org/pub/telephony/asterisk/ \
  		http://downloads.asterisk.org/pub/telephony/asterisk/old-releases/
 diff -ruN --exclude=CVS /usr/ports/net/asterisk.orig/files/patch-pbx__pbx_spool.c /usr/ports/net/asterisk/files/patch-pbx__pbx_spool.c
 --- /usr/ports/net/asterisk.orig/files/patch-pbx__pbx_spool.c	1970-01-01 01:00:00.000000000 +0100
 +++ /usr/ports/net/asterisk/files/patch-pbx__pbx_spool.c	2010-11-30 11:14:30.000000000 +0100
 @@ -0,0 +1,240 @@
 +--- ./pbx/pbx_spool.c.orig	2010-10-18 17:32:40.000000000 +0200
 ++++ ./pbx/pbx_spool.c	2010-11-30 11:14:19.000000000 +0100
 +@@ -26,11 +26,6 @@
 + 
 + ASTERISK_FILE_VERSION(__FILE__, "$Revision: 292083 $")
 + 
 +-/* Handling of call files using inotify is not functioning correctly currently:
 +- * Issue 18089 - https://issues.asterisk.org/view.php?id=18089 
 +- */
 +-#undef HAVE_INOTIFY
 +-
 + #include <sys/stat.h>
 + #include <time.h>
 + #include <utime.h>
 +@@ -67,7 +62,7 @@
 + 	 */
 + 	SPOOL_FLAG_ALWAYS_DELETE = (1 << 0),
 + 	/* Don't unlink the call file after processing, move in qdonedir */
 +-	SPOOL_FLAG_ARCHIVE = (1 << 1)
 ++	SPOOL_FLAG_ARCHIVE = (1 << 1),
 + };
 + 
 + static char qdir[255];
 +@@ -260,24 +255,18 @@
 + 
 + static void safe_append(struct outgoing *o, time_t now, char *s)
 + {
 +-	int fd;
 + 	FILE *f;
 +-	struct utimbuf tbuf;
 +-
 +-	if ((fd = open(o->fn, O_WRONLY | O_APPEND)) < 0)
 +-		return;
 ++	struct utimbuf tbuf = { .actime = now, .modtime = now + o->retrytime };
 + 
 +-	if ((f = fdopen(fd, "a"))) {
 ++	if ((f = fopen(o->fn, "a"))) {
 + 		fprintf(f, "\n%s: %ld %d (%ld)\n", s, (long)ast_mainpid, o->retries, (long) now);
 + 		fclose(f);
 +-	} else
 +-		close(fd);
 ++	}
 + 
 + 	/* Update the file time */
 +-	tbuf.actime = now;
 +-	tbuf.modtime = now + o->retrytime;
 +-	if (utime(o->fn, &tbuf))
 ++	if (utime(o->fn, &tbuf)) {
 + 		ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", o->fn, strerror(errno));
 ++	}
 + }
 + 
 + /*!
 +@@ -288,7 +277,6 @@
 +  */
 + static int remove_from_queue(struct outgoing *o, const char *status)
 + {
 +-	int fd;
 + 	FILE *f;
 + 	char newfn[256];
 + 	const char *bname;
 +@@ -297,8 +285,9 @@
 + 		struct stat current_file_status;
 + 
 + 		if (!stat(o->fn, &current_file_status)) {
 +-			if (time(NULL) < current_file_status.st_mtime)
 ++			if (time(NULL) < current_file_status.st_mtime) {
 + 				return 0;
 ++			}
 + 		}
 + 	}
 + 
 +@@ -313,26 +302,28 @@
 + 		return -1;
 + 	}
 + 
 +-	if ((fd = open(o->fn, O_WRONLY | O_APPEND))) {
 +-		if ((f = fdopen(fd, "a"))) {
 +-			fprintf(f, "Status: %s\n", status);
 +-			fclose(f);
 +-		} else
 +-			close(fd);
 ++	if (!(bname = strrchr(o->fn, '/'))) {
 ++		bname = o->fn;
 ++	} else {
 ++		bname++;
 + 	}
 + 
 +-	if (!(bname = strrchr(o->fn, '/')))
 +-		bname = o->fn;
 +-	else
 +-		bname++;	
 + 	snprintf(newfn, sizeof(newfn), "%s/%s", qdonedir, bname);
 + 	/* a existing call file the archive dir is overwritten */
 + 	unlink(newfn);
 + 	if (rename(o->fn, newfn) != 0) {
 + 		unlink(o->fn);
 + 		return -1;
 +-	} else
 +-		return 0;
 ++	}
 ++
 ++	/* Only append to the file AFTER we move it out of the watched directory,
 ++	 * otherwise the fclose() causes another event for inotify(7) */
 ++	if ((f = fopen(newfn, "a"))) {
 ++		fprintf(f, "Status: %s\n", status);
 ++		fclose(f);
 ++	}
 ++
 ++	return 0;
 + }
 + 
 + static void *attempt_thread(void *data)
 +@@ -399,7 +390,7 @@
 + 	}
 + 
 + 	/* Attempt to open the file */
 +-	if (!(f = fopen(fn, "r+"))) {
 ++	if (!(f = fopen(fn, "r"))) {
 + 		remove_from_queue(o, "Failed");
 + 		free_outgoing(o);
 + 		ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno));
 +@@ -414,7 +405,7 @@
 + 		fclose(f);
 + 		return -1;
 + 	}
 +-	
 ++
 + #if 0
 + 	printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
 + #endif
 +@@ -432,7 +423,7 @@
 + 			   so abort their retry and continue as we were... */
 + 			if (o->callingpid)
 + 				safe_append(o, time(NULL), "AbortRetry");
 +-			
 ++
 + 			safe_append(o, now, "StartRetry");
 + 			launch_service(o);
 + 		}
 +@@ -455,6 +446,7 @@
 + 
 + /* Only one thread is accessing this list, so no lock is necessary */
 + static AST_LIST_HEAD_NOLOCK_STATIC(dirlist, direntry);
 ++static AST_LIST_HEAD_NOLOCK_STATIC(createlist, direntry);
 + 
 + static void queue_file(const char *filename, time_t when)
 + {
 +@@ -482,14 +474,12 @@
 + 		when = st.st_mtime;
 + 	}
 + 
 +-#ifndef HAVE_INOTIFY
 +-	/* Need to check the existing list for kqueue(2), in order to avoid duplicates. */
 ++	/* Need to check the existing list in order to avoid duplicates. */
 + 	AST_LIST_TRAVERSE(&dirlist, cur, list) {
 + 		if (cur->mtime == when && !strcmp(filename, cur->name)) {
 + 			return;
 + 		}
 + 	}
 +-#endif
 + 
 + 	if ((res = when) > now || (res = scan_service(filename, now)) > 0) {
 + 		if (!(new = ast_calloc(1, sizeof(*new) + strlen(filename) + 1))) {
 +@@ -517,6 +507,40 @@
 + 	}
 + }
 + 
 ++#ifdef HAVE_INOTIFY
 ++static void queue_file_create(const char *filename)
 ++{
 ++	struct direntry *cur;
 ++
 ++	AST_LIST_TRAVERSE(&createlist, cur, list) {
 ++		if (!strcmp(cur->name, filename)) {
 ++			return;
 ++		}
 ++	}
 ++
 ++	if (!(cur = ast_calloc(1, sizeof(*cur) + strlen(filename) + 1))) {
 ++		return;
 ++	}
 ++	strcpy(cur->name, filename);
 ++	AST_LIST_INSERT_TAIL(&createlist, cur, list);
 ++}
 ++
 ++static void queue_file_write(const char *filename)
 ++{
 ++	struct direntry *cur;
 ++	/* Only queue entries where an IN_CREATE preceded the IN_CLOSE_WRITE */
 ++	AST_LIST_TRAVERSE_SAFE_BEGIN(&createlist, cur, list) {
 ++		if (!strcmp(cur->name, filename)) {
 ++			AST_LIST_REMOVE_CURRENT(list);
 ++			ast_free(cur);
 ++			queue_file(filename, 0);
 ++			break;
 ++		}
 ++	}
 ++	AST_LIST_TRAVERSE_SAFE_END
 ++}
 ++#endif
 ++
 + static void *scan_thread(void *unused)
 + {
 + 	DIR *dir;
 +@@ -557,7 +581,7 @@
 + 	}
 + 
 + #ifdef HAVE_INOTIFY
 +-	inotify_add_watch(inotify_fd, qdir, IN_CLOSE_WRITE | IN_MOVED_TO);
 ++	inotify_add_watch(inotify_fd, qdir, IN_CREATE | IN_CLOSE_WRITE | IN_MOVED_TO);
 + #endif
 + 
 + 	/* First, run through the directory and clear existing entries */
 +@@ -567,7 +591,7 @@
 + 	}
 + 
 + #ifndef HAVE_INOTIFY
 +-	EV_SET(&kev, dirfd(dir), EVFILT_VNODE, EV_ADD | EV_ENABLE, NOTE_WRITE | NOTE_EXTEND | NOTE_DELETE | NOTE_REVOKE | NOTE_ATTRIB, 0, NULL);
 ++	EV_SET(&kev, dirfd(dir), EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, NULL);
 + 	if (kevent(inotify_fd, &kev, 1, NULL, 0, &nowait) < 0 && errno != 0) {
 + 		ast_log(LOG_ERROR, "Unable to watch directory %s: %s\n", qdir, strerror(errno));
 + 	}
 +@@ -598,7 +622,15 @@
 + 				(res = read(inotify_fd, &buf, sizeof(buf))) >= sizeof(buf.iev)) {
 + 				/* File(s) added to directory, add them to my list */
 + 				do {
 +-					queue_file(buf.iev.name, 0);
 ++					if (buf.iev.mask & IN_CREATE) {
 ++						queue_file_create(buf.iev.name);
 ++					} else if (buf.iev.mask & IN_CLOSE_WRITE) {
 ++						queue_file_write(buf.iev.name);
 ++					} else if (buf.iev.mask & IN_MOVED_TO) {
 ++						queue_file(buf.iev.name, 0);
 ++					} else {
 ++						ast_log(LOG_ERROR, "Unexpected event %d for file '%s'\n", (int) buf.iev.mask, buf.iev.name);
 ++					}
 + 					res -= sizeof(buf.iev) + buf.iev.len;
 + 					if (res >= sizeof(buf.iev)) {
 + 						memmove(&buf.iev, &buf.iev.name[buf.iev.len], res);
 ===> Done
 
 --------------000202090605060700080204--

From: Florian Smeets <flo@smeets.im>
To: Max Khon <fjoe@samodelkin.net>
Cc: Alexander Brovikov <alexander@brovikov.ru>, bug-followup@freebsd.org
Subject: Re: ports/152700: [patch] net/asterisk using 100% cpu with .call
 files
Date: Tue, 30 Nov 2010 17:05:30 +0100

 On 30.11.10 16:55, Max Khon wrote:
 > Florian,
 > 
 > On Tue, Nov 30, 2010 at 4:37 PM, Florian Smeets <flo@smeets.im> wrote:
 > 
 > 
 >> can you please commit the attached patch to net/asterisk as a workaround
 >> to digium bug 18089. This will be in 1.8.1.
 >>
 > 
 > Are you sure that the reference to Digium bug id is correct?
 > https://issues.asterisk.org/view.php?id=18089
 > 
 
 The patch is the one attached to that bug id, and Alexander said the
 patch fixes his problem. He also mentioned it in his original message.
 
 So i guess, yes.
 
 However for me it would be OK to just wait for 1.8.1.
 
 Cheers,
 Florian
 -- 
 Florian Smeets

From: Max Khon <fjoe@samodelkin.net>
To: Florian Smeets <flo@smeets.im>
Cc: Alexander Brovikov <alexander@brovikov.ru>, bug-followup@freebsd.org
Subject: Re: ports/152700: [patch] net/asterisk using 100% cpu with .call files
Date: Tue, 30 Nov 2010 21:55:20 +0600

 --00163631002f3aba4b049647376e
 Content-Type: text/plain; charset=ISO-8859-1
 
 Florian,
 
 On Tue, Nov 30, 2010 at 4:37 PM, Florian Smeets <flo@smeets.im> wrote:
 
 
 > can you please commit the attached patch to net/asterisk as a workaround
 > to digium bug 18089. This will be in 1.8.1.
 >
 
 Are you sure that the reference to Digium bug id is correct?
 https://issues.asterisk.org/view.php?id=18089
 
 Max
 
 --00163631002f3aba4b049647376e
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 Florian,<br><br><div class=3D"gmail_quote">On Tue, Nov 30, 2010 at 4:37 PM,=
  Florian Smeets <span dir=3D"ltr">&lt;<a href=3D"mailto:flo@smeets.im">flo@=
 smeets.im</a>&gt;</span> wrote:<br><div>=A0</div><blockquote class=3D"gmail=
 _quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204,=
  204, 204); padding-left: 1ex;">
 
 can you please commit the attached patch to net/asterisk as a workaround<br=
 >
 to digium bug 18089. This will be in 1.8.1.<br></blockquote></div><br>Are y=
 ou sure that the reference to Digium bug id is correct?<br><a href=3D"https=
 ://issues.asterisk.org/view.php?id=3D18089">https://issues.asterisk.org/vie=
 w.php?id=3D18089</a><br>
 <br>Max<br><br>
 
 --00163631002f3aba4b049647376e--
State-Changed-From-To: feedback->closed 
State-Changed-By: fjoe 
State-Changed-When: Tue Nov 30 17:06:11 UTC 2010 
State-Changed-Why:  
Committed, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152700 

From: Alexander Brovikov <alexander@brovikov.ru>
To: bug-followup@freebsd.org, alexander@brovikov.ru
Cc:  
Subject: Re: ports/152700: [patch] net/asterisk using 100% cpu with .call files
Date: Tue, 30 Nov 2010 21:38:09 +0500

 Yes, with this patch all works ok for me.
 While inotify is linux-only lib, apparently, at some point in time
 call-file mechanism was broken (there were several bugs related) and
 fixed (finally?) with this patch.

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/152700: commit references a PR
Date: Tue, 30 Nov 2010 17:06:48 +0000 (UTC)

 fjoe        2010-11-30 17:06:42 UTC
 
   FreeBSD ports repository
 
   Modified files:
     net/asterisk         Makefile 
   Added files:
     net/asterisk/files   patch-pbx__pbx_spool.c 
   Log:
   Fix 100% CPU use with .call files
   (upstream issue https://issues.asterisk.org/view.php?id=18089)
   
   The patch will be included in asterisk 1.8.1.
   
   PR:             152700
   Submitted by:   Florian Smeets (MAINTAINER)
   
   Revision  Changes    Path
   1.132     +1 -0      ports/net/asterisk/Makefile
   1.1       +240 -0    ports/net/asterisk/files/patch-pbx__pbx_spool.c (new)
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
