Thanks for all the helpful information there! Yes, I am writing an exit for needs that the 9.4.3 Positive Authority Events will cover. Wasn't aware of that new feature, so thanks for the heads up on that. We follow the LTS roll out, so I may have use of the exit until we get this new functionality in the next version of IBM MQ. I ended landing on this Hconn logic for my exit. It will more than likely just use the passed in Hconn in the MQCXP.
pParms->pEntryPoints->MQPUT1_Call(Hcon, /* connection handle */
&od, /* object descriptor */
&md, /* message descriptor */
&pmo, /* default options */
messlen, /* message length */
messageBuffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
if (needMQDISC)
{
pParms->pEntryPoints->MQDISC_Call(&Hcon, /* connection handle */
&CompCode, /* completion code */
&Reason); /* reason code */
}
}
Original Message:
Sent: Wed November 19, 2025 10:47 PM
From: Morag Hughson
Subject: Channel Security Exit Hconn Question
Hi Tim,
Copying over the top of a DLL in Linux that is still loaded and being used is not advisable. Stopping the Queue Manager, while absolute, is probably more heavyweight than needed. Just make sure that all running channels are stopped. I tend to develop exits with a runmqlsr in the foreground with environment variable MQNOREMPOOL set to yes so I can fully control where the channels run, and also make use of printfs that I can actually see while developing.
Mark is quite right that the OSes vary hugely in this regard though. On Windows you can't get into the pickle you have because the copy would fail if it was currently loaded. On z/OS you can't get into the pickle you have because a new copy is loaded into memory each time a new version exists. No need to stop the queue manager. Also, even if you did need to cycle something, you only need to stop the CHIN address space for channel exits on z/OS.
Given that you know the SIGSEGV is as a result of the DLL overlay, I would argue against making a new hConn, unless you have some other reason to do it. Not sure exactly what your exit is doing, but it sounds like you are making a security exit, so the fact that MQPUT1s would be in the same batch as a channel messages is not quite so much of an issue - I assume you are doing an MQPMO_NO_SYNCPOINT put? If you're intending to code this exit on z/OS as well, remember to be explicit about that!
btw - is there any chance you are writing a channel exit version of the recently provided positive authority/authentication events? They capture inbound SSLPEER and SSLCERTI. See example in Using MQ Feature - Positive Authority Events
Cheers,
Morag
------------------------------
Morag Hughson
MQ Technical Education Specialist
MQGem Software Limited
Website: https://www.mqgem.com
Original Message:
Sent: Wed November 19, 2025 02:20 PM
From: Tim Zielke
Subject: Channel Security Exit Hconn Question
Just curious. Would the same approach be recommended for z/OS IBM MQ exits? For example, if you already have a loaded exit in your CHIN from CSQXLIB, and you want to update that exit, would it be recommended to first stop the queue manager before updating that same exit in the CSQXLIB dataset?
------------------------------
Tim Zielke
Original Message:
Sent: Wed November 19, 2025 01:55 PM
From: Tim Zielke
Subject: Channel Security Exit Hconn Question
For the example above, the original clientcert exit was just using the passed in Hconn from the MQCXP and only did an MQPUT1 for any MQI calls. However, there were long running client connections into the queue manager that would have invoked that original clientcert exit and were still running when the new cliencert exit update was copied into /var/mqm/exits64 and then later invoked (which caused the SIGSEGV in the amqrmppa process that the exit is running under). I will make sure going forward to not make any exit changes unless the queue manager is stopped, especially for changes to existing exits.
------------------------------
Tim Zielke
Original Message:
Sent: Wed November 19, 2025 12:51 PM
From: Mark Taylor
Subject: Channel Security Exit Hconn Question
That sounds plausible. Especially if your exit is doing its own MQCONN (did you do a matching MQDISC on channel terminate?)
Whenever I'm developing exits, I always restart the qmgr. And I don't actually put the new code version into the exits directory until the qmgr has stopped. Just to make sure. Different operating systems can behave in strange ways when you try to overwrite an in-use library, or try to load the same named file into a process. I've seen too many weird things to try to short-cut it.
There was an environment variable used around MQv5 timeframe - set AMQ_INHIBIT_DLCLOSE=true - that modified some of the dynamic load behaviour. Not needed these days, but I wonder if it might have had some effect here. Not necessarily positive ones, but it's possible that it might even have stopped you overwriting the exit until the qmgr was ended. Again, some of this tends to be OS-specific.
------------------------------
Mark Taylor
Winchester
Original Message:
Sent: Tue November 18, 2025 01:04 PM
From: Tim Zielke
Subject: Channel Security Exit Hconn Question
I think I found the issue with the SIGSEGV. This seems to be the flow that triggers it. This is being done on a Linux queue manager at 9.4.0.16.
1) You have a channel security exit (e.g. clientcert) that you are using that is making an MQI call (e.g. MQPUT1) to the queue manager. clientcert is located in /var/mqm/exits64.
2) You then copy a new version of clientcert to /var/mqm/exits64.
3) When you execute the new version of clientcert, the amqrmppa process crashes with a SIGSEGV.
When I look at the pmap of the amqrmppa address space after #1 and compare it to #3, it looks like the original exit was using some shared memory segments (probably due to the local connection to the queue manager) that are now deleted when I look at the pmap of the amqrmppa in the FDC that has the SIGSEGV. Not sure if that is the underlying issue, but this is how the issue is recreated.
------------------------------
Tim Zielke
Original Message:
Sent: Sat November 15, 2025 03:23 PM
From: Michel David
Subject: Channel Security Exit Hconn Question
It's generally safer to be defensive. Even if pParms->Hconn is valid, using a local copy like you described can prevent issues like the SIGSEGV you saw. Checking the handle before use and falling back to a new connection if needed adds stability, especially across different exit reasons and channel types.
------------------------------
Michel David
Original Message:
Sent: Fri November 14, 2025 01:44 PM
From: Tim Zielke
Subject: Channel Security Exit Hconn Question
If I am working with a channel security exit like this:
DllExport void MQENTRY ChlExit (PMQVOID pChannelExitParms,
PMQVOID pChannelDefinition,
PMQLONG pDataLength,
PMQLONG pAgentBufferLength,
PMQVOID pAgentBuffer,
PMQLONG pExitBufferLength,
PMQPTR pExitBufferAddr)
{
PMQCXP pParms = (PMQCXP)pChannelExitParms;
PMQCD pCD = (PMQCD)pChannelDefinition;
/* return if no addressability to input pointers we are using in exit, probably not needed but be defensive */
if (pParms == NULL || pCD == NULL)
return;
/* Only MQPUT1 when we have a security exit being called because of MQXR_SEC_PARMS */
/* Also make sure MQCXP version is >= 9, since we rely on values up until version 9 in this exit */
if(pParms->ExitId == MQXT_CHANNEL_SEC_EXIT && pParms->ExitReason == MQXR_SEC_PARMS && pParms->Version >= 9)
{
and I later want to do an MQPUT1 with the Hconn that is in the passed in MQCXP. I have a few questions about working with this Hconn.
1) Can I safely assume since I am at least at version 9 of the MQCXP that I will be provided a valid Hconn and just use it directly into the MQPUT1 call? For example:
pParms->pEntryPoints->MQPUT1_Call(pParms->Hconn, /* connection handle */
&od, /* object descriptor */
&md, /* message descriptor */
&pmo, /* default options */
messlen, /* message length */
messageBuffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
2) Or should I be defensive and not assume the Hconn is valid (e.g. 0) and do something like the following? High level, get my own connection and disconnect, assuming I was not returned an already active connection.
/* PUT1 our message data to a queue */
MQHCONN Hcon; /* connection handle */
MQOD od = {MQOD_DEFAULT}; /* Object Descriptor */
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
MQPMO pmo = {MQPMO_DEFAULT}; /* put message options */
MQLONG CompCode; /* completion code */
MQLONG Reason; /* reason code */
MQLONG messlen; /* message length received */
int needMQDISC = 0;
if (pParms->Hconn > 0)
{
Hcon = pParms->Hconn;
}
else
{
char QMName[50]; /* queue manager name */
QMName[0] = 0; /* default */
MQCNO cno = {MQCNO_DEFAULT}; /* connection options */
pParms->pEntryPoints->MQCONNX_Call(QMName, /* queue manager */
&cno, /* connection options */
&Hcon, /* connection handle */
&CompCode, /* completion code */
&Reason); /* reason code */
/* Do not MQDISC if already connected */
if (CompCode == 1 && Reason == 2002)
{
}
else
{
needMQDISC = 1;
}
}
pmo.Options = MQPMO_NO_SYNCPOINT; /* No syncpoint */
strncpy(od.ObjectName, "TCZ.QUEUE", MQ_Q_NAME_LENGTH);
messlen = mbOffset; /* length of message */
pParms->pEntryPoints->MQPUT1_Call(Hcon, /* connection handle */
&od, /* object descriptor */
&md, /* message descriptor */
&pmo, /* default options */
messlen, /* message length */
messageBuffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
if (needMQDISC)
{
pParms->pEntryPoints->MQDISC_Call(&Hcon, /* connection handle */
&CompCode, /* completion code */
&Reason); /* reason code */
}
One reason I am asking is that I have a found a scenario (channel security exit on a CLUSRCVR channel with an exit reason of MQXR_INIT_SEC) where the amqrmppa process hits a SIGSEGV and the queue manager becomes unstable when you pass the pParms->Hconn (which I have validated is a valid Hconn value) directly into the MQPUT1 call. What is interesting is that if you instead define an MQHCONN Hconn variable, assign Hconn = pParms->Hconn, and then call the MQPUT1 with the Hconn variable, the exit works fine. But this instability got me thinking if I should be more defensive in my coding in working with this pParms->Hconn.
------------------------------
Tim Zielke
------------------------------