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 .work if
662: * it opens 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