Skip to content

Commit

Permalink
Zowe Suite v1.14.0
Browse files Browse the repository at this point in the history
  • Loading branch information
zowe-robot authored Jul 31, 2020
2 parents 01c368a + 1bfbef7 commit 6bc1ceb
Show file tree
Hide file tree
Showing 5 changed files with 497 additions and 49 deletions.
275 changes: 261 additions & 14 deletions c/crossmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,42 @@ typedef struct CrossMemoryServerLogServiceParm_tag {
int messageLength;
} CrossMemoryServerLogServiceParm;

typedef struct CrossMemoryServerDumpServiceParm_tag {

#define CMS_DUMP_SERVICE_PARM_EYECATCHER "ZWESXDSV"
#define CMS_DUMP_SERVICE_VERSION 1
// TODO we can improve the data size limit by passing the data address itself
#define CMS_DUMP_SERVICE_MAX_DATA_SIZE 512
#define CMS_DUMP_SERVICE_MAX_DESC_SIZE 32

char eyecatcher[8];
uint8_t version;
char reserved0[3];

LogMessagePrefix prefix;
char padding1[3];

char descriptionNullTerm[CMS_DUMP_SERVICE_MAX_DESC_SIZE];
uint64_t originalAddress;
uint32_t originalSize;
uint16_t dataLength;
char data[CMS_DUMP_SERVICE_MAX_DATA_SIZE];

} CrossMemoryServerDumpServiceParm;

typedef struct CrossMemoryServerMsgQueueElement_tag {

#define CROSS_MEMORY_SERVER_MSGQEL_TYPE_MSG 1
#define CROSS_MEMORY_SERVER_MSGQEL_TYPE_DUMP 2

QueueElement queueElement;
CPID cellPool;
char filler0[4];
CrossMemoryServerLogServiceParm logServiceParm;
uint8_t type;
char filler0[3];
union {
CrossMemoryServerLogServiceParm logServiceParm;
CrossMemoryServerDumpServiceParm dumpServiceParm;
};
} CrossMemoryServerMsgQueueElement;

typedef struct CrossMemoryServerConfigServiceParm_tag {
Expand Down Expand Up @@ -1596,6 +1627,7 @@ static int handleLogService(CrossMemoryServer *server, CrossMemoryServerLogServi
return allocRC;
}

newElement->type = CROSS_MEMORY_SERVER_MSGQEL_TYPE_MSG;
newElement->logServiceParm = localParm;

/* log service is always space switch */
Expand All @@ -1604,6 +1636,37 @@ static int handleLogService(CrossMemoryServer *server, CrossMemoryServerLogServi
return RC_CMS_OK;
}

static int handleDumpService(CrossMemoryServer *server,
CrossMemoryServerLogServiceParm *callerParm) {

if (callerParm == NULL) {
return RC_CMS_STDSVC_PARM_NULL;
}

CrossMemoryServerDumpServiceParm localParm;
cmCopyFromSecondaryWithCallerKey(&localParm, callerParm,
sizeof(CrossMemoryServerDumpServiceParm));

if (memcmp(localParm.eyecatcher, CMS_DUMP_SERVICE_PARM_EYECATCHER,
sizeof(localParm.eyecatcher))) {
return RC_CMS_STDSVC_PARM_BAD_EYECATCHER;
}

CrossMemoryServerMsgQueueElement *newElement = NULL;
int allocRC = allocateMsgQueueElement(server, &newElement);
if (allocRC != RC_CMS_OK) {
return allocRC;
}

newElement->type = CROSS_MEMORY_SERVER_MSGQEL_TYPE_DUMP;
newElement->dumpServiceParm = localParm;

/* dump service is always space switch */
qEnqueue(server->messageQueue, &newElement->queueElement);

return RC_CMS_OK;
}

static int handleConfigService(CrossMemoryServer *server,
CrossMemoryServerConfigServiceParm *callerParm) {

Expand Down Expand Up @@ -1652,7 +1715,7 @@ static int handleStandardService(CrossMemoryServer *server, CrossMemoryServerPar
status = handleLogService(server, localParmList->callerData);
break;
case CROSS_MEMORY_SERVER_DUMP_SERVICE_ID:
status = RC_CMS_PC_NOT_IMPLEMENTED;
status = handleDumpService(server, localParmList->callerData);
break;
case CROSS_MEMORY_SERVER_CONFIG_SERVICE_ID:
status = handleConfigService(server, localParmList->callerData);
Expand Down Expand Up @@ -2798,22 +2861,85 @@ static int establishPCRoutines(CrossMemoryServer *server) {
return RC_CMS_OK;
}

static void printLogServiceMsg(CrossMemoryServerMsgQueueElement *msgElement) {

CrossMemoryServerLogServiceParm *msgParm = &msgElement->logServiceParm;

if (memcmp(msgParm->eyecatcher, CMS_LOG_SERVICE_PARM_EYECATCHER,
sizeof(msgParm->eyecatcher))) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE,
CMS_LOG_INVALID_EYECATCHER_MSG, "log parm", msgParm);
zowedump(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, (char*) msgParm,
sizeof(CrossMemoryServerLogServiceParm));
return;
}

printf("%.*s", min(msgParm->messageLength, sizeof(msgParm->message)),
msgParm->message);
}

static void printDumpServiceMsg(CrossMemoryServerMsgQueueElement *dumpElement) {

CrossMemoryServerDumpServiceParm *dumpParm = &dumpElement->dumpServiceParm;

if (memcmp(dumpParm->eyecatcher, CMS_DUMP_SERVICE_PARM_EYECATCHER,
sizeof(dumpParm->eyecatcher))) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE,
CMS_LOG_INVALID_EYECATCHER_MSG, "dump parm", dumpParm);
zowedump(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, (char*) dumpParm,
sizeof(CrossMemoryServerDumpServiceParm));
return;
}

printf("%.*s"CMS_LOG_DUMP_MSG_ID" Dump of \'%s\' (%u bytes at 0x%p):\n",
sizeof(dumpParm->prefix.text), dumpParm->prefix.text,
dumpParm->descriptionNullTerm,
dumpParm->originalSize, dumpParm->originalAddress);

char workBuffer[4096];
for (int i = 0; ; i++) {
char *line = dumpWithEmptyMessageID(workBuffer, sizeof(workBuffer),
dumpParm->data, dumpParm->dataLength, i);
if (line == NULL) {
break;
}
printf("%*s%s\n", LOG_MSG_PREFIX_SIZE, "", line);
}

if (dumpParm->dataLength < dumpParm->originalSize) {
printf("%*s"CMS_LOG_DUMP_MSG_ID" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . \n",
LOG_MSG_PREFIX_SIZE, "");
printf("%*s"CMS_LOG_DUMP_MSG_ID" %u bytes have been truncated\n",
LOG_MSG_PREFIX_SIZE, "",
dumpParm->originalSize - dumpParm->dataLength);
}

}

static void flushDebugMessages(CrossMemoryServer *server) {

CrossMemoryServerMsgQueueElement *element =
(CrossMemoryServerMsgQueueElement *)qDequeue(server->messageQueue);

while (element != NULL) {

CrossMemoryServerLogServiceParm *msg = &element->logServiceParm;
if (logShouldTraceInternal(NULL, LOG_COMP_ID_CMSPC, ZOWE_LOG_INFO)) {

if (memcmp(msg->eyecatcher, CMS_LOG_SERVICE_PARM_EYECATCHER, sizeof(msg->eyecatcher))) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, CMS_LOG_INVALID_EYECATCHER_MSG, "log parm", msg);
zowedump(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, (char *)msg, sizeof(CrossMemoryServerLogServiceParm));
}
switch (element->type) {
case CROSS_MEMORY_SERVER_MSGQEL_TYPE_MSG:
printLogServiceMsg(element);
break;
case CROSS_MEMORY_SERVER_MSGQEL_TYPE_DUMP:
printDumpServiceMsg(element);
break;
default:
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG,
CMS_LOG_DEBUG_MSG_ID" Bad msg element type @ 0x%p", element);
zowedump(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG, (char*)element,
sizeof(CrossMemoryServerMsgQueueElement));
break;
}

if (logShouldTraceInternal(NULL, LOG_COMP_ID_CMSPC, ZOWE_LOG_INFO)) {
printf("%.*s", msg->messageLength > sizeof(msg->message) ? sizeof(msg->message) : msg->messageLength, msg->message);
}

freeMsgQueueElement(element);
Expand Down Expand Up @@ -4004,11 +4130,78 @@ static int verifySTEPLIB(CrossMemoryServer *srv) {
return RC_CMS_OK;
}

#define MAIN_WAIT_MILLIS 10000
#define START_COMMAND_HANDLING_DELAY_IN_SEC 5
#define STCBASE_SHUTDOWN_DELAY_IN_SEC 5
static bool isReusableASID(void) {

int cmsStartMainLoop(CrossMemoryServer *srv) {
const char ascbreus = 0x40;

ASCB *ascb = getASCB();

return ascb->ascbflg3 & ascbreus;
}

__asm("CSVQRGLB CSVQUERY PLISTVER=0,MF=(L,CSVQRGLB)" : "DS"(CSVQRGLB));

static bool isModulePrivate(void) {

unsigned char attr = 0;
int queryRC = 0;

__asm("CSVQRGLB CSVQUERY PLISTVER=0,MF=L" : "DS"(parmList));
parmList = CSVQRGLB;

/* Use the address of this function itself since it's in the module. */
unsigned moduleAddress = (unsigned)&isModulePrivate;

__asm(
" CSVQUERY INADDR=(%[addr]),OUTATTR3=%[attr]"
",PLISTVER=0,MF=(E,%[parm]) \n"
: [attr]"=m"(attr), "=NR:r15"(queryRC)
: [addr]"r"(&moduleAddress), [parm]"m"(parmList)
: "r0", "r1", "r14", "r15"
);

zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG,
"CSVQUERY of 0x%08X - attr = 0x%02X, RC = %d",
moduleAddress, attr, queryRC);

if (queryRC != 0) {
return false;
}

const unsigned char jobPackAreaMask = 0x40;
if (attr & jobPackAreaMask) {
return true;
}

return false;
}

#ifdef _LP64
#pragma linkage(BPX4QDB,OS)
#define BPXQDB BPX4QDB
#else
#pragma linkage(BPX1QDB,OS)
#define BPXQDB BPX1QDB
#endif

static bool isDubStatusOk(int *status, int *bpxRC, int *bpxRSN) {

const int dubFailRC = 4; /* QDB_DUB_MAY_FAIL */

BPXQDB(status, bpxRC, bpxRSN);

zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG,
CMS_LOG_DEBUG_MSG_ID" BPXnQDB RV = %d, RC = %d, RSN = 0x%08X\n",
*status, *bpxRC, *bpxRSN);

if (*status == dubFailRC) {
return false;
}

return true;
}

static int testEnvironment(void) {

int authStatus = testAuth();
if (authStatus != 0) {
Expand All @@ -4023,6 +4216,37 @@ int cmsStartMainLoop(CrossMemoryServer *srv) {
return RC_CMS_BAD_SERVER_KEY;
}

if (!isReusableASID()) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_WARNING, CMS_LOG_REUSASID_NO_MSG);
}

if (!isModulePrivate()) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_WARNING,
CMS_LOG_NON_PRIVATE_MODULE_MSG);
return RC_CMS_NON_PRIVATE_MODULE;
}

int dubStatus = 0, bpxRC = 0, bpxRSN = 0;
if (!isDubStatusOk(&dubStatus, &bpxRC, &bpxRSN)) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, CMS_LOG_DUB_ERROR_MSG,
dubStatus, bpxRC, bpxRSN & 0xFFFF);
return RC_CMS_BAD_DUB_STATUS;
}

return RC_CMS_OK;
}

#define MAIN_WAIT_MILLIS 10000
#define START_COMMAND_HANDLING_DELAY_IN_SEC 5
#define STCBASE_SHUTDOWN_DELAY_IN_SEC 5

int cmsStartMainLoop(CrossMemoryServer *srv) {

int envStatus = testEnvironment();
if (envStatus != 0) {
return envStatus;
}

int rcvrPushRC = recoveryPush(
"cmsStartMainLoop",
RCVR_FLAG_RETRY | RCVR_FLAG_DELETE_ON_RETRY | RCVR_FLAG_PRODUCE_DUMP,
Expand Down Expand Up @@ -4452,6 +4676,29 @@ int cmsPrintf(const CrossMemoryServerName *serverName, const char *formatString,
return cmsCallService(serverName, CROSS_MEMORY_SERVER_LOG_SERVICE_ID, &msgParmList, NULL);
}

int cmsHexDump(const CrossMemoryServerName *serverName,
const void *data, unsigned size, const char *description) {

CrossMemoryServerDumpServiceParm parm = {
.eyecatcher = CMS_DUMP_SERVICE_PARM_EYECATCHER,
.version = CMS_DUMP_SERVICE_VERSION,
.originalAddress = (uint64_t)data,
.originalSize = size,
};

initLogMessagePrefix(&parm.prefix);

strncpy(parm.descriptionNullTerm, description,
sizeof(parm.descriptionNullTerm) - 1);

parm.dataLength = min(sizeof(parm.data), size);

memcpy(parm.data, data, parm.dataLength);

return cmsCallService(serverName, CROSS_MEMORY_SERVER_DUMP_SERVICE_ID,
&parm, NULL);
}

int cmsGetConfigParm(const CrossMemoryServerName *serverName, const char *name,
CrossMemoryServerConfigParm *parm) {

Expand Down
Loading

0 comments on commit 6bc1ceb

Please sign in to comment.