You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Setup: a stone and netldi that Jasper manages get started outside Jasper — e.g. by hand from a terminal after a machine reboot — from a shell whose GemStone environment differs from Jasper's own (a different GEMSTONE_GLOBAL_DIR, or an inherited GEMSTONE_NRS_ALL that points their registration at a different directory). The external stone and netldi use the same names as a database Jasper manages.
Outside Jasper, start <stone> and its <netldi> from a terminal (same names as a Jasper-managed database), in a shell whose GemStone environment differs from Jasper's.
In Jasper, click the login for that database and try to connect.
The connect does not just work — instead:
The Databases tree shows a contradictory state — e.g. <stone>Running but <netldi>Stopped — even though both processes are alive on the host.
The login fails as though the stone isn't running (Jasper can't traverse a NetLDI its own gslist doesn't see), and Jasper offers to start the database.
Accepting the offer collides with the already-running external servers (name already in use / registered elsewhere), and in some states a raw GEMSTONE environment variable is not defined error surfaces.
Seeing "not running" and "GEMSTONE not defined," the user goes off to debug their shell profile and GemStone install — when the real cause is simply that the servers were started outside Jasper's environment and registered where Jasper's own gslist doesn't look.
Summary
Jasper runs its own gslist in its own environment — it sets GEMSTONE_GLOBAL_DIR to its configured root (sysadminStorage.getRootPath()) and discovers servers by their .LCK files in that root's locks/ directory. A stone or netldi started outside Jasper — by hand, or from a shell carrying different GemStone environment (e.g. an inherited GEMSTONE_NRS_ALL or a different GEMSTONE_GLOBAL_DIR) — registers in a differentlocks/ directory, so Jasper's gslist can't see it even though the OS process is alive. Servers started outside Jasper can't be prevented, so Jasper should recognize this situation and offer to reconcile it instead of showing a misleading state.
This issue also folds in two related state-accuracy fixes (see Related state-accuracy fixes below) that came out of the same investigation: status should reflect reachability rather than mere process presence, and Jasper's discovery environment should be deterministic rather than perturbed by the launching shell's leftover GemStone variables.
Motivation / what goes wrong today
The tree can show a contradictory, partial state — e.g. "Stone Running / NetLDI Stopped" while both processes are alive — because one registered where Jasper looks and the other didn't.
A login fails (it must traverse a NetLDI that Jasper's gslist can't see), and the failure reads as "the stone isn't running" when it plainly is.
In some states a raw GemStone shell-script error (GEMSTONE environment variable is not defined) is relayed verbatim, sending the user off to debug their shell profile for a problem that isn't in their shell.
Acceptance criteria
For each managed database, Jasper detects when a stoned/netldid process matching that database's stone/ldi name and version is running but is not visible in Jasper's own gslist (its locks/ dir), and classifies it as "started outside Jasper's environment."
On connect (and reflected on tree refresh), when such a server is detected, Jasper offers to reconcile with a dialog worded as a mismatch, not a missing install. Example wording:
"<stone> and <netldi> are running, but were started outside Jasper's environment, so they're registered where Jasper's own gslist doesn't look. (Jasper runs its own gslist in its own environment, which can differ from gslist on the host — so a server can look Stopped to Jasper while it's alive on the host.) Restart them under Jasper's environment and connect?"
[Restart & Connect] [Connect as-is] [Cancel]
Restart & Connect stops the external stone/netldi (clean stopstone/stopnetldi, with the existing force-kill fallback), then does Jasper's normal start + connect, so everything lands in Jasper's own locks/ dir.
Before Restart & Connect stops anything, confirm the running same-named server is actually the managed database. If it can't be confirmed, warn that it may be a different stone that merely shares the name, and do not auto-stop it. (Identity by name alone is ambiguous — see Implementation notes.)
The reconcile dialog warns that restarting the stone drops any uncommitted sessions on it.
If Jasper cannot stop or kill the external server, it does not dead-end: it shows enough to resolve by hand — stone name, netldi name, process IDs, and the directory the server is registered in — plus how to inspect it (e.g. gslist pointed at that directory).
Jasper never surfaces the child script's bare GEMSTONE environment variable is not defined; that path is replaced by the situation-specific message above.
The failure message is not phrased as "GemStone <version> install path isn't configured" — a user who already installed that version would be baffled by that.
Related state-accuracy fixes (folded in)
Both came out of the same investigation and share the root cause above — Jasper's view of server state must be accurate and self-consistent regardless of how or where servers were started. Filed here rather than separately.
Status should reflect reachability, not just process presence
Today the tree shows Running whenever a matching process appears in Jasper's own gslist, even if the stone has no reachable NetLDI and a login cannot actually connect — so the tree can directly contradict a failing login.
A stone that is running but not connectable (its NetLDI is unreachable, or it's registered outside Jasper) is shown in a distinct "running but not connectable" state — never a plain, healthy Running.
The Running/Stopped state the tree shows must not contradict what a connect attempt will actually do. One approach: give the isStoneRunning-style checks a reachability notion instead of trusting gslist presence alone.
Discovery environment should be deterministic
The start path (getEnvironment) sets GEMSTONE_NRS_ALL, but versionEnvironment — used for gslist discovery and the version terminal — sets no GEMSTONE_NRS_ALL at all. So a stray inherited GEMSTONE_NRS_ALL / GEMSTONE_GLOBAL_DIR from the shell that launched the editor can sway what Jasper discovers and where a version-terminal command lands.
The environment used for discovery (and the version terminal) normalizes these variables the same way the start path does, so Jasper's view matches what it actually manages and isn't perturbed by the launching shell's leftovers.
Implementation notes
(Possibilities, not prescriptions.)
The building blocks exist: each database's stone/ldi name and version are known; processManager already does ps-based process inspection (classifyPidOwnership, forceKillStone, inspectStaleLock) and has a clean-stop-with-force-fallback path; version matching has a versionsMatch guard to reuse so two installed versions sharing a stone name don't collide.
The missing piece is the cross-check: "a process matching my stone/ldi name+version exists, but it's absent from my own gslist." One approach is a broad process scan (for stoned <stone> / netldid <ldi>) compared against the gslist Jasper already runs against its configured root.
A running stone's GEMSTONE_GLOBAL_DIR is fixed at start time — a live stone can't be re-homed into Jasper's directory — so reconcile must be stop + start, not re-registration.
Deciding "is this really my stone?" is the hard part, and name alone can't answer it — the same name can belong to a different stone. Matching the extent/data files the running stoned has open (e.g. from its command line or open files) against the managed database's path is a candidate signal, but not foolproof: a stone can be started against a different extent. So treat "can't confirm" as "not confirmed" (warn-only, don't stop it), and finding a more robust identity check is an open problem worth solving while implementing this.
Background (why the guard is part of this, not a separate issue)
The GEMSTONE environment variable is not defined errors observed in practice were the GemStone shell script's own stderr, relayed by Jasper, and occurred only while a mismatched/external server was in the picture. Jasper's own start path sets GEMSTONE correctly — a clean Jasper start+connect works even with GEMSTONE unset in the shell. So the hardening bundled here is (a) the situation-specific messaging above, and (b) resolving/verifying the environment up front and failing with an actionable message rather than relaying a raw shell-script error.
Reproduction (what the user hits)
Setup: a stone and netldi that Jasper manages get started outside Jasper — e.g. by hand from a terminal after a machine reboot — from a shell whose GemStone environment differs from Jasper's own (a different
GEMSTONE_GLOBAL_DIR, or an inheritedGEMSTONE_NRS_ALLthat points their registration at a different directory). The external stone and netldi use the same names as a database Jasper manages.<stone>and its<netldi>from a terminal (same names as a Jasper-managed database), in a shell whose GemStone environment differs from Jasper's.<stone>Running but<netldi>Stopped — even though both processes are alive on the host.gslistdoesn't see), and Jasper offers to start the database.GEMSTONE environment variable is not definederror surfaces.gslistdoesn't look.Summary
Jasper runs its own
gslistin its own environment — it setsGEMSTONE_GLOBAL_DIRto its configured root (sysadminStorage.getRootPath()) and discovers servers by their.LCKfiles in that root'slocks/directory. A stone or netldi started outside Jasper — by hand, or from a shell carrying different GemStone environment (e.g. an inheritedGEMSTONE_NRS_ALLor a differentGEMSTONE_GLOBAL_DIR) — registers in a differentlocks/directory, so Jasper'sgslistcan't see it even though the OS process is alive. Servers started outside Jasper can't be prevented, so Jasper should recognize this situation and offer to reconcile it instead of showing a misleading state.This issue also folds in two related state-accuracy fixes (see Related state-accuracy fixes below) that came out of the same investigation: status should reflect reachability rather than mere process presence, and Jasper's discovery environment should be deterministic rather than perturbed by the launching shell's leftover GemStone variables.
Motivation / what goes wrong today
gslistcan't see), and the failure reads as "the stone isn't running" when it plainly is.GEMSTONE environment variable is not defined) is relayed verbatim, sending the user off to debug their shell profile for a problem that isn't in their shell.Acceptance criteria
For each managed database, Jasper detects when a
stoned/netldidprocess matching that database's stone/ldi name and version is running but is not visible in Jasper's owngslist(itslocks/dir), and classifies it as "started outside Jasper's environment."On connect (and reflected on tree refresh), when such a server is detected, Jasper offers to reconcile with a dialog worded as a mismatch, not a missing install. Example wording:
Restart & Connect stops the external stone/netldi (clean
stopstone/stopnetldi, with the existing force-kill fallback), then does Jasper's normal start + connect, so everything lands in Jasper's ownlocks/dir.Before Restart & Connect stops anything, confirm the running same-named server is actually the managed database. If it can't be confirmed, warn that it may be a different stone that merely shares the name, and do not auto-stop it. (Identity by name alone is ambiguous — see Implementation notes.)
The reconcile dialog warns that restarting the stone drops any uncommitted sessions on it.
If Jasper cannot stop or kill the external server, it does not dead-end: it shows enough to resolve by hand — stone name, netldi name, process IDs, and the directory the server is registered in — plus how to inspect it (e.g.
gslistpointed at that directory).Jasper never surfaces the child script's bare
GEMSTONE environment variable is not defined; that path is replaced by the situation-specific message above.The failure message is not phrased as "GemStone <version> install path isn't configured" — a user who already installed that version would be baffled by that.
Related state-accuracy fixes (folded in)
Both came out of the same investigation and share the root cause above — Jasper's view of server state must be accurate and self-consistent regardless of how or where servers were started. Filed here rather than separately.
Status should reflect reachability, not just process presence
Today the tree shows Running whenever a matching process appears in Jasper's own
gslist, even if the stone has no reachable NetLDI and a login cannot actually connect — so the tree can directly contradict a failing login.isStoneRunning-style checks a reachability notion instead of trustinggslistpresence alone.Discovery environment should be deterministic
The start path (
getEnvironment) setsGEMSTONE_NRS_ALL, butversionEnvironment— used forgslistdiscovery and the version terminal — sets noGEMSTONE_NRS_ALLat all. So a stray inheritedGEMSTONE_NRS_ALL/GEMSTONE_GLOBAL_DIRfrom the shell that launched the editor can sway what Jasper discovers and where a version-terminal command lands.Implementation notes
(Possibilities, not prescriptions.)
processManageralready does ps-based process inspection (classifyPidOwnership,forceKillStone,inspectStaleLock) and has a clean-stop-with-force-fallback path; version matching has aversionsMatchguard to reuse so two installed versions sharing a stone name don't collide.gslist." One approach is a broad process scan (forstoned <stone>/netldid <ldi>) compared against thegslistJasper already runs against its configured root.GEMSTONE_GLOBAL_DIRis fixed at start time — a live stone can't be re-homed into Jasper's directory — so reconcile must be stop + start, not re-registration.stonedhas open (e.g. from its command line or open files) against the managed database's path is a candidate signal, but not foolproof: a stone can be started against a different extent. So treat "can't confirm" as "not confirmed" (warn-only, don't stop it), and finding a more robust identity check is an open problem worth solving while implementing this.Background (why the guard is part of this, not a separate issue)
The
GEMSTONE environment variable is not definederrors observed in practice were the GemStone shell script's own stderr, relayed by Jasper, and occurred only while a mismatched/external server was in the picture. Jasper's own start path setsGEMSTONEcorrectly — a clean Jasper start+connect works even withGEMSTONEunset in the shell. So the hardening bundled here is (a) the situation-specific messaging above, and (b) resolving/verifying the environment up front and failing with an actionable message rather than relaying a raw shell-script error.