LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-04-2006, 07:32 PM   #1
mallport
LQ Newbie
 
Registered: Aug 2006
Posts: 4

Rep: Reputation: 0
poll returns errno 22, EINVAL


I have run into a problem when using the 2.6 kernel and using poll ( I have the problem w/ Fedora Core 5 and not with RedHat 8.0 ).

Despite having 'ulimit -n' and /proc/sys/fs/file-max set very high, say 10000 and 20000 respectively to avoid errno 24 (too many open files), I've made the following observations that seem to be rooted in polling file descriptors set to -1.

1) The poll call will return EINVAL when polling more than 1024 file descriptors and some of the file descriptors are set to -1. This is my problem.

2) The poll call will NOT return EINVAL when polling 1024 file descriptors or less and some of the file descriptors are set to -1.

3) The poll call will NOT return EINVAL when polling more than 1024 file descriptors and all file descriptors are valid.

I am looking for an answer as to why 1) happens and if there is something I can do about it. I don't want to change my code to avoid using -1 in poll calls, using -1 in poll calls is allowed.


Here is a program that exemplifies the problem.

Cut and past and compile as follows 'g++ ./test1.cpp -o test1'.

The program takes an optional command line parameter that is the number of file descriptors to test poll with. The default is 1024.

The program needs file, ./test_file, to exist in the directory where the program is executed. Do 'touch ./test_file' before running this program.

This problem has driven me crazy and far too 'wordy' as you can tell from this long post.

Thanks,
mallport

----here is the test program ---------------
Code:
#include <unistd.h>
#include <iostream.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>


int main(const int argc, const char** argv) {

    bool            DoPoll  = true;
    int             NumFds  = 1024;
    struct pollfd*  pPollFds;
    int             RetVal;
    bool            UseOther = false;


    if( (argc > 1) ) {

        NumFds = atoi(argv[1]);
        cout << "using input number of fds " << NumFds << endl;

    } else {

        cout << "using number of fds " << NumFds << endl;
    }


    try {

        pPollFds = new struct pollfd[NumFds];

    } catch(...) {

        cout << "caught exception making pollfds, exiting" << endl;
        exit(1);
    }

    memset(reinterpret_cast<void*>(pPollFds), -1, (NumFds * (sizeof(struct pollfd))));


    for(int i = 0; i < NumFds; i++) {

        UseOther = !UseOther;

        //
        // add some 'unitialized' file descriptors
        //
        if( (UseOther) ) {

            pPollFds[i].fd = -1;

        } else {

            //
            // generate a valide file descriptor by opening test_file
            //
            pPollFds[i].fd = open("./test_file", O_RDONLY);

            if( (-1 == pPollFds[i].fd) ) {

                cout << "open failed, i is " << i
                    << " errno is " << errno << " \"" << strerror(errno) << "\" " << endl;
                DoPoll = false;
                break;
            }
        }

        pPollFds[i].events  = POLLIN;
    }


    if( (DoPoll) ) {

        cout << "polling ..." << endl;

        RetVal = poll(pPollFds, NumFds, 5000);

        if( (-1 == RetVal) ) {

            cout << "poll failed, errno is " << errno << " \"" << strerror(errno) << "\" " << endl;

        } else {

            cout << "poll worked" << endl;
        }

    } else {

        cout << "Not doing poll" << endl;
    }


    for(int i = 0; i < NumFds; i++) {

        close(pPollFds[i].fd);
    }

    delete [] pPollFds;

    return(0);
}
--------------------------------------------

Last edited by mallport; 08-07-2006 at 12:29 PM.
 
Old 08-06-2006, 10:47 AM   #2
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Please use [code] tags. I can't read this code very well when the indentation is gone.
 
Old 08-07-2006, 12:32 PM   #3
mallport
LQ Newbie
 
Registered: Aug 2006
Posts: 4

Original Poster
Rep: Reputation: 0
I added the code tags, looks much better. I was foolish to think anyone would want to work with the text the way it was presented.

If you run the program pass in the number of file descriptors as the agrument.

'./test1 1024' this will work

./test1 1025' this will present the errno 22.

Thanks,
mallport
 
Old 08-07-2006, 01:04 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

Try typing "ulimit -H -n" ...
... and I'll bet you'll see the magic number "1024"
... as the maximum #/file descriptors per process.

Try increasing the #/file descriptors - that should fix the "poll()" problem.

'Hope that helps .. PSM

http://developers.sun.com/solaris/ar...efficient.html
http://bcr2.uwaterloo.ca/~brecht/servers/openfiles.html
http://www.xenoclast.org/doc/benchma...WTO/node7.html
http://www.uwsg.iu.edu/hypermail/lin...01.2/0885.html
http://www.linux-mag.com/index.php?o...sk=view&id=344

Last edited by paulsm4; 08-07-2006 at 01:10 PM.
 
Old 08-08-2006, 10:02 AM   #5
mallport
LQ Newbie
 
Registered: Aug 2006
Posts: 4

Original Poster
Rep: Reputation: 0
If this is at all different the doing 'ulimit -n 10000', I'll try it.

What I have tried is increasing the number of open files via ulimit as mentioned above and also increasing the value in /proc/sys/fs/file-max.

What I observed is:

1) if your program polls with more than 1024 valid file descriptors, poll will not return an errno. A valid file descriptor being not -1.

2) if your program polls with 1024 file descriptors or less and some of the file descriptors are -1, poll will not return an errno.

3) if your program polls with more than 1024 file descriptors and some of those file descriptors are -1, poll will return an errno.

The interesting thing is, with the program text I've included in the first post of this thread, when polling as 3) above, the red hat 8 kernel will not return an errno but the red hat 9 kernel will.

Any ideas why poll would behave differently from kernel to kernel?

Thanks,
mallport

Last edited by mallport; 08-08-2006 at 10:04 AM.
 
Old 08-21-2006, 03:24 PM   #6
mallport
LQ Newbie
 
Registered: Aug 2006
Posts: 4

Original Poster
Rep: Reputation: 0
We've found this to a bug in the kernel, my place of employment has a RedHat engineer working on it.

I'll keep you posted.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
errno saurabhtopno Linux - General 3 05-04-2006 01:47 AM
errno cynthia Linux - Networking 3 09-24-2004 01:58 PM
How to use errno sibtay Programming 4 09-24-2004 09:38 AM
errno.h, but it IS declared...... privateprimate Linux - Software 3 09-08-2004 07:37 PM
semop returns -1 but errno is 0 DaveRob Programming 1 08-11-2003 05:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration