Advertise, look up, and use (connect to) a service across a network
gns [-cv] [nodename ...] gns [-sv] [nodename]
Neutrino
The global name service (gns) manager is a standalone resource manager. With the help of gns, an application could advertise, look up, and use (connect to) a service across network, without knowing the detail of where the service is, or who is the provider.
GNS runs in two different modes: server and client. A server-mode manager is a central database that stores advertised services, and handles lookup and connect requests. A client-mode manager relays advertise, lookup, and connect requests between a local application and the gns server.
There are several functions in the Library Reference that you can use: name_attach() to advertise, name_open() to connect to, name_close() to disconnect from a certain service, and name_detach() to remove a name from the namespace.
An application advertises (attaches) a service (i.e. represented by a path name) either locally or globally. If an application attaches a service locally, then applications from another machine can't look up this service through the gns utility. If an application attaches its services globally, then any machine that's on the network and is running the gns manager can access the services.
An application can attach a service locally, but only if there isn't another application that's attached locally to the same service. There's no credential restriction for applications that are attached as local services.
An application can attach a service globally only if the application has root privileges.
Even though attaching globally is network-wide, an application on another machine could still attach globally with the same service name. This allows service redundancy, since the same service is available from multiple hosts on the network.
Although we have used the name_* API for the implementation of GNS, there is slight behavior change with respect to the previous implementation of the Neutrino realtime operating system. Before, when an application called name_open() to connect to a service, the server was not aware of that. This has been changed now —an _IO_CONNECT/_IO_OPEN message is sent to the server. The server application has to be modified to handle a possible _IO_CONNECT message coming in. For an example, see the documentation for name_attach() in the Neutrino Library Reference. |
A service is represented by a path namespace (without a leading “/”) and is registered under /dev/name/global or /dev/name/local, depending on how it attaches itself.
Every machine running a gns client or server on the same network has the same view of the /dev/name/global namespace. Each machine also has a /dev/name/local namespace that's local to each machine, and therefore, is different.
For details, see the Examples section.
Applications that wish to connect to a global name service can use the name_open() API. If the same service is registered by multiple hosts, the rules that determine which specific instance of the service you connect to are:
It's possible to start multiple global name service managers in server mode on different machines.
You can set some clients to connect to server1, and some clients to server2. This creates separate “service domains,” where clients connected to server1 (in “service domain1”) can't use services registered on server2 (in “service domain2”).
On some clients:
# gns -c server1
On others:
# gns -c server2
Since the GNS server is a central database, the loss of redundant GNS servers could mean the interruption of service (advertise, lookup, use) across the network. To solve this problem, you can start multiple GNS servers and point clients to all of them.
On server1:
# gns -s
On server2:
# gns -s
On all clients:
# gns -c server1 server2
In this case, every time an application tries to register a global service, the registration is sent to both server1 and server2. Every time an application tries to connect to a global service, the request is attempted on both server1 and server2.
The GNS on server1 doesn't communicate with the GNS on server2. This means that if an application on server1 wants to register a global service on client nodes, the gns process on server1 can't forward the request to server2, because a gns process can't act as a client and server at the same time. This however, doesn't affect the applications that try to connect to that service because both servers are attempted. |
Each GNS manager is registered under /dev/name/gns_server or /dev/name/gns_client. If you start a GNS client without specifically assigning a target server, it performs an auto-scan to find the GNS server(s) on the local network.
On a client:
# gns -c
An auto-scan is performed by going through the local network directory (usually /net), and trying to see if any machine has a pathname of /net/machine/proc/mount/dev/name/gns_server.
An auto-scan isn't guaranteed to find a server. This is because the Qnet network isn't guaranteed to have all local machines under /net. |
The benefit of an auto-scan client lies in the event of losing the connection to a server. The client will rescan to find another server when this happens. This makes it easy to start another GNS server, synchronize it with the first one (we'll discuss synchronizing later), and then kill the first GNS server.
If a client starts specifying specific GNS server(s) on the command line, it won't perform an auto-scan. If it loses the connection to its server, it tries to reestablish the connection every time a registration, lookup, or connect request is made.
A GNS manager can be started in a “backup server” mode. Simply start a GNS manager in server mode, and pass a specific server machine on the command line.
On node1, start a normal server:
# gns -s
and, on node2, start a backup server:
# gns -s node1
The GNS manager on node2 synchronizes with the GNS manager on node1, gets all the global service information from node1, and stores it locally.
All GNS clients that are already connected to the GNS server on node1 are notified about the new server on node2, and they connect to it. These clients then have multiple servers, as if they had been started as follows:
# gns -c node1 node2
For a tightly coupled network, you may start the GNS manager in server mode only. All client nodes could prefix the server's name space, instead of running a GNS manager in client mode locally.
On a server:
# gns -s
On other clients:
# ln -sP /net/gsrv/dev/name/global /dev/name/global
When a service provider registers its global service name from a client node (not running gns -c), the information is directly sent to the GNS manager on server. Subsequently, if a service consumer tries to look up the service name, the lookup message is sent to the GNS manager on server, which then returns the service provider information.
If a service provider registers a local service name, it simply registers itself in the local path manager. The local path manager serves a service consumer when it starts to look up the local service.
You must take note of the differences of running the GNS manager in client mode rather than using the prefixes described above. A client-mode GNS manager running locally may cache some service provider information, such that every lookup does not need to go to the GNS manager on the server. This ensures that a lookup usually succeeds even if there is a period of lost connection with the GNS manager.
Also, if the path namespace is prefixed, the client can't look at the /dev/name/net directory to tell which node provides which services. This information is, however, not important in normal advertise/lookup operations.
All GNS managers are registered as /dev/name/gns_server or /dev/name/gns_client. This pathname can provide some statistical information about the GNS manager. For example:
$ cat /dev/name/gns_client Global Name Service Mode: Client Server: xtang (connected) Registered services: net/netsrv.ott.qnx.com/0,1818649,1,0,-1 (No Expiration) network/tcpip/51,20533309,1,0,12 (Fri Feb 7 13:57:39 2003) printer/ps/techpub/0,1826845,1,0,12 (No Expiration)
From the above, we infer that the gns process is a client, it has only one server (the machine named xtang), and it's already connected to the server. This also lists all the services known to the GNS manager. Note that the network/tcpip service has an expiration time, suggesting that this is a cached entry resulting from querying the gns server.
A typical network with gns looks like this:
Server node:
# gns -s
Client(s) node:
# gns -c server1 server2
Here's an example after a service called printer/ps/techpub has attached itself globally:
$ ls -l /dev/name/global/ total 2 dr-xr-xr-x 0 root techies 1 Feb 06 16:20 net dr-xr-xr-x 0 root techies 1 Feb 06 16:21 printer $ ls -l /dev/name/global/printer/ps total 1 dr-xr-xr-x 0 root techies 1 Feb 06 16:21 techpub
Notice how /dev/name/global/printer/ps/techpub is registered. The path /dev/name/global/net is reserved by the gns manager (therefore, an application can't attach a service started as net/). The machines under /dev/name/global/net represent machines that run the GNS manager. For example, the following listing shows that there are two machines running the GNS manager:
$ ls -l /dev/name/global/net total 2 dr-xr-xr-x 0 root techies 1 Feb 06 18:32 netsrv.ott.qnx.com dr-xr-xr-x 0 root techies 2 Feb 06 16:20 xtang.ott.qnx.com
Multiple application servers on different machines can attach to the same service. Therefore one pathname could represent multiple servers. In order to show that, the GNS manager automatically creates a name in the format nd pid chid handle file_type under the registered pathname, as follows:
$ ls /dev/name/global/printer/ps/techpub 0,16834613,1,0,12 8,1826845,1,0,12
From the above, you conclude that there are two applications attached to the printer/ps/techpub service.
Sometimes, you may wish determine what service machine netsrv.ott.qnx.com provides. To find that out, you can look into /dev/name/global/net/netsrv.ott.qnx.com — it shows the services attached by a process on netsrv.ott.qnx.com:
$ ls /dev/name/global/net/netsrv.ott.qnx.com/printer/ps/techpub 0,1826845,1,0,12
To know exactly which machine registered a service, try this:
$ ls -l /dev/name/global/printer/ps/techpub total 0 lr-xr-xr-x 0 root techies 0 Feb 06 16:48 0,16834613,1,0,12 -> ../../../net/xtang.ott.qnx.com/printer/ps/techpub/0,16834613,1,0,12 lr-xr-xr-x 0 root root 0 Feb 06 16:28 8,1826845,1,0,12 -> ../../../net/netsrv.ott.qnx.com/printer/ps/techpub/0,1826845,1,0,12
From the above, you conclude that a process on machine xtang.ott.qnx.com with process ID 16834613 has registered the printer/ps/techpubservice; meanwhile, process 1826845 on machine netsrv.ott.qnx.com also registered the same service.
name_attach(), name_close(), name_open(), name_detach() in the Library Reference.
“Locating services using GNS” in the Transparent Distributed Processing Using Qnet chapter of the Programmer's Guide.