I have a client that performs a tppost of a database event(in this case a oracle RAC FAN event indicating a down node). I created another server that subscribes to this event. At this point I have had issues. From the server I am unable to perform a system call of tmshutdown and tmboot.
It performs the tmshutdown but not the tmboot. When i do the same thing from a client I have no issues. Is there something unique about the tuxedo server main preventing me from doing a system call effectively? The TMIB calls appear to work ok also but do nto restart the server. If someone has an idea thanks.
I then tried to perform the activity via TMIB calls but also had not luck:
void DBSTATECHGSERV(TPSVCINFO *svcinfo)
{
char charBuf[2000];
FBFR32 *fbfr;
FLDLEN32 len;
char *pEventName = NULL;
int i=0;
FBFR32 *ibuf = (FBFR32 *)tpalloc((char *)FMLTYPE32, NULL, 0);
Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
Fchg32(ibuf, TA_CLASS, 0,(char*) "T_SERVER", 0);
Fchg32(ibuf, TA_GRPNO, 0, (char *)"1", 0);
Fchg32(ibuf, TA_SERVERNAME, 0, (char *)"ECHO", 0);
Fchg32(ibuf, TA_SRVID, 0, (char *)"10", 0);
Fchg32(ibuf, TA_STATE, 0, (char *)"DEA", 0);
int retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (l
ong)0);
//int retc = tpadmcall(ibuf, &ibuf, 0);
if ( retc < 0)
{
printf("tpadmcall() failed:%s\n",tpstrerror(tperrno));
}
Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
Fchg32(ibuf, TA_CLASS, 0,(char*) "T_SERVER", 0);
Fchg32(ibuf, TA_GRPNO, 0, (char *)"1", 0);
Fchg32(ibuf, TA_SERVERNAME, 0, (char *)"ECHO", 0);
Fchg32(ibuf, TA_SRVID, 0, (char *)"10", 0);
Fchg32(ibuf, TA_STATE, 0, (char *)"ACT", 0);
retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (long)
0);
//int retc = tpadmcall(ibuf, &ibuf, 0);
if ( retc < 0)
{
printf("tpadmcall() failed:%s\n",tpstrerror(tperrno));
}
tpfree((char *)ibuf);
userlog("got the subscription ");
execl("/home/hems/prod/getit.sh","","getit.sh", NULL);
i = system("getit.sh ");
userlog("return value from system call %d ",i);
//i = system("tmboot -yg -yg TESTGRP_1 ");
//userlog("return value from system call %d ",i);
Your buffersize for your tpalloc is zero:
FBFR32 *ibuf = (FBFR32 *)tpalloc((char *)FMLTYPE32, NULL, 0);
You may change it from zero to something lilke 1024. Tuxedo will adjust the actual size on the outbound.
Also verify that the last argument in tpcall does not have a space in the 'long' cast.
int retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (l ong)0);
Modified to 1024 and received service failure; going to review the columns for that class maybe something with that.
Jim
here is the tmconfig output for that server:
Return value TAOK
Buffer contents:
TA_OPERATION 3
TA_SECTION 3
TA_STATUS Operation completed successfully
TA_OCCURS 1
TA_BASESRVID 10
TA_GRACE 200
TA_GRPNO 1
TA_MAX 1
TA_MAXGEN 10
TA_MIN 1
TA_RPPERM 438
TA_RQPERM 438
TA_SEQUENCE 10164
TA_SRVID 10
TA_STATE ACTIVE
TA_CLOPT -A
TA_CONV N
TA_ENVFILE /home/hems/prod/env/default.env
TA_RCMD
TA_REPLYQ Y
TA_RESTART Y
TA_RQADDR ECHO1
TA_SERVERNAME /home/hems/prod/appdir/ECHO
TA_SYSTEM_ACCESS FASTPATH
TA_SRVGRP TESTGRP_1
and the code
void DBSTATECHGSERV(TPSVCINFO *svcinfo)
{
char charBuf[2000];
FBFR32 *fbfr;
FLDLEN32 len=1024;
char *pEventName = NULL;
int i=0;
userlog("got there");
FBFR32 *ibuf = (FBFR32 *)tpalloc((char *)FMLTYPE32, NULL, len);
Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
Fchg32(ibuf, TA_CLASS, 0,(char*) "T_SERVER", 0);
Fchg32(ibuf, TA_SRVGRP, 0,(char*) "TESTGRP_1", 0);
Fchg32(ibuf, TA_GRPNO, 0, (char *)"1", 0);
Fchg32(ibuf, TA_SERVERNAME, 0, (char *)"ECHO", 0);
Fchg32(ibuf, TA_SRVID, 0, (char *)"10", 0);
Fchg32(ibuf, TA_STATE, 0, (char *)"DEA", 0);
Fchg32(ibuf, TA_CONV, 0, (char *)"N", 0);
Fchg32(ibuf, TA_SEQUENCE, 0, (char *)"10164", 0);
Fchg32(ibuf, TA_RQADDR, 0, (char *)"ECHO1", 0);
Fchg32(ibuf, TA_LMID, 0, (char *)"CWSFEP1", 0);
Fchg32(ibuf, TA_PID, 0, (char *)"9094", 0);
int retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (long)0);
if ( retc < 0)
{
printf("tpadmcall() failed:%s\n",tpstrerror(tperrno));
}
userlog("past call to set svr to dead");
// Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
// Fchg32(ibuf, TA_CLASS, 0,(char*) "T_SERVER", 0);
// Fchg32(ibuf, TA_GRPNO, 0, (char *)"1", 0);
// Fchg32(ibuf, TA_SERVERNAME, 0, (char *)"ECHO", 0);
// Fchg32(ibuf, TA_SRVID, 0, (char *)"10", 0);
// Fchg32(ibuf, TA_STATE, 0, (char *)"ACT", 0);
// retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (long)0);
//int retc = tpadmcall(ibuf, &ibuf, 0);
// if ( retc < 0)
// {
// printf("tpadmcall() failed:%s\n",tpstrerror(tperrno));
// }
userlog("past call to set svr to active");
tpfree((char *)ibuf);
userlog("got the subscription ");
//execl("/home/hems/prod/getit.sh","","getit.sh", NULL);
//i = system("getit.sh ");
//userlog("return value from system call %d ",i);
//i = system("tmboot -yg -yg TESTGRP_1 ");
//userlog("return value from system call %d ",i);
tpreturn(TPSUCCESS, 0, NULL, 0, 0);
}
and the associated userlog output:
132236.CWSFEP1!DBSTATECHGSERV.9472: 07192010: TUXEDO Version 6.5 HP-UX B.11.00 U 9000/898 1623623321 unlimited-user license.
132236.CWSFEP1!DBSTATECHGSERV.9472: LIBTUX_CAT:262: INFO: Standard main starting
132236.CWSFEP1!DBSTATECHGSERV.9472: the logging feature associated with DB waits is set to
132236.CWSFEP1!DBSTATECHGSERV.9472: Started Service DBSTATESERV: 1.1
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: { tpservice({"DBSTATECHGSERV", 0x4, 0x0, 0, 0, -1, {1279560175, 0, 1000}})
132255.CWSFEP1!DBSTATECHGSERV.9472: got there
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: { tpalloc("FML32", "", 1024)
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: } tpalloc = 0x4001aea8
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: { tpcall(".TMIB", 0x4001aea8, 0, 0x7f7f2c9c, 0x7f7f2c98, 0x0)
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: } tpcall = -1 [tperrno TPESVCFAIL]
132255.CWSFEP1!DBSTATECHGSERV.9472: past call to set svr to dead
132255.CWSFEP1!DBSTATECHGSERV.9472: past call to set svr to active
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: { tpfree(0x400289a8)
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: } tpfree
132255.CWSFEP1!DBSTATECHGSERV.9472: got the subscription
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: { tpreturn(2, 0, 0x0, 0, 0x0)
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: } tpreturn [long jump]
132255.CWSFEP1!DBSTATECHGSERV.9472: TRACE:at: } tpservice
132504.CWSFEP1!tmconfig.9572: 07192010: TUXEDO Version 6.5 HP-UX B.11.00 U 9000/898 1623623321 unlimited-user license.
132504.CWSFEP1!tmconfig.9572: LIBTUX_CAT:1376: WARN: TUXDIR value "/opt/tuxedo6.5" in environment does not match configuratio
n "/opt/tuxedo"
Hi,
My recommendation is to get a working ud32 script to do what you want before trying to do it in code. Then once you have the proper MIB request created, simply copy it in code. My guess is you are being way to specific in your identifying the server. All you should need is the TA_SRVGRP and TA_SRVID I think. You definitely can't set some of the fields you are trying to set such as TA_PID. Those extra fields, especially the readonly ones are most likely causing your MIB request to fail.
Regards,
Todd Little
Oracle Tuxedo Chief Architect
I did what you mention yesterday and came up with the following:
#
#/bin/ksh
#
export FIELDTBLS32=tpadm,Usysfl32,evt_mib,tpadm
export FLDTBLDIR32=${TUXDIR}/udataobj
#
ud32 -C tpsysadm < ud32dead.txt
#
#
ud32 -C tpsysadm < ud32active.txt
Contents of ud32dead.txt:
SRVCNM .TMIB
TA_FLAGS 65536
TA_OPERATION SET
TA_CLASS T_SERVER
TA_GRPNO 1
TA_SRVID 10
TA_STATE DEAD
Contents of ud32aCTIVE.TXT:
SRVCNM .TMIB
TA_FLAGS 65536
TA_OPERATION SET
TA_CLASS T_SERVER
TA_GRPNO 1
TA_SRVID 10
TA_STATE ACTIVE
This works like a champ. I then added this as a system call to the server program and it also worked. This may prove to actually be a more flexible way to accomplish this but still wanted to understand what is wrong with what I am doing in the server. I was able to set the domain to protected via this code and an example you worked with on another person:
Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
Fchg32(ibuf, TA_CLASS, 0, (char *)"T_DOMAIN", 0);
Fchg32(ibuf, TA_SYSTEM_ACCESS, 0, (char *)"PROTECTED", 0);
int retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (long)0);
userlog("value of retc %d",retc);
if ( retc < 0)
{
userlog("tpadmcall() failed:%s",tpstrerror(tperrno));
}
So I think my security is correct. When I try the folllowing code I receive an error
int tpsvrinit(int argc, char **argv)
{
TPEVCTL ctl;
int found = 0;
int i = 0;
TPINIT * tpinfo = (TPINIT*)tpalloc((char *)"TPINIT",NULL,TPINITNEED(20));
strcpy(tpinfo->grpname,"dba");
strcpy(tpinfo->usrname, "tuxedo");
strcpy(tpinfo->cltname, "tpsysadm");
strcpy(tpinfo->passwd,"XXXXX#");
// tpinfo->flags = TPSA_FASTPATH;
userlog("the logging feature associated with DB waits is set to %s",logWaits);
ctl.flags = TPEVSERVICE;
strcpy(ctl.name1, "DBSTATECHGSERV");
strcpy(ctl.name2, "");
if ((subscribeHandle = tpsubscribe("DB_STATE_CHG", "", &ctl, 0)) == -1)
{
if (tperrno != TPEMATCH)
{
/* Could not subscribe so just get out without starting since we can't do anything */
userlog("Could not subscribe, tperrno = '%s'", tpstrerror(tperrno));
return -1;
}
}
userlog("Started Service %s", DBSTATESERVX);
return 0;
}
void tpsvrdone(void)
{
/* Clean up subscription before exiting */
if (subscribeHandle != 0 && subscribeHandle != -1)
{
tpunsubscribe(subscribeHandle, 0);
}
}
/* Service Entry Point for subscription */
void DBSTATECHGSERV(TPSVCINFO *svcinfo)
{
char charBuf[2000];
FBFR32 *fbfr;
FLDLEN32 len=1024;
char *pEventName = NULL;
int i=0;
long srvid=10;
long grpno=1;
userlog("got there");
FBFR32 *ibuf = (FBFR32 *)tpalloc((char *)FMLTYPE32, NULL, len);
//Fchg32(ibuf, TA_FLAGS, 0,(char*) "65536", 0);
Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
Fchg32(ibuf, TA_CLASS, 0,(char*) "T_SERVER", 0);
Fchg32(ibuf, TA_GRPNO, 0, (char *)"1", 0);
Fchg32(ibuf, TA_SRVID, 0, (char *)"10", 0);
Fchg32(ibuf, TA_STATE, 0, (char *)"DEAD", 0);
//Fchg32(ibuf, TA_SRVGRP, 0,(char*) "TESTGRP_1", 0);
//Fchg32(ibuf, TA_SERVERNAME, 0, (char *)"ECHO", 0);
//Fchg32(ibuf, TA_LMID, 0, (char *)"CWSFEP1", 0);
//Fchg32(ibuf, TA_PID, 0, (char *)"9094", 0);
//Fchg32(ibuf, TA_OPERATION, 0,(char*) "SET", 0);
//chg32(ibuf, TA_CLASS, 0, (char *)"T_DOMAIN", 0);
//Fchg32(ibuf, TA_SYSTEM_ACCESS, 0, (char *)"PROTECTED", 0);
int retc = tpcall((char *)".TMIB", (char *)ibuf, 0, (char **)&ibuf, &len, (long)0);
userlog("value of retc %d",retc);
if ( retc < 0)
{
userlog("tpadmcall() failed:%s",tpstrerror(tperrno));
}
// userlog("past call to set svr to dead");
This is the userlog output from the above.
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: { tpservice({"DBSTATECHGSERV", 0x4, 0x0, 0, 0, -1, {1279653754, 0, 1000}})
152234.CWSFEP1!DBSTATECHGSERV.4488: got there
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: { tpalloc("FML32", "", 1024)
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: } tpalloc = 0x4001aea0
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: { tpcall(".TMIB", 0x4001aea0, 0, 0x7f7f2ca4, 0x7f7f2ca0, 0x0)
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: } tpcall = -1 [tperrno TPESVCFAIL]
152234.CWSFEP1!DBSTATECHGSERV.4488: value of retc -1
152234.CWSFEP1!DBSTATECHGSERV.4488: tpadmcall() failed:TPESVCFAIL - application level service failure
152234.CWSFEP1!DBSTATECHGSERV.4488: past call to set svr to active
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: { tpfree(0x400289a0)
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: } tpfree
152234.CWSFEP1!DBSTATECHGSERV.4488: got the subscription
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: { tpreturn(2, 0, 0x0, 0, 0x0)
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: } tpreturn [long jump]
152234.CWSFEP1!DBSTATECHGSERV.4488: TRACE:at: } tpservice
Something I am just not seeing. Thanks for your time.
Jim
Hi Jim,
I don't believe you can perform a tpinit() inside a server the way you are. A server normally acts on behalf of the client that called it. For a server to act as a different client, you would need to use the user created context feature that was added in Tuxedo 10gR3. See the 10gR3 release notes at: http://download.oracle.com/docs/cd/E13161_01/tuxedo/docs10gr3/relnotes/relnotes.html#wp385436
Essentially you will need to create a separate thread to make the request and in that thread use tpappthrinit() to perform the tpinit so you connect as tpsysadm.
Regards,
Todd Little
Oracle Tuxedo Chief Architect