Package: fam Version: 2.7.0-6 Severity: important
After certain (~250) directories fam stops working. To reproduce run shell script in the attachment to create directory famtestdir with 30 subdirectories, with 30 subdirectories in each of them. Then compile gmonitorrec as $ g++ -o gmonitorrec -lfam gmonitorrec.cc and start gmonitorrec in the directory where famtestdir is located. After starting to monitor ~250 directories (at my machine), fam will refuse to continue working. It will not even return all of the End Exists events (it returns just 8 on my machine). -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.9-1-k7 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages fam depends on: ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries an ii libgcc1 1:3.4.3-6 GCC support library ii libstdc++5 1:3.3.5-8 The GNU Standard C++ Library v3 ii portmap 5-7 The RPC portmapper -- debconf information: fam/init: inetd
famtest
Description: application/shellscript
#include <fam.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
#include <map>
using namespace std;
typedef map<int,string> req_path_map;
int main()
{
int dircount(1);
int endexistcount(0);
int existcount(0);
req_path_map req_path;
FAMConnection m_fc;
if ( FAMOpen( &m_fc ) < 0 )
{
return false;
}
FAMRequest fr;
char *tm = canonicalize_file_name("famtestdir");
string tomonitor(tm);
free(tm);
if(-1 == FAMMonitorDirectory(&m_fc, tomonitor.c_str(), &fr, NULL ))
{
cerr << "fammonitordir(" << tomonitor << ") error detected!!!" << endl;
::exit(1);
}
// FAMMonitorFile(&m_fc, "/tmp/xxx", &fr, NULL);
req_path[fr.reqnum] = tomonitor;
while(1)
{
FAMEvent ev;
// if ( FAMPending( &m_fc ) )
{
if(-1 == FAMNextEvent(&m_fc, &ev))
{
cerr << "fam error detected!!!" << endl;
::exit(1);
}
switch (ev.code)
{
case FAMDeleted:
cerr << "Deleted event: " << ev.filename << endl;
break;
case FAMCreated:
cerr << "Created event: " << ev.filename << endl;
break;
case FAMChanged:
cerr << "Changed event: " << ev.filename << endl;
break;
case FAMExists:
{
//cerr << "Exist event: " << ev.filename << endl;
++existcount;
if(req_path[ev.fr.reqnum] != string(ev.filename))
{
string path(req_path[ev.fr.reqnum] + "/" + string(ev.filename));
struct stat statbuf;
::stat(path.c_str(), &statbuf);
if(S_ISDIR(statbuf.st_mode))
{
++dircount;
if(-1 == FAMMonitorDirectory(&m_fc, path.c_str(), &fr, NULL ))
{
cerr << "fammonitordir("<< path <<") error detected!!!" << endl;
::exit(1);
}
req_path[fr.reqnum] = path;
cerr << "Got Exist event and started to monitor "<< path << " endexist count is " << endexistcount << ", dircount is " << dircount << ", exist count is " << existcount << endl;
}
}
}
break;
case FAMEndExist:
++endexistcount;
cerr << "Got EndExist event for " << req_path[ev.fr.reqnum] << ". endexist count is " << endexistcount << ", dircount is " << dircount << ", exist count is " << existcount<< endl;
if(dircount == endexistcount)
{
cerr << "test passed" << endl;
exit(0);
}
break;
default:
cerr << "unhandled event code: " << ev.code << endl;
break;
}
}
// else
// {
// ::sleep(1);
// }
}
FAMClose( &m_fc );
}

