Skip to content

Commit

Permalink
Module registry initial implementation
Browse files Browse the repository at this point in the history
To address potential LPA shortages when multiple ZIS instances are
running on the same LPAR, a new feature--the module registry--has been
introduced.

The module registry is a set of data structures in common storage in
which eligible modules are traced. An eligible module is a module marked
with a special macro; the mark and the module names are then used to
uniquely identify the module. Once ZIS and its plug-in modules are
marked, they can be added to the registry and shared: if another ZIS
instance needs to load an identical module to the LPA, it will reuse
a previously registered (and loaded to the LPA) module instead. Sharing
identical modules should dramatically decrease the LPA footprint.

This feature must not be used when an application wants to remove its
modules from the LPA (e.g., ZIS does that in dev mode) because it will
affect any other applications using the same modules.

Fixes: #405

Signed-off-by: Irek Fakhrutdinov <[email protected]>
  • Loading branch information
ifakhrutdinov committed Oct 30, 2024
1 parent 4d91ad9 commit 5fc7874
Show file tree
Hide file tree
Showing 9 changed files with 878 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## `3.1.0`
- Bugfix: removed "ByteOutputStream" debug message, which was part of the `zwe` command output (#491)
- Bugfix: HEAPPOOLS and HEAPPOOLS64 no longer need to be set to OFF for configmgr (#497)
- Enhancement: module registry (#405)

## `3.0.0`
- Feature: added javascript `zos.getStatvfs(path)` function to obtain file system information (#482).
Expand Down
56 changes: 47 additions & 9 deletions c/crossmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "stcbase.h"
#include "utils.h"
#include "zvt.h"
#include "modreg.h"

#define CMS_STATIC_ASSERT($expr) typedef char p[($expr) ? 1 : -1]

Expand Down Expand Up @@ -367,6 +368,8 @@ void cmsInitializeLogging() {
logConfigureComponent(NULL, LOG_COMP_STCBASE, "STCBASE", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO);
logConfigureComponent(NULL, LOG_COMP_ID_CMS, "CIDB", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO);
logConfigureComponent(NULL, LOG_COMP_ID_CMSPC, "CIDB CM", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO);
logConfigureComponent(NULL, LOG_COMP_LPA, "LPA", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO);
logConfigureComponent(NULL, LOG_COMP_MODREG, "MODREG", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO);
printf("DATESTAMP JOBNAME ASCB (ASID) TCB MSGID MSGTEXT\n");

}
Expand Down Expand Up @@ -2442,6 +2445,8 @@ CrossMemoryServer *makeCrossMemoryServer2(
logSetLevel(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG);
logSetLevel(NULL, LOG_COMP_ID_CMSPC, ZOWE_LOG_DEBUG);
logSetLevel(NULL, LOG_COMP_STCBASE, ZOWE_LOG_DEBUG);
logSetLevel(NULL, LOG_COMP_LPA, ZOWE_LOG_DEBUG);
logSetLevel(NULL, LOG_COMP_MODREG, ZOWE_LOG_DEBUG);
}

EightCharString cmsModule = {0};
Expand Down Expand Up @@ -2483,6 +2488,10 @@ CrossMemoryServer *makeCrossMemoryServer2(
server->flags |= CROSS_MEMORY_SERVER_FLAG_RESET_LOOKUP;
}

if (flags & CMS_SERVER_FLAG_USE_MODREG) {
server->flags |= CROSS_MEMORY_SERVER_FLAG_USE_MODREG;
}

int allocResourcesRC = allocServerResources(server);
if (allocResourcesRC != RC_CMS_OK) {
safeFree31((char *)server, sizeof(CrossMemoryServer));
Expand Down Expand Up @@ -3388,17 +3397,41 @@ static int allocateGlobalResources(CrossMemoryServer *server) {
globalArea->serverFlags |= server->flags;
globalArea->serverASID = getMyPASID();

/* Load the module to LPA if needed, otherwise re-use the existing module. */
const char *statusText = "n/a";
/* Register the module or load it to LPA if needed, otherwise re-use the
* existing module. */
if (moduleAddressLPA == NULL) {

int lpaAddRSN = 0;
int lpaAddRC = lpaAdd(&server->lpaCodeInfo, &server->ddname, &server->dsname,
&lpaAddRSN);
if (lpaAddRC != 0) {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE, CMS_LOG_LPA_LOAD_FAILURE_MSG, lpaAddRC, lpaAddRSN);
return RC_CMS_LPA_ADD_FAILED;
/* Load to the LPA manually only if the "clean LPA" (dev mode) is enabled
* or the "use module registry" option is disabled. */
if (server->flags & CROSS_MEMORY_SERVER_FLAG_CLEAN_LPA ||
!(server->flags & CROSS_MEMORY_SERVER_FLAG_USE_MODREG)) {
int lpaAddRSN = 0;
int lpaAddRC = lpaAdd(&server->lpaCodeInfo, &server->ddname,
&server->dsname, &lpaAddRSN);
if (lpaAddRC == 0) {
statusText = "own instance loaded to LPA";
} else {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE,
CMS_LOG_LPA_LOAD_FAILURE_MSG, lpaAddRC, lpaAddRSN);
return RC_CMS_LPA_ADD_FAILED;
}
} else {
uint64_t modregRSN;
int modregRC = modregRegister(server->ddname, server->dsname,
&server->lpaCodeInfo, &modregRSN);
if (modregRC == RC_MODREG_OK) {
statusText = "new instance added to registry";
} else if (modregRC == RC_MODREG_ALREADY_REGISTERED) {
statusText = "instance reused from registry";
} else {
zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_SEVERE,
CMS_LOG_MODREG_ADD_FAILURE_MSG, modregRC, modregRSN);
return RC_CMS_MODREG_FAILED;
}
}
globalArea->lpaModuleInfo = server->lpaCodeInfo;
moduleAddressLPA =
server->lpaCodeInfo.outputInfo.stuff.successInfo.loadPointAddr;

zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG, CMS_LOG_DEBUG_MSG_ID
" module successfully loaded into LPA @ 0x%p, LPMEA:\n",
Expand All @@ -3408,6 +3441,7 @@ static int allocateGlobalResources(CrossMemoryServer *server) {

} else {

statusText = "previously added/loaded instance reused";
server->lpaCodeInfo = globalArea->lpaModuleInfo;

zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_DEBUG, CMS_LOG_DEBUG_MSG_ID
Expand All @@ -3417,9 +3451,11 @@ static int allocateGlobalResources(CrossMemoryServer *server) {

}

zowelog(NULL, LOG_COMP_ID_CMS, ZOWE_LOG_INFO, CMS_LOG_MODULE_STATUS_MSG,
statusText, moduleAddressLPA);

/* The required module is in LPA, update the corresponding fields. */
globalArea->lpaModuleTimestamp = getServerBuildTimestamp();
moduleAddressLPA = server->lpaCodeInfo.outputInfo.stuff.successInfo.loadPointAddr;
server->moduleAddressLPA = moduleAddressLPA;

/* Prepare the service table */
Expand Down Expand Up @@ -4925,6 +4961,8 @@ static int testEnvironment(const CrossMemoryServer *srv) {

int cmsStartMainLoop(CrossMemoryServer *srv) {

MODREG_MARK_MODULE();

int envStatus = testEnvironment(srv);
if (envStatus != 0) {
return envStatus;
Expand Down
Loading

0 comments on commit 5fc7874

Please sign in to comment.