rlm_detail and radrelay concurrence

2006-06-15 Thread Michael Chernyakhovsky
hello, everyone

i use radrelay
there are errors in log from rlm_detail like

Error: rlm_detail: Couldn't open file /var/log/radius/radacct/detail-relay: Bad 
file descriptor

while examine rlm_detail.c i found two places in it.
first while open (create if need) detail-file (line 204 rlm_detail.c).
second while do converting the FD to FP (line 243) after aquiring
filelock of detail file.

Bad file description error appear because radrelay
can remove detail file while rad_detail trying to aquire filelock, I
think (line 655 of radrelay.c).

rlm_detail.c:
201:if ((outfd = open(buffer, O_WRONLY | O_APPEND | O_CREAT,
202:  inst-detailperm))  0) {
203:radlog(L_ERR, rlm_detail: Couldn't open file %s: %s,
204:   buffer, strerror(errno));
205:return RLM_MODULE_FAIL;
206:}
208:/*
209: *  If we're not using locking, we'll just pass straight though
210: *  the while loop.
211: *  If we fail to aquire the filelock in 80 tries (approximately
212: *  two seconds) we bail out.
213: */
214:locked = 0;
215:lock_count = 0;
216:do {
  
231:} while (!locked  inst-locking  lock_count  80);
...
239:/*
240: *  Convert the FD to FP.  The FD is no longer valid
241: *  after this operation.
242: */
243:if ((outfp = fdopen(outfd, a)) == NULL) {
244:radlog(L_ERR, rlm_detail: Couldn't open file %s: %s,
245:   buffer, strerror(errno));
246:if (inst-locking) {
247:lseek(outfd, 0L, SEEK_SET);
248:rad_unlockfd(outfd, 0);
249:DEBUG(rlm_detail: Released filelock);
250:}
251:close(outfd);
253:return RLM_MODULE_FAIL;
254:}



radrelay.c:

655:if (detail_move(r_args-detail, work) == 0) {
656:if (debug_flag  0)
657:fprintf(stderr, Moving %s to %s\n,
658:r_args-detail, work);
659:/*
660: *  rlm_detail might still write
661: *  something to detail.work if
662: *  it opens detail before it is
663: *  renamed (race condition)
664: */
665:ms_sleep(1000);
666:state = STATE_BACKLOG;
667:}
668:fpos = ftell(fp);
669:fseek(fp, 0L, SEEK_SET);
670:rad_unlockfd(fileno(fp), 0);
671:fseek(fp, fpos, SEEK_SET);


so detail_move can be called by radrelay while rad_detail already
opens detail (line 201) have outfd and try to aquire lock. after radrelay made
rad_unlockfd(fileno(fp), 0) (line 670), rlm_detail try to fdopen (line
243) and will get error.


As workaround we can give to rlm_detail recreate detail...

--- rlm_detail.c-orig   2006-06-15 12:09:43.0 +0600
+++ rlm_detail.c2006-06-15 12:22:49.0 +0600
@@ -119,6 +119,7 @@
struct stat st;
int locked;
int lock_count;
+   int opencount=0;
struct timeval  tv;
REALM   *proxy_realm;
charproxy_buffer[16];
@@ -195,6 +196,8 @@
*p = '/';
} /* else there was no directory delimiter. */

+
+reopen:
/*
 *  Open  create the file, with the given permissions.
 */
@@ -241,8 +244,9 @@
 *  after this operation.
 */
if ((outfp = fdopen(outfd, a)) == NULL) {
-   radlog(L_ERR, rlm_detail: Couldn't open file %s: %s,
-  buffer, strerror(errno));
+   radlog(L_ERR, rlm_detail: Couldn't open file %s: %s. %s,
+  buffer, strerror(errno),
+  (opencount==0)?try reopen to create:return 
MODULE_FAIL);
if (inst-locking) {
lseek(outfd, 0L, SEEK_SET);
rad_unlockfd(outfd, 0);
@@ -250,7 +254,10 @@
}
close(outfd);

-   return RLM_MODULE_FAIL;
+   if (opencount++ == 0)
+   goto reopen;
+   else
+   return RLM_MODULE_FAIL;
}

/*



btw, why to sleep 1000ms on [EMAIL PROTECTED]
how rlm_detail can write something to detail.work, while file is locked
by radreplay?


Mike.






- 
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html


Re: rlm_detail and radrelay concurrence

2006-06-15 Thread Alan DeKok
Nicolas Baradakis [EMAIL PROTECTED] wrote:
 I think the fixes are in CVS head but they were never included in any
 stable release.

  Whoops, that's a bug.  It should be fixed in both rlm_Detail 
radrelay.

  Alan DEKok.

- 
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html