[Previous] [Contents] [Next]

Caution: This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs.

The Migration Library

The migration library is a set of functions that implement many of the QNX 4 functions that are no longer supported or are different in the new OS.

There's also a migration process manager (mig4nto-procmgr) that must be run for some of the library functions to work.


Note: In the list of migration functions given below, functions that require mig4nto-procmgr are indicated as such. If a process does call functions that require mig4nto-procmgr, then you must call the mig4nto_init() function at the very beginning of your program. See the description for mig4nto-procmgr below for more on this.

The migration process manager (mig4nto-procmgr)

Provides numerous features of the migration library (QNX)

Syntax:

mig4nto-procmgr [-ntv]

Options:

-n
QNX 4-style network ID (nid) (default: 1)
-t
Number of threads for relaying proxy messages (default: 4)
-v
Be verbose. Use more v's for more information.

Description

The migration process manager provides services such as name registration and name location, proxy registration and sending, and nid storage. Basically, it provides things that Proc32 does under QNX 4 but that procnto (the QNX Neutrino equivalent) doesn't provide (or doesn't provide in the same way).

Triggering of proxies using this library can be much slower than in QNX 4. If a process triggers a proxy and that proxy isn't attached to the triggering process, then the triggerer sends a message to mig4nto-procmgr. The mig4nto-procmgr process has a number of threads dedicated to receiving these trigger messages (see the -t option above). When one of these threads receives the trigger message, it replies back immediately. It then sends a message to the process that the proxy is attached to. The reason for having the Trigger() function send to mig4nto-procmgr is so that it will know if the proxy is a valid one.

Many of the functions in the migration library require that the mig4nto-procmgr process be running. If using any of these functions, you must also call mig4nto_init() at the very beginning of you program, preferably the first thing in main(). One of the reasons for this is that mig4nto_init() creates a channel by calling ChannelCreate(). The channel ID returned must be 1 -- calling this function very early ensures this.

Migration functions that require mig4nto-procmgr

The following functions need mig4nto-procmgr to be running:

The migration library functions

The following functions are in the migration library (libmig4nto.a). The only include needed is <mig4nto.h>. Note that full source is available.

Rather than repeat the contents of the QNX 4 documentation, only the differences from QNX 4 implementation are given below. Note that no attempt was made to keep the errno failure values the same.

block_read()

The block number has been changed from 1-based to 0-based.

block_write()

The block number has been changed from 1-based to 0-based. The QNX 4 block_write(), when applied to a regular file, would never grow it; the QNX Neutrino writeblock() function (which this migration function uses) may cause a regular file to be extended if writing occurs beyond the end-of-file.

dev_arm()

Only the following are supported:

Requires mig4nto-procmgr to be running.

dev_info()

If the call is successful, the following members of the info structure are filled:

int unit
Unit number of this device (e.g. /dev/con2 would have a unit of 2).
nid_t nid
The network ID where this device exists. Note that this will contain a QNX Neutrino node descriptor (nd), not a QNX 4 network ID (nid).
pid_t driver_pid
Process ID of the driver that controls this device.
char driver_type[16]
A symbolic name describing the device nature.
char tty_name[MAX_TTY_NAME]
A complete pathname that may be used to open his device.

dev_insert_chars()

Same as QNX 4 implementation.

dev_ischars()

Same as QNX 4 implementation.

dev_mode()

_DEV_OSFLOW is not supported.

dev_read()

The proxy and armed parameters are not supported.

dev_readex()

This gets the out-of-band data from devc-* drivers (uses the DCMD_CHR_GETOBAND of devctl()). The return value is the number of bytes read, but is not obtained from the driver. Instead, this function estimates the number of bytes by filling the buffer with zeros before doing the devctl() and then after the devctl() has returned, counting the number of leading non-zero bytes.

dev_size()

Same as QNX 4 implementation.

dev_state()

This only lets you query the current state. The __bits and __mask parameters are ignored.

The following can be returned:

_DEV_EVENT_INPUT
Input is available from the device.
_DEV_EVENT_DRAIN
The output has drained on this device.
_DEV_EVENT_EXRDY
An exception or out-of-bound character is available to be read with dev_readex()
_DEV_EVENT_OUTPUT
There's room in the output buffer to transmit N chars (by default, N is 1).

disk_get_entry()

This uses devctl() with the DCMD_CAM_DEVINFO command. See <sys/dcmd_cam.h> and <sys/cam_device.h>.

You may want to use the direct devctl()s that build this, because they're more useful and have better field definitions (e.g. "cylinders" in QNX Neutrino is 32-bit, but only 16 in QNX 4; large EIDE disks have already wrapped this due to geometry translation).

disk_space()

It may be better to switch directly to statvfs(), which has additional fields that may be useful (such as the block size, the mount flags, etc).

fsys_get_mount_dev()

Same as QNX 4 implementation.

fsys_get_mount_pt()

Same as QNX 4 implementation.

getnid()

This returns the network id passed to mig4nto-procmgr through the -n option. The mig4nto-procmgr process defaults this to 1.

Requires mig4nto-procmgr to be running.

mig4nto_init()

This must be called before most library functions are called (see the list under the mig4nto-procmgr section above). It should be called as the first or one of the first things in main(). The reason is that it creates a channel for receiving messages on, and the channel ID must be 1. This will be true only for the first call to ChannelCreate(). Calling this early ensures that this will be the case.

Requires mig4nto-procmgr to be running.

qnx_hint_attach()

QNX Neutrino interrupt handlers can return with an event that contains a pulse. QNX 4 interrupt handlers can return a proxy. In order for this to still work, this function installs its own QNX Neutrino interrupt handler that will call the given interrupt handler. So when the interrupt is generated, this hidden handler is called. The hidden handler calls the given handler. If the given handler returns with a proxy (non-zero value), then the hidden handler returns a pulse event. The proxy value is stuffed into the event.

The Receive*() migration functions watch for this pulse event. When they receive it, they pull the proxy value from the pulse message and return with it.

qnx_hint_detach()

Same as QNX 4 implementation.

qnx_name_attach()

The only valid values for nid are 0 and the local nid (gotten from mig4nto-procmgr).

Requires mig4nto-procmgr to be running.

qnx_name_detach()

The only valid values for nid are 0 and the local nid (gotten from mig4nto-procmgr).

Requires mig4nto-procmgr to be running.

qnx_name_locate()

The only valid values for nid are 0 and the local nid (gotten from mig4nto-procmgr).

Requires mig4nto-procmgr to be running.

qnx_name_query()

The only valid values for proc_pid are 0 and PROC_PID.

Requires mig4nto-procmgr to be running.

qnx_osinfo()

The fields in the osdata structure are set to the following values:

The remaining fields are set to MIG4NTO_UNSUPP.

qnx_proxy_attach()

Requires mig4nto-procmgr to be running.

qnx_proxy_detach()

Requires mig4nto-procmgr to be running.

qnx_psinfo()

Some of the information associated with a process in QNX 4 is associated with a thread in QNX Neutrino (e.g. state, blocked_on, ...). The assumption here is that if you're migrating a QNX 4 process to QNX Neutrino, you'll have only one thread, so this information is taken from the thread with ID 1 (the main() thread).

The following fields are populated:

All other psdata structure elements are set to MIG4NTO_UNSUPP.

QNX Neutrino doesn't support time-accounting information, so the members of the tms structures are always set to 0.

The qnx_psinfo() function can currently examine processes only, as there are no /proc entries for virtual circuits and pulses.

The only valid values for proc_pid are 0 and PROC_PID.

The segdata parameter is ignored.

qnx_spawn()

Here are some notes regarding the parameters:

__msgbuf
This is ignored.
__sched_algo
QNX 4 and QNX Neutrino use the same names for scheduling algorithms, but their values are different. Be very careful if you're not just recompiling with the macros from the QNX Neutrino header files.

Note also that in the new OS, SCHED_OTHER is SCHED_RR. QNX Neutrino doesn't have QNX 4's adaptive scheduling algorithm. As such, there's no equivalent of SCHED_FAIR.

__flags
The _SPAWN_XCACHE flag is not supported.
__iov
If this is given, then unlike QNX 4, the FDs passed within it will be the only ones inherited by the child. This is true even for the IOVs that are -1.
__ctfd
This returns -1 and sets errno to EINVAL if the __ctfd parameter is anything other than -1.

Readmsg()

Requires mig4nto-procmgr to be running.

Readmsgmx()

Requires mig4nto-procmgr to be running.

Receive()

Requires mig4nto-procmgr to be running.

Receivemx()

Requires mig4nto-procmgr to be running.

Reply()

Requires mig4nto-procmgr to be running.

Replymx()

Requires mig4nto-procmgr to be running.

Send()

This function creates a connection for each process that is sent to. Once the message has been sent, the connection is not detached. Instead, the connection ID is cached in case further messages are sent to the same process.

Requires mig4nto-procmgr to be running.

Sendmx()

This function creates a connection for each process that is sent to. Once the message has been sent, the connection is not detached. Instead, the connection ID is cached in case further messages are sent to the same process.

Requires mig4nto-procmgr to be running.

Trigger()

If triggering a proxy that is attached to the calling process, then this uses a pulse.

If triggering a proxy that is attached to another process, then this sends a message to mig4nto-procmgr, which has a set of dedicated threads for receiving this message. When one of those threads receives the message, it replies immediately and then sends a message to the process that the proxy is attached to.

The reason for going through mig4nto-procmgr is that the Trigger() function will at least know whether or not the proxy is a valid one.

Requires mig4nto-procmgr to be running.

Writemsg()

Requires mig4nto-procmgr to be running.

Writemsgmx()

Requires mig4nto-procmgr to be running.

Yield()

Same as QNX 4 implementation.


[Previous] [Contents] [Next]