Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - _IO_CONNECT and non POSIX() API calls.... : (5 Items)
   
_IO_CONNECT and non POSIX() API calls....  
I have a small program that uses the POSIX API calls like open(), read() to read a file. This file is "managed" by my 
resource manager. (ie, it is under my resource manager's mount point).

I want to find a non POSIX way to read from the file.

C program fragment (error checking code omitted):

int fd = open("/home/narrow/if.txt", O_RDONLY);
read(fd, buf, 20);

The kernel event trace is below, with some of my questions:

Event, Time, Owner, Type, Data
74272, 2s 576ms 892us, MyTestProgram Thread 1, ConnectAttach Enter, nd 0x0 pid 1 chid 0x1 index 0 flags 0x1 process 
procnto-smp-instr
	--> seems like it is making contact with the Process Manager. why?
74273, 2s 576ms 894us, MyTestProgram Thread 1, ConnectAttach Exit, coid 0x3
	--> seems like it got a connecton id 3
74274, 2s 576ms 895us, MyTestProgram Thread 1, MsgSendv Enter, coid 0x3 sparts 2 rparts 2 msg0 0x20100 msg1 0x0 msg2 
0x100a18 function _IO_CONNECT_OPEN
	--> seems like the POSIX open() call resulted in a Message Send to procnto. Why?
74357, 2s 577ms 121us, MyTestProgram Thread 1, MsgSendv Exit, status 2148204544 rmsg 0x20100
	--> how do I interpet the return value?
74366, 2s 577ms 154us, MyTestProgram Thread 1, ConnectAttach Enter, nd 0x0 pid 630794 chid 0x1 index 0 flags 0x1 process
 MyResourceManager
	--> seems like the POSIX open() call resulted in a Message Send to MyResourceManager. This was expected.
74368, 2s 577ms 158us, MyTestProgram Thread 1, ConnectAttach Exit, coid 0x3
	--> seems like it got a connecton id 3
74369, 2s 577ms 159us, MyTestProgram Thread 1, MsgSendv Enter, coid 0x3 sparts 2 rparts 2 msg0 0x20100 msg1 0x0 msg2 
0xf0998 function _IO_CONNECT_OPEN
	--> seems like it now sends a message (_IO_CONNECT) to my resource manager. Expected. How do I know the contents of the
 _IO_CONNECT? 
	--> Is it a two part IOV? if so, what is in those two parts?
134486, 3s 579ms 311us, MyTestProgram Thread 1, MsgSendv Exit, status 4294967295 rmsg 0x1

In this case, my registered callout for open(0 does get invoked.

QNX native fragment (error checking code omitted):

typedef struct
{
	uint16_t msg_type;
	unsigned data_size;
} header_t;

coid = ConnectAttach(0, 630794, 1, 0, 1); // I know that the pid of MyResourceManager is 630794

iov_t siov[2];

header_t hdr;
hdr.msg_type = _IO_CONNECT;
hdr.data_size = strlen("if.txt");
SETIOV (&siov[0], &hdr, sizeof hdr);
SETIOV (&siov[1],"if.txt", hdr.data_size);

char rec_msg[100];
int status = MsgSendvs(coid, siov, 2,rec_msg, sizeof (rec_msg) );
if(-1 == status)
{   //was there an error sending to server?
	printf("could not send message with errorno = %d and error string %s \n", errno, strerror(errno));
}

It prints the program output as: "could not send message with errorno = 89 and error string Function not implemented"

The corresponding kernel trace is:
Event, Time, Owner, Type, Data
49992, 1s 818ms 265us, ReaderAppSansPosix Thread 1, ConnectAttach Enter, nd 0x0 pid 1 chid 0x1 index 1073741824 flags 
0x0 process procnto-smp-instr
50054, 1s 819ms 153us, ReaderAppSansPosix Thread 1, ConnectAttach Exit, coid 0x40000000
	--> seems like it got a connecton id 0x40000000, different than the 3 in the above case
Event, Time, Owner, Type, Data
52646, 1s 824ms 422us, ReaderAppSansPosix Thread 1, ConnectAttach Enter, nd 0x0 pid 630794 chid 0x1 index 0 flags 0x1 
process MyResourceManager
52647, 1s 824ms 423us, ReaderAppSansPosix Thread 1, ConnectAttach Exit, coid 0x3
52648, 1s 824ms 425us, ReaderAppSansPosix Thread 1, MsgSendv Enter, coid 0x3 sparts 2 rparts 1 msg0 0x8040100 msg1 0x6 
msg2 0x0 function _IO_CONNECT
	--> this should have caused the message to show up in MyResourceManager (in the myio_open() which I specify during 
resmgr_attach())
	--> but this does not happen. Why?
	
What is the format of the _IO_CONNECT messsage that goes from the libc implementation of open() to a resource manager? I
 do not have the source code for libc....
View Full Message
RE: _IO_CONNECT and non POSIX() API calls....  
Hi,

first, to answer your question as to why your application "is making contact with the Process Manager": Because the 
process manager is the one who keeps track of all registered path prefixes in the system; so in order to map your 
pathname "/home/narrow/if.txt" to the triple of nd/pid/chid required for ConnectAttach() to the resmgr, your application
 needs to ask the process manager.

Regarding your question about the format of the "IO_CONNECT" message - I could tell you that the format of this message 
is defined in /usr/include/sys/iomsg.h, but I won't, unless you can provide a really good reason why you would want to 
send such a message by yourself. You will probably get the most helpful information if you can elaborate a bit on what 
you're ultimately trying to achieve; spoofing system (rsp., libc) messages is usually just asking for unnecessary 
trouble.

Kind regards,
Thomas


-----Original Message-----
From: Manoj Sati [mailto:community-noreply@qnx.com] 
Sent: Freitag, 21. März 2014 13:10
To: ostech-core_os
Subject: _IO_CONNECT and non POSIX() API calls....


I have a small program that uses the POSIX API calls like open(), read() to read a file. This file is "managed" by my 
resource manager. (ie, it is under my resource manager's mount point).

I want to find a non POSIX way to read from the file.

C program fragment (error checking code omitted):

int fd = open("/home/narrow/if.txt", O_RDONLY); read(fd, buf, 20);

The kernel event trace is below, with some of my questions:

Event, Time, Owner, Type, Data
74272, 2s 576ms 892us, MyTestProgram Thread 1, ConnectAttach Enter, nd 0x0 pid 1 chid 0x1 index 0 flags 0x1 process 
procnto-smp-instr
	--> seems like it is making contact with the Process Manager. why?
74273, 2s 576ms 894us, MyTestProgram Thread 1, ConnectAttach Exit, coid 0x3
	--> seems like it got a connecton id 3
74274, 2s 576ms 895us, MyTestProgram Thread 1, MsgSendv Enter, coid 0x3 sparts 2 rparts 2 msg0 0x20100 msg1 0x0 msg2 
0x100a18 function _IO_CONNECT_OPEN
	--> seems like the POSIX open() call resulted in a Message Send to procnto. Why?
74357, 2s 577ms 121us, MyTestProgram Thread 1, MsgSendv Exit, status 2148204544 rmsg 0x20100
	--> how do I interpet the return value?
74366, 2s 577ms 154us, MyTestProgram Thread 1, ConnectAttach Enter, nd 0x0 pid 630794 chid 0x1 index 0 flags 0x1 process
 MyResourceManager
	--> seems like the POSIX open() call resulted in a Message Send to MyResourceManager. This was expected.
74368, 2s 577ms 158us, MyTestProgram Thread 1, ConnectAttach Exit, coid 0x3
	--> seems like it got a connecton id 3
74369, 2s 577ms 159us, MyTestProgram Thread 1, MsgSendv Enter, coid 0x3 sparts 2 rparts 2 msg0 0x20100 msg1 0x0 msg2 
0xf0998 function _IO_CONNECT_OPEN
	--> seems like it now sends a message (_IO_CONNECT) to my resource manager. Expected. How do I know the contents of the
 _IO_CONNECT? 
	--> Is it a two part IOV? if so, what is in those two parts?
134486, 3s 579ms 311us, MyTestProgram Thread 1, MsgSendv Exit, status 4294967295 rmsg 0x1

In this case, my registered callout for open(0 does get invoked.

QNX native fragment (error checking code omitted):

typedef struct
{
	uint16_t msg_type;
	unsigned data_size;
} header_t;

coid = ConnectAttach(0, 630794, 1, 0, 1); // I know that the pid of MyResourceManager is 630794

iov_t siov[2];

header_t hdr;
hdr.msg_type = _IO_CONNECT;
hdr.data_size = strlen("if.txt");
SETIOV (&siov[0], &hdr, sizeof hdr);
SETIOV (&siov[1],"if.txt", hdr.data_size);

char rec_msg[100];
int status = MsgSendvs(coid, siov, 2,rec_msg, sizeof (rec_msg) );
if(-1 == status)
{   //was there an error sending to server?
	printf("could not send message with errorno = %d and error string %s \n", errno, strerror(errno)); }

It prints the program output as: "could not send message with errorno = 89 and error string Function not implemented"

The corresponding kernel trace is:
Event, Time,...
View Full Message
Re: RE: _IO_CONNECT and non POSIX() API calls....  
Hi Thomas,

Thanks for the quick reply.

Thanks for corroborating the answer to my 1st question - I guess I knew that, but I was unable to reconcile the 
differences in the two traces - hence the reason for asking.

Yes, I did look at the iomsh.h header, and saw the declaration of struct _io_connect, with its 17 constituent members. 
But I assume this is for use within the implementation of callouts in resource manager, i.e., :

int
myio_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
    // here we can do things like msg->connect.path (to get file name), msg->connect.type (to get type information), msg
->connect.subtype (to get subtype information), etc...
 
}

The reason for asking this is partly academic, partly professional. When I build that resource manager for my mount 
point, I want to be sure that my callouts like myio_open() - get invoked from the resource manager library in both cases
 - a) when the client application is POSIX compliant and b) when the client application is written using "native" QNX 
kernel calls without using any POSIX api. I know the 2nd case might be infrequent, still I'd like to be sure.

It is with regard that I attempted to write a small sample program that would "mimic" a POSIX like application, and be 
sure that my callouts in my resource manager did indeed get invoked.

Thanks,
MS
RE: RE: _IO_CONNECT and non POSIX() API calls....  
Hi Manoj,

I'm pretty glad you don't seem to be planning a re-implementation of the open() call by generating IO_CONNECT messages 
yourself. I've seen the open() code, it isn't all that trivial. 

Regarding the _io_connect members - you definitely shouldn't, even for purely academic testing purposes, rely on any of 
these members not being used, evaluated, or interpreted by the resource manager framework. To give just one example, the
 file_type member will surely be checked to make sure your resource manager is capable of handling the type of open() 
that the client used.

Now for your (b) case, where a client tries to communicate with a resource manager by sending the system messages "
manually" instead via the appropriate POSIX calls -- such an approach is not only infrequent, as you correctly point out
, it is also strongly discouraged by us (we obviously do need to ship "iomsg.h", to allow implementation of resource 
managers; we do not ship it with the intention of it being used on the client side). Thus, I think you can safely 
disregard the case of "hand-crafted" IO_CONNECT or other system messages. Any client sending such messages is operating 
at its own risk, and obviously it would be required to fully stick to the protocol (i.e., send only messages that were 
not only partially set up). The resource manager is only required to execute functions if the associated messages are 
set up exactly as they would have been by the according POSIX API calls.

A point that /could/ be tested (and part of that you already did, successfully) is whether the resource manager reacts 
in a defined and stable manner to invalid client messages -- i.e., make sure that a malformed client cannot negatively 
affect or even crash the server. 

Kind regards,
Thomas

-----Original Message-----
From: Manoj Sati [mailto:community-noreply@qnx.com] 
Sent: Freitag, 21. März 2014 13:55
To: ostech-core_os
Subject: Re: RE: _IO_CONNECT and non POSIX() API calls....

Hi Thomas,

Thanks for the quick reply.

Thanks for corroborating the answer to my 1st question - I guess I knew that, but I was unable to reconcile the 
differences in the two traces - hence the reason for asking.

Yes, I did look at the iomsh.h header, and saw the declaration of struct _io_connect, with its 17 constituent members. 
But I assume this is for use within the implementation of callouts in resource manager, i.e., :

int
myio_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra) {
    // here we can do things like msg->connect.path (to get file name), msg->connect.type (to get type information), msg
->connect.subtype (to get subtype information), etc...
 
}

The reason for asking this is partly academic, partly professional. When I build that resource manager for my mount 
point, I want to be sure that my callouts like myio_open() - get invoked from the resource manager library in both cases
 - a) when the client application is POSIX compliant and b) when the client application is written using "native" QNX 
kernel calls without using any POSIX api. I know the 2nd case might be infrequent, still I'd like to be sure.

It is with regard that I attempted to write a small sample program that would "mimic" a POSIX like application, and be 
sure that my callouts in my resource manager did indeed get invoked.

Thanks,
MS




_______________________________________________

OSTech
http://community.qnx.com/sf/go/post109555
To cancel your subscription to this discussion, please e-mail ostech-core_os-unsubscribe@community.qnx.com
Re: RE: RE: _IO_CONNECT and non POSIX() API calls....  
Thanks, again, Thomas, for the super quick reply! It is just my second month on QNX, so I am prone to make rookie 
mistakes :(

I am wondering if I can bother you with an additional point regarding the callouts and the _IO_CONNECT messages?

Certain POSIX calls like stat(), for example, carry the semantics of open(), fstat(), close(). According to the 
documentation (section titled "Combine Messages"), libc will optimize these three calls and issue either a 
_IO_COMBINE_CONNECT or _IO_COMBINE_CONNECT_CLOSE message, which will land up in my myio_open(). In that case, can I have
 the conditional code like this:

int myio_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
	if( msg->connect.subtype == _IO_CONNECT_COMBINE || msg->connect.subtype == _IO_CONNECT_COMBINE_CLOSE )
	{
		// maps to the client issuing a stat(), and I will get a stat callout later
		// same pattern would be observed for other such "combine" functions
	}
	if( msg->connect.subtype == _IO_CONNECT_OPEN )
	{
		//  maps to the client issuing an open()
	}
}

int io_stat(resmgr_context_t *ctp, io_stat_t *msg, RESMGR_OCB_T *ocb)
{
	// handle stat stuff here….
}

would the above thinking be accurate? I do handle the stat and the close_ocb callouts by providing my function pointers 
in the resmgr_io_funcs_t data structure.

What about POSIX methods like mkdir()? Any way to receive those? Or is that combination message too?

Any other section in the documentation that calls out the significance of the members of most data structures used by a 
resource manager? The header files do mention some comments and so do the doc, but at times they are not very clear.

Thanks,
Manoj