for connected embedded systems
![]() |
![]() |
![]() |
![]() |
Understanding System Limits
This chapter includes:
The limits on describing limits
Neutrino is a microkernel, so many things that might be a core limit in some operating systems, become dependent on the particular manager that implements that service under Neutrino, especially for filesystems, where there are multiple possible filesystems.
Many resources depend on how much memory is available. Other limits depend on your target system. For example, the virtual address space for a process can vary by processor from 32M on ARM to 3.5G on x86.
Some limits are a complex interaction between many things. To quote the simple/obvious limit is misleading; describing all of the interactions can be complicated. The key thing to remember while reading this chapter is that there can be many factors behind a limit.
Configurable limits
When you're trying to determine your system's limits, you can get the values of configurable limits, special read-only variables that store system information.
![]() |
Neutrino also supports configuration strings, which are similar to, and frequently used in conjunction with, environment variables. For more information, see the Configuring Your Environment chapter. |
You can use the POSIX getconf utility to get the value of a configurable limit or a configuration string. Since getconf is a POSIX utility, scripts that use it instead of hard-coded QNX-specific limits can adapt to other POSIX environments.
Some configurable limits are associated with a path; their names start with _PC_. When you get the value of these limits, you must provide the path (see "Filesystem limits," below). For example, to get the maximum length of the filename, type:
getconf _PC_NAME_MAX pathname
Other limits are associated with the entire system; their names start with _SC_. You don't have to provide a path when you get their values. For example, to get the maximum number of files that a process can have open, type:
getconf _SC_OPEN_MAX
In general, you can't change the value of the configurable limits -- they're called "configurable" because the system can set them.
The Neutrino libraries provide various functions that you can use in a program to work with configurable limits:
- pathconf()
- Get the value of a configurable limit that's associated with a path.
- sysconf()
- Get the value of a limit for the entire system.
- setrlimit()
- Change the value of certain limits. For example, you can use this function to limit the number of files that a process can open; this limit also depends on the value of the -F option to procnto.
Filesystem limits
Under Neutrino, filesystems aren't part of the kernel or core operating system; they're provided by separately loadable processes or libraries. This means that:
- There's no one set limit or rule for filesystems under Neutrino -- the limits depend on the filesystem in question and on the process that provides access to that filesystem.
- You can provide your own filesystem process or layer that can almost transparently override or change many of the underlying values.
The sections that follow give the limits for the supported filesystems. Note the following:
- Lengths for filenames and pathnames are in bytes, not characters.
- Many of the filesystems that Neutrino supports use a 32-bit format. This means that files are limited to 2G - 1 bytes. This, in turn, limits the size of a directory, because the file that stores the directory's information is limited to 2G - 1 bytes.
Querying filesystem limits
You can query the path-specific configuration limits to determine some of the properties and limits of a specific filesystem:
- _PC_LINK_MAX
- Maximum value of a file's link count.
- _PC_MAX_CANON
- Maximum number of bytes in a terminal's canonical input buffer (edit buffer).
- _PC_MAX_INPUT
- Maximum number of bytes in a terminal's raw input buffer.
- _PC_NAME_MAX
- Maximum number of bytes in a filename (not including the terminating null).
- _PC_PATH_MAX
- Maximum number of bytes in a pathname (not including the terminating null).
- _PC_PIPE_BUF
- Maximum number of bytes that can be written atomically when writing to a pipe.
- _PC_CHOWN_RESTRICTED
- If defined (not -1), indicates that the use of the chown() function is restricted to a process with appropriate privileges, and to changing the group ID of a file to the effective group ID of the process or to one of its supplementary group IDs.
- _PC_NO_TRUNC
- If defined (not -1), indicates that the use of pathname components longer than the value given by _PC_NAME_MAX will generate an error.
- _PC_VDISABLE
- If defined (not -1), this is the character value that can be used to individually disable special control characters in the termios control structure.
For more information, see "Configurable limits," above.
QNX 4 filesystem
The limits for QNX 4 filesystems include:
- Filename length
- 48 bytes, or 505 if .longfilenames exists before mounting; see "Filenames" in the description of the QNX 4 filesystem in Working with Filesystems.
- Pathname length
- 1024 bytes.
- File size
- 2G - 1.
- Directory size
- No practical limit, although the files that the directory uses to manage its contents are limited to 2G - 1 bytes, which works out to approximately 33 million files in a single directory. You wouldn't want to do that, though, as directory scans are linear: they'd be very slow.
- Filesystem size
- 2G * 512; limited by the disk driver.
- Disk size
- 264 bytes; limited by the disk driver.
Ext2 filesystem
The limits for Linux Ext2 filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2G - 1.
- Directory size
- 2G - 1; directories are files with inode and filename information as data.
- Filesystem size
- 2G * 512.
- Disk size
- 264 bytes; limited by the disk driver.
DOS FAT12/16/32 filesystem
The limits for DOS FAT12/16/32 filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 260 bytes.
- File size
- 2G - 1; uses a 32-bit filesystem format.
- Directory size
- Depends on the type of filesystem:
- The root directory of FAT12/16 is special, in that it's pregrown and can't increase. You choose the size when you format, and is typically 512 entries. FAT32 has no such limit.
- Neutrino's FAT12/16 filesystem is limited to 64K entries. There are no such limits on FAT32; it has a practical limit of 2G - 1 (which is about 33 million entries) on the directory size.
- For long (non-8.3) names, a single filename may need multiple entries, thus reducing the possible size of a directory.
- Filesystem size
- Depends on the FAT format:
- for FAT12, it's 4084 clusters (largest cluster is 32K hence 128M)
- for FAT16, it's 65524 clusters (thus 2G)
- for FAT32 you get access to 268435444 clusters (which is 8T)
- Disk size
- Limited by the disk driver and io-blk.
These filesystems don't really support permissions, but they can emulate them.
CD-ROM (ISO9660) filesystem
The limits for CD-ROM (ISO9660) filesystems include:
- Filename length
- 32 bytes for basic ISO9660, 128 for Joliet, 255 for Rockridge.
- Pathname length
- 1024 bytes.
- Disk size
- This filesystem also uses a 32-bit (2G - 1) format. We don't allow the creation of anything via fs-cd.so; it's read-only. Any limits would be imposed by the tools used to make the image (which hopefully would be a subset of ISO9660). Disk size is also limited by the disk driver and io-blk.
NFS2 and NFS3 filesystem
The limits for NFS2 and NFS3 filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2G - 1; 32-bit filesystem limit.
- Directory size, filesystem size, and disk size
- Depends on the server; 32-bit filesystem limit.
CIFS filesystem
The limits for CIFS filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2G - 1; 32-bit filesystem limit.
- Directory size, filesystem size, and disk size
- 32-bit filesystem limit.
The CIFS filesystem doesn't support chmod or chown.
Embedded (flash) filesystem
The limits for embedded (flash) filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size, filesystem size, and disk size
- 2G - 1.
- Directory size
- Limited by the available space.
File entries, directory entries, and file extents are connected by linked lists. The longer these lists get, the longer it takes to seek for a position in, append to, and get statistics about files.
Other system limits
These limits apply to the entire system:
- Processes
- A maximum of 4095 active at any time; on ARM platforms, the limit is 63 processes.
- Prefix space (resource-manager attaches, etc.)
- Limited by memory.
- Sessions and process groups
- 4095 (since you need at least one process per session or group).
- Physical address space
- No limits, except those imposed by the hardware; see the documentation for the chip you're using.
These limits apply to each process:
- Number of threads: 32767
- Number of timers: 32767
- Priorities: 0 through 255
Priority 0 is used for the idle thread; by default, priorities of 64 and greater are privileged, so only processes with an effective user ID of 0 (i.e. root) can use them. Non-root processes can use priorities from 1 through 63.
You can change the range of privileged priorities with the -P option for procnto.
File descriptors
The total number of file descriptors has a hard limit of 32767 per process, but you're more likely to be constrained by the -F option to procnto or the RLIMIT_NOFILE system resource. The default value is 1000; the minimum is 100.
![]() |
Sockets, named semaphores, message queues, channel IDs (chids), and connection IDs (coids) all use file descriptors. |
To determine the current limit, use the ksh builtin command, ulimit, (see the Utilities Reference), or call getrlimit() (see the Library Reference).
Synchronization primitives
There are no limits on the number of mutexes and condition variables (condvars).
There's no limit on the number of unnamed semaphores, but the number of named semaphores is limited by the number of available file descriptors (see "File descriptors," above).
TCP/IP limits
The number of open connections and sockets is limited only by memory and by the maximum number of file descriptors per process (see "File descriptors," above).
Shared memory
The number of shared memory areas is limited by the allowed virtual address space for a process, which depends on the target architecture. See the RLIMIT_AS and RLIMIT_DATA resources for setrlimit() in the Library Reference.
Message queues
The number of message queues is limited by the number of available file descriptors (see "File descriptors," above).
The default maximum number of entries in a queue, and the default maximum size of a queue entry depend on whether you're using the traditional (mqueue) or alternate (mq) implementation of message queues:
| Attribute | Traditional | Alternate |
|---|---|---|
| Number of entries | 1024 | 64 |
| Message size | 4096 | 256 |
For more information, see mqueue and mq in the Utilities Reference, and mq_open() in the Neutrino Library Reference.
Platform-specific limits
| Limit | x86 | PPC | MIPS | SH-4 | ARM |
|---|---|---|---|---|---|
| System RAM | 64G (36-bit addressing) | 64G (36-bit addressing) | 1T (40-bit addressing) | 512M (29-bit addressing) | 4G (32-bit addressing) |
| CPUs* | 8 | 8 | 8 | 1 | 1 |
| Virtual address space+ | 3.5G | 3G | 2G | 2G | 32M |
* The hardware might further limit the number of CPUs.
+ These are the absolute maximum limits for the virtual address space; you can reduce them by setting the RLIMIT_AS resource with setrlimit().
![]() |
![]() |
![]() |
![]() |

![[Previous]](prev.gif)
![[Contents]](contents.gif)
![[Index]](keyword_index.gif)
![[Next]](next.gif)
