Where Is Open_Max Defined for Linux Systems

Where is OPEN_MAX defined for Linux systems?

For what it's worth, the 4th edition of Beginning Linux Programming was published in 2007; parts of it may be a bit out of date. (That's not a criticism of the book, which I haven't read.)

It appears that OPEN_MAX is deprecated, at least on Linux systems. The reason appears to be that the maximum number of file that can be opened simultaneously is not fixed, so a macro that expands to an integer literal is not a good way to get that information.

There's another macro FOPEN_MAX that should be similar; I can't think of a reason why OPEN_MAX and FOPEN_MAX, if they're both defined, should have different values. But FOPEN_MAX is mandated by the C language standard, so system's don't have the option of not defining it. The C standard says that FOPEN_MAX

expands to an integer constant expression that is the minimum number of files that
the implementation guarantees can be open simultaneously

(If the word "minimum" is confusing, it's a guarantee that a program can open at least that many files at once.)

If you want the current maximum number of files that can be opened, take a look at the sysconf() function; on my system, sysconf(_SC_OPEN_MAX) returns 1024. (The sysconf() man page refers to a symbol OPEN_MAX. This is not a count, but a value recognized by sysconf(). And it's not defined on my system.)

I've searched for OPEN_MAX (word match, so excluding FOPEN_MAX) on my Ubuntu system, and found the following (these are obviously just brief excerpts):

/usr/include/X11/Xos.h:

# ifdef __GNU__
# define PATH_MAX 4096
# define MAXPATHLEN 4096
# define OPEN_MAX 256 /* We define a reasonable limit. */
# endif

/usr/include/i386-linux-gnu/bits/local_lim.h:

/* The kernel header pollutes the namespace with the NR_OPEN symbol
and defines LINK_MAX although filesystems have different maxima. A
similar thing is true for OPEN_MAX: the limit can be changed at
runtime and therefore the macro must not be defined. Remove this
after including the header if necessary. */
#ifndef NR_OPEN
# define __undef_NR_OPEN
#endif
#ifndef LINK_MAX
# define __undef_LINK_MAX
#endif
#ifndef OPEN_MAX
# define __undef_OPEN_MAX
#endif
#ifndef ARG_MAX
# define __undef_ARG_MAX
#endif

/usr/include/i386-linux-gnu/bits/xopen_lim.h:

/* We do not provide fixed values for 

ARG_MAX Maximum length of argument to the `exec' function
including environment data.

ATEXIT_MAX Maximum number of functions that may be registered
with `atexit'.

CHILD_MAX Maximum number of simultaneous processes per real
user ID.

OPEN_MAX Maximum number of files that one process can have open
at anyone time.

PAGESIZE
PAGE_SIZE Size of bytes of a page.

PASS_MAX Maximum number of significant bytes in a password.

We only provide a fixed limit for

IOV_MAX Maximum number of `iovec' structures that one process has
available for use with `readv' or writev'.

if this is indeed fixed by the underlying system.
*/

Portable equivalent of OPEN_MAX

Advanced Programming in the Unix Environment, 2nd Ed gives us the following code which should work everywhere; though it is pretty clever, I think it is a little unfortunate it doesn't also check the rlimits of the process, since the rlimits can further constrain how many open files a process may use. That aside, here's the code from The Master:

#ifdef  OPEN_MAX
static long openmax = OPEN_MAX;
#else
static long openmax = 0;
#endif

/*
* If OPEN_MAX is indeterminate, we're not
* guaranteed that this is adequate.
*/
#define OPEN_MAX_GUESS 256

long
open_max(void)
{
if (openmax == 0) { /* first time through */
errno = 0;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) {
if (errno == 0)
openmax = OPEN_MAX_GUESS; /* it's indeterminate */
else
err_sys("sysconf error for _SC_OPEN_MAX");
}
}

return(openmax);
}

(err_sys() is provided in the apue.h header with the sources -- should be easy to code a replacement for your routine.)

FOPEN_MAX and _SC_OPEN_MAX

The discrepancy is because one is dynamic, one is static. If you write software for Ubuntu systems, the numbers are telling you'll always be able to rely on 20 open files (POSIX here is guaranteeing more than plain C's 16 limit). So you could theoretically compile some stuff conditionally to do crazy stuff to work around a low limit, to make sure the software will work on all systems with the same headers.

The runtime limit, _SC_OPEN_MAX, is the actual fd limit. It might be lower on some systems, but not below 20 (for any POSIX OS).

Finally, OPEN_MAX is the OS-specific lower limit for _SC_OPEN_MAX (that is, _POSIX_OPEN_MAX is telling you that on any POSIX system, OPEN_MAX has to be at least 20). Linux will define OPEN_MAX to be something higher, so you can rely on having more fds available, and will prevent _SC_OPEN_MAX going below the actual OPEN_MAX.

What are file descriptors, explained in simple terms?

In simple words, when you open a file, the operating system creates an entry to represent that file and store the information about that opened file. So if there are 100 files opened in your OS then there will be 100 entries in OS (somewhere in kernel). These entries are represented by integers like (...100, 101, 102....). This entry number is the file descriptor.
So it is just an integer number that uniquely represents an opened file for the process.
If your process opens 10 files then your Process table will have 10 entries for file descriptors.

Similarly, when you open a network socket, it is also represented by an integer and it is called Socket Descriptor.
I hope you understand.

Maximum number of files that can be opened by c fopen in linux

You can see the maximum allowed open files (kernel limit) by doing:

cat /proc/sys/fs/file-max

Quote from kernel docs:

The value in file-max denotes the maximum number of file-
handles that the Linux kernel will allocate. When you get lots
of error messages about running out of file handles, you might
want to increase this limit.

Can value of a file descriptor go beyond max opened file descriptor softlimit?

Yes, it can. The soft limit is something you can change with a call to ulimit(2) system call.... so you can put it under the number of actually open files and that mean that open(2) will fail on the next open, but it doesn't affect the actual number of open files you have open now. anyway... let's imagine this scenario:

  • you open 97 files (plus stdin, stdout and stderr, this makes 100 open descriptors from 0 to 99)
  • you close descriptors 0 to 49 (You have still open 50 to 99). (beware that this example will not allow you to print anything, as you have closed stdin, stdout & stderr)
  • you reduce the soft limit to 75.

you can still open 25 files more (you have 50 open files now)... and the'll go in the range 0 to 24, but the others continue to be open from 50 to 99. And you cannot open more files, because you run out the limit of open files.

By the way, the descriptor you get from the system from an open system call is always the minimum value available number to get... so, if you avoid touching the ulimits maximum number of open files, then you can do what you want.

Max open files for working process

As a system administrator: The /etc/security/limits.conf file controls this on most Linux installations; it allows you to set per-user limits. You'll want a line like myuser - nofile 1000.

Within a process: The getrlimit and setrlimit calls control most per-process resource allocation limits. RLIMIT_NOFILE controls the maximum number of file descriptors. You will need appropriate permissions to call it.

How to decode h264 video using OpenMax in Linux? Is this code correct?

I guess that question is without answer for long enough for you to find it in other place, but I will answer regardless.

In your callback event handler on PortSettingsChanged event you only print a message about it, but what OpenMAX specification describes in section 3.4.5 is dynamic port reconfiguration.
In case of tunneled implementation it would only require to disable/re-enable port that this event occured for (disabling the port will cause return and deallocation of buffers connected to this port, enabling will allocate new buffers configured with new port setings).
In case of non-tunneled implementation you have to:
- disable port,
- free buffers,
- read port settings,
- enable port,
- alloc new buffers according to settings.

Should be working from there.



Related Topics



Leave a reply



Submit