Manoj Sati(deleted)
|
_IO_CONNECT and non POSIX() API calls....
|
Manoj Sati(deleted)
03/21/2014 8:09 AM
post109550
|
_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
|
|
|
Thomas Haupt
|
RE: _IO_CONNECT and non POSIX() API calls....
|
Thomas Haupt
03/21/2014 8:30 AM
post109553
|
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
|
|
|
Manoj Sati(deleted)
|
Re: RE: _IO_CONNECT and non POSIX() API calls....
|
Manoj Sati(deleted)
03/21/2014 8:55 AM
post109555
|
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
|
|
|
Thomas Haupt
|
RE: RE: _IO_CONNECT and non POSIX() API calls....
|
Thomas Haupt
03/21/2014 9:28 AM
post109557
|
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
|
|
|
Manoj Sati(deleted)
|
Re: RE: RE: _IO_CONNECT and non POSIX() API calls....
|
Manoj Sati(deleted)
03/21/2014 10:42 AM
post109561
|
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
|
|
|
|