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

Attachment: 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 );
}

Reply via email to