This chapter includes:
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 32 MB on ARM to 3.5 GB 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.
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.
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 2 G − 1 bytes.
This, in turn, limits the size of a directory, because the file that stores
the directory's information is limited to 2 G − 1 bytes.
The filesystems include:
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.
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
- 2 GB − 1.
- Directory size
- No practical limit, although the
files that the directory uses to manage its contents are limited to
2 G − 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
- 2 GB × 512; limited by the disk driver.
- Disk size
- 264 bytes; limited by the disk driver.
The limits for Power-Safe filesystems (supported by fs-qnx6.so)
include:
- Physical disk sector
- 32-bit (2 TB), using the devb API.
- Logical filesystem block
- 512, 1024, 2048, or 4096 (set when you initially format the filesystem).
- Maximum filename length
- 510 bytes (UTF-8).
If the filename is less than 28 bytes long, it's stored in the directory
entry; if it's longer, it's stored in an external file, and the directory
entry points to the name.
- Maximum file size
- 64-bit addressing.
With a 1 KB (default) block size, you can fit 256 block pointers in a block,
so a file that's 16 × 256 × 1 KB (4 MB) requires 1 level
of indirect pointers.
If the file is bigger, you need two levels (i.e. 16 blocks of 256 pointers
to blocks holding another 256 pointers to blocks), which gives a maximum
file size of 1 GB.
For three levels of indirect pointers, the maximum file size is 256 GB.
If the block size is 2 KB, then each block holds up to 512 pointers, and
everything scales accordingly.
The limits for Linux Ext2 filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2 GB − 1.
- Directory size
- 2 GB − 1;
directories are files with inode and filename information as data.
- Filesystem size
- 2 GB × 512.
- Disk size
- 264 bytes; limited by the disk driver.
The limits for DOS FAT12/16/32 filesystems include:
- Filename length
- 255 characters.
- Pathname length
- 260 characters.
- File size
- 4 GB − 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.
- FAT directories are limited (for DOS-compatability) to containing
64 K entries.
- 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 32 KB, hence 128 MB)
- for FAT16, it's 65524 clusters (thus 2 GB)
- for FAT32, you get access to 268435444 clusters (which is 8 TB)
- Disk size
- Limited by the disk driver and io-blk.
These filesystems don't really support permissions, but they can emulate them.
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 (4 GB − 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.
|
We've deprecated fs-cd.so in favor of
fs-udf.so,
which now supports ISO-9660 filesystems in addition to UDF.
For information about the limits for UDF, see
“UDF filesystem,”
later in this chapter. |
The limits for NFS2 and NFS3 filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2 GB − 1; 32-bit filesystem limit.
- Directory size, filesystem size, and disk size
- Depends on the server; 32-bit filesystem limit.
The limits for CIFS filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2 GB − 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.
The limits for embedded (flash) filesystems include:
- Filename length
- 255 bytes.
- Pathname length
- 1024 bytes.
- File size, filesystem size, and disk size
- 2 GB − 1.
- Directory size
- Limited by the available space.
Flash filesystems use a cache to remember the location of extents
within files and directories, to reduce the time for random seeking
(especially backward).
The limits for ETFS are:
- Filename length
- 91 bytes.
- Pathname length
- 1024 bytes.
- File size
- 2 GB − 1; 32-bit filesystem limit.
- Maximum number of files
- 32768 (15 bits).
- Default maximum number of files
- 4096.
- Max cluster size
- 4096.
- Maximum filesystem size
- 64 GB.
For NAND flash, some additional limitations apply:
- Only single-level cell (SLC) NAND flash is supported.
- The maximum filesystem size is 4 GB.
- ECC protection of the spare area is supported only on 2 KB and 4 KB
page NAND.
- The software ECC supports only 1-bit error correction, for each 256-byte
buffer.
- Only NAND flash with page sizes of 512, 2048, and 4096 bytes are supported.
|
For ETFS on NAND, you can perform 1-bit software error correction coding (ECC) for the data in the spare area. Support configurations are available for:
- 2 KB page NAND flash devices
- 4 KB page NAND flash devices
Once calculated, the spare area receives the ECC value from devio_postcluster(), and then writes it to NAND flash. To determine the appropriately sized ECC value, use the following:
- For 512 NAND, it's not available
- For 2048 NAND, use 64 byte ECC
- For 4096 NAND, use 128 byte ECC
To take advantage of the spare area, you'll need to make the following changes for BSPs:
- For devio_readtrans() and devio_readcluster() — When reading the spare area, first save the spare area ECC, and then set those fields of the spare structure to 0xFF, which is required for calculating the cyclic redundancy check (CRC — data integrity checks for NAND). Perform the CRC calculation and if it fails, then in order to recover, you must attempt using the new spare area ECC value. If the spare area CRC is correct, then you can skip the ECC operation. If the ECC can correct the spare area, then set tacode in the transaction structure to ETFS_TRANS_ECC. If the ECC can't be corrected, then set the tacode to ETFS_TRANS_DATAERR.
- For devio_postcluster() — After calculating the CRC and ECC for the cluster data, and calculating the CRC for the spare area, add a calculation for the ECC of the spare area. When doing the CRC calculation, use 0xFF as placeholder values for the spare area ECC.
|
The limits for UDF filesystems include:
- Filename length
- 255 Unicode characters.
- Pathname length
- 1024 bytes.
- Disk size
- This filesystem uses a 32-bit block address, but the filesystem is
64-bit (> 4 GB).
We don't allow the creation of anything via fs-udf.so;
it's read-only.
The limits for the Apple Macintosh HFS (Hierarchical File System) and HFS Plus
include:
- Filename length
- 31 MacRoman characters on HFS; 255 bytes (Unicode) on HFS Plus.
- Pathname length
- 1023 bytes.
- Disk size
- This filesystem uses a 32-bit block address, but the filesystem is
64-bit (> 4 GB).
We don't allow the creation of anything via fs-mac.so;
it's read-only.
The limits for Windows NT filesystems include:
- Filename length
- 255 characters.
- Pathname length
- 1024 bytes.
- File size
- 4 GB − 1; uses a 64-bit filesystem format.
- Filesystem size
- 264 - 1 clusters.
- Disk size
- Limited by the disk driver and io-blk.
This filesystem is read-only.
These limits apply to the entire system:
- Processes
- A maximum of 4095 active at any time, with these exceptions:
- On ARMv6 platforms (running
procnto-v6),
the limit is 255 processes.
The MMU has an 8-bit ASID that's used to tag non-global TLB entries.
Each address space is assigned a unique tag that's set in the MMU context
register on a context switch to specify the current ASID in use.
The code doesn't currently take ASIDs, so we're limited to 255 processes.
- On earlier ARM platforms, the limit is 63 processes.
On ARM platforms, the limit is actually on the number of separate
address spaces; you could have more processes if they happen to
be sharing an address space because of
vfork(),
but that's very unusual.
- 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.
- Memory allocation:
Because the malloc() implementation uses signed, 32-bit
integers to represent the size internally,
you can't allocate more than 2 GB in a single allocation.
If the size is greater than 2 GB, these functions indicate an error
of ENOMEM:
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, 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).
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).
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).
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.
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.
Limit
|
x86
|
PPC
|
MIPS
|
SH-4
|
ARMv4
|
ARMv6 |
System RAM
|
64 GB (36-bit addressing)
|
64 GB (36-bit addressing)
|
1 TB (40-bit addressing)
|
512 MB (32-bit addressing)a
|
4 GB (32-bit addressing)
|
512 MB (32-bit addressing)a |
CPUsb
|
8
|
8
|
8
|
2
|
1
|
1 |
Virtual address spacec
|
3.5 GB
|
3 GB
|
2 GB
|
2 GB
|
32 MB
|
2 GB |
a 32-bit addressing gives 4 GB of space, but not all can be
used for system RAM on some platforms.
Some space is reserved for devices, and some platforms might impose other
restrictions.
b The hardware might further limit the number of CPUs.
c
These are the absolute maximum limits for the virtual address space;
you can reduce them by setting the RLIMIT_AS
resource with
setrlimit().