Skip to content

GS2 Agent Stack

gs2-agent.exe, mb-repeater.exe, and dummy-svc.exe are consolidated here from the 2026-05-19 snapshot. NvGridSvc remains deprecated/legacy context only.

Deep-only retained findings

  • gitlab-master.nvidia.com/gfn-core/go/protocols/pb/grpc_protos is embedded in gs2-agent.exe symbols.
  • gitlab-master.nvidia.com/gfn-core/go/protocols/pb/gsapi_v2 is embedded in mb-repeater.exe symbols.
  • gitlab-master.nvidia.com/gfn/gs2/gameseat2/src/shared/message-bus is embedded in dummy-svc.exe symbols.

2026-05-19 application notes

gs2-agent.exe

What this program actually does

gs2-agent.exe is the local control plane on a GeForce NOW gameseat. Remote orchestration (session manager / grid) talks to it over gRPC on TCP port 8102. The agent performs privileged seat operations that a normal user process cannot: mount/volume lifecycle, registry reads, GPU clock/power tweaks, timezone, writing session config into ProgramData, starting perfmon / logman traces, and streaming large files in chunks.

It is not the game streamer. It is the seat-side RPC daemon that prepares and instruments the VM while volumes appear/disappear and a session starts.


Architecture (recovered from Go symbol strings)

main.go
  └─ config.LoadConfig (gs2-agent-config.json, mTLS paths)
  └─ server.NewServer
        ├─ gRPC RegisterGs2AgentServiceServer
        ├─ volumeMonitor.Run (1s poll) → logs Volume appeared/disappeared
        ├─ WithMtlsListen / WithPersistentMtlsListen
        └─ agentService handlers (server.go, server_windows.go)
              ├─ disk/*     — PnP eject, QueryVolumeStatistics, FlushDisk
              ├─ filechunk/* — GrpcStreamReader/Writer for ReadFiles
              ├─ uec/*      — Unified Error Code → proto errors
              └─ platform*  — Win32 registry, perfmon, logman, timezone

Source tree (embedded in binary): gitlab-master.nvidia.com/gfn/gs2/gameseat2/src/gs2-agent/

Protocol definitions: gitlab-master.nvidia.com/gfn-core/go/protocols/pb/grpc_protos (Gs2AgentService.proto, Gs2AgentService_grpc.pb.go)

Build ID from runtime log: bbd5ba76


gRPC service: Gs2.Gs2AgentService

Full method paths recovered from strings (also logged as Received <Method> in logs/gs2-agent/gs2-agent.log):

RPCHandler packageBehavior (evidence-based)
GetEnvserver.(*agentService).GetEnvReturns environment variables to remote caller (Gs2.GetEnvResponse.EnvVarsEntry). Seen in log at session prep.
GetGpuFeaturesserver.(*agentService).GetGpuFeaturesQueries GPU capabilities for seat. Seen in log early in boot.
QueryVolumeStatisticsdisk.QueryVolumeStatisticsEnumerates volumes/partitions, returns capacity/free bytes. Background monitor also calls Update every 1s. Heavily used in log during VHD mount storm (X→A: drives).
WriteFileserver.writeFileInternalWrites remote-supplied bytes to absolute paths. Log: C:\ProgramData\NVIDIA Corporation\GfnRuntimeSdk\.clientdata, ...\Lightning\lightning.json.
ReadFile / ReadFilesserver.(*agentService).ReadFile(s)Reads seat files; ReadFiles uses streaming via filechunk.GrpcStreamReader. Strings: Done streaming contents from reader.
FilesExistserver.(*agentService).FilesExistPath existence check before install/patch steps.
DeleteFileserver.thoroughDeleteDeletes paths (thorough delete with defer cleanup).
SetTimezoneOffsetserver.platformSetTimezoneSets dynamic timezone (setDynamicTimeZoneInformation). Log: offsetMinutes: 180.
RunPerfmonserver.platformRunPerfmonStarts Windows perfmon collection. Log: op: START, Started perfmon pid: 4372.
StopLogmanTraceserver.platformStopLogmanTraceStops logman trace (Executing logman stop trace command).
QueryRegKeysserver.platformQueryRegKeysRegistry read API (queryRegKey, regKeyResultProtoError).
SetGpuClockserver.(*agentService).SetGpuClockGPU clock control; CLI strings: --reset-memory-clocks.
SetGpuPowerLimitserver.(*agentService).SetGpuPowerLimitPower limit; string: --power-limit.
FlushDiskserver.PlatformFlushDiskFlushes disk buffers (Flushed disk buffers).
QueryDiskserver.(*agentService).QueryDiskDisk discovery; strings: Disk not found yet, waiting..., search for disk: %w.
EjectDiskdisk.EjectDiskplatformEjectDiskPnP-safe volume removal: cmRequestDeviceEject, prepareVolumeForRemoval, PNP_VetoTypeUnknown, FSCTL_LOCK_VOLUME.
QueryVolumeStatistics (path)/Gs2.Gs2AgentService/QueryVolumeStatisticsSame as above; primary hot path during game volume attach.

Transport: gRPC over TCP (ConnectionMode: tcp, port 8102 in gs2-agent-config.json). mTLS material paths: gs2-agent-mtls.json, PersistMtlsFilePath.

Embedded codecs/archives: binary embeds 7zip, gzip, lz4, xz, rar, tar, zstd stacks — used when unpacking/processing streamed file payloads (sevenzip:, readFilesInfo, etc.), not for general seat archiving.


Volume monitor (background goroutine)

From server/volume_monitor.go + logs:

  1. Poll interval 1000 ms (VolumeMonitorPollIntervalMs in config).
  2. On change, logs Volume appeared / Volume disappeared with drive letter, deviceId, capacity/free.
  3. Observed sequence in snapshot: transient ~2 GB volumes B:, Y:, Z: → many letters L:X: → consolidation to A: (~2 TB game volume) and C: shrink (~1 GB system), plus I: user content volume.

This monitor lets the control plane wait for game VHD attach before QueryVolumeStatistics returns stable stats.


Windows API surface (disk subsystem)

Recovered Win32/PnP calls from strings in disk_windows.go:

  • GetVolumePathNamesForVolumeNameW, GetVolumeNameForVolumeMountPointW
  • GetDiskFreeSpaceExW
  • CM_Locate_DevNode, CM_Get_DevNode_Status, cmRequestDeviceEject
  • SetupDiCreateDeviceInfoListExW, SetupDiGetDeviceInstallParamsW, SetupDiEnumDeviceInfo
  • FSCTL_LOCK_VOLUME
  • SubscribeServiceChangeNotifications

Eject path uses retry policy symbols: Attempts, MaxDelay, OnRetry, DelayType — indicates deliberate handling of PnP veto races.

| r2 confirmed | LoadLibraryW (kernel32.dll) | LoadLibraryExW (kernel32.dll) | GetProcAddress (kernel32.dll) |


Session timeline (from logs/gs2-agent/gs2-agent.log)

Time (UTC)EventInterpretation
18:42:50Start server :8102, volume monitorAgent up after seat software install
18:42:50–18:43:21Many Volume appeared/disappearedStaging VHDs mounting/unmounting during prep
18:43:22GetEnv, QueryVolumeStatistics, GetGpuFeaturesRemote poller probing seat readiness
18:48:23SetTimezoneOffset(180), WriteFile (GfnRuntimeSdk, Lightning)Session start — inject client metadata + lightning config
18:48:27+New volumes I:, A:, C: resizeUser/game disks attached for active session
18:48:42+RunPerfmon START + continuous QueryVolumeStatisticsPerformance instrumentation for session

Configuration files

FilePurpose
services/gs2/gs2-agent-config.jsonPort 8102, log paths, mTLS persist path, volume poll interval
services/gs2/gs2-agent-mtls.jsonReferenced; not present in Linux snapshot (expected on live seat)

Error / telemetry model

Package gs2-agent/uec: Error, ErrorFromGeneric, ToProtoError, flags IsUserImpacting, IsSevere, IsWarning.

Panic log: C:\Asgard\Logs\gs2-agent\gs2-agent-panic.txt (configured in JSON).


What is NOT verified without dynamic debugging

  • Exact protobuf request/response fields per RPC (only type names recovered).
  • mTLS cipher suites and client certificate pinning rules.
  • Full GPU feature bitmask semantics for GetGpuFeatures.
  • Whether ReadFiles is used for game manifest delivery in this seat build (handler exists; not seen in sampled log).

Evidence

  • strings on services/gs2/gs2-agent.exe (Go pclntab / gRPC symbols)
  • logs/gs2-agent/gs2-agent.log
  • services/gs2/gs2-agent-config.json
  • docs/reverse-engineering/_analysis/gs2-agent.strings.txt

mb-repeater.exe

What this program actually does

mb-repeater.exe is a Go message-bus bridge on the gameseat. It listens locally on TCP 8100, maintains a filtered view of seat Message Bus traffic, and pairs with a remote repeater so cloud-side peers (TelemetryAggregator, PIPS, CTMT, NGS) can join the seat's bus namespace.

Primary filtered forwards (from services/gs2/mb-repeater.json):

  1. All message_bus_broadcast_system broadcasts
  2. GCIS / GciPluginSysmon / ProcessEventMessage broadcasts (Sysmon process events)

Build ID from log: bbd5ba76 (matches gs2-agent).


Architecture (Go symbol strings)

mb-repeater/main.go
  └─ bridge/server.go           — TCP :8100 server mode
  └─ bridge/repeater.go         — local/remote peer maps, join commands
  └─ bridge/client.go           — remote repeater connection
  └─ bridge/health.go           — health check (disabled in log)
  └─ bridge/filter/filter.go    — filteredSources from JSON
  └─ config/config.go           — mb-repeater.json
  └─ bridge/pb/MBRepeater*.pb.go — repeater control protobuf

Embedded protocol knowledge: imports gitlab-master.nvidia.com/gfn-core/go/protocols/pb/gsapi_v2 and StreamCaptureControllerMessage types — used for bus message parsing/filtering, not as an external API server.

Source tree: gitlab-master.nvidia.com/gfn/gs2/gameseat2/src/mb-repeater/ (inferred from paths in strings)


Runtime behavior (from logs/mb-repeater/mb-repeater.log)

Time (UTC)Event
18:42:49Banner, version bbd5ba76, panic handler → C:\Asgard\logs\mb-repeater\mb-repeater-panic.txt
18:42:49Starting in Server mode, port 8100, health check disabled
18:42:49Local peers: GSConfigurator, GSConfiguratorUecReporter (pid 6496)
18:42:50Remote join commands: TelemetryAggregator:SeatConnector, SessionInfoApi, PIPS modules, CTMT:GameseatTelemetryConnector, NGS:GameseatTelemetryConnector, mb-repeater-connected

PIPS remote peers added:

  • PIPS:PIPS
  • PIPS:PIPS-InputFeatures
  • PIPS:PIPSTasConnector
  • PIPS:PIPSAnybrainTasConnector

This enables PipsController.exe (local) to reach cloud PIPS GSBE through the repeater tunnel.


Configuration

KeyValue
pairAddress.port8100
pairAddress.servertrue
pairAddress.schemetcp
connection.persistMtlsFilePathC:\Asgard\services\gs2\mb-repeater-mtls.json
filteredSourcesGCIS ProcessEventMessage + broadcast_system
LogC:\Asgard\logs\mb-repeater\mb-repeater.log

mTLS material referenced but not present in Linux snapshot.


Relationships

ComponentRole
gs2-agent.exeSibling GS2 service; same build ID
GciPlugin.dllSource of forwarded ProcessEventMessage
PipsController.exeConsumer of bridged PIPS peers
NvContainerGSP / GSConfiguratorFirst local bus peers seen

Not verified

  • Remote repeater hostname/port (empty endpoint in JSON — likely from mTLS persist file).
  • Full list of message types forwarded beyond JSON filters.
  • Whether repeater runs as Windows Service (log shows console startup only).

Evidence

  • strings on services/gs2/mb-repeater.exe (docs/reverse-engineering/_analysis/mb-repeater.strings.txt)
  • logs/mb-repeater/mb-repeater.log
  • services/gs2/mb-repeater.json

dummy-svc.exe

What this program actually does

dummy-svc.exe is a minimal Go Windows service wrapper whose sole runtime purpose in this build is to host the local NVIDIA Message Bus stack on the gameseat. It registers as a Windows service and runs the shared message-bus library — the same transport layer used by other GS2 components.

It is not a placeholder no-op in practice: strings show full bus client/server implementation (NewBus, SendMessage, SendProto, peer join handling).

Source: dummy-svc/main.go + gitlab-master.nvidia.com/gfn/gs2/gameseat2/src/shared/message-bus/


Architecture (Go symbol strings)

dummy-svc/main.go
  └─ message-bus.NewBus
        ├─ config.GetMBConf
        ├─ transport.Dial
        ├─ SendMessage / SendProto / SendMessageWithDomain
        ├─ StartReadingMessages
        └─ sendJoin (peer registration)
  └─ pb.BusMessage (protobuf)
  └─ IsWindowsService / RegisterService

Build ID: redacted in strings extract.


Message Bus surface (strings)

SymbolRole
message-bus.(*Bus).SendMessagePost bus messages
message-bus.(*Bus).SendProtoProtobuf payloads
message-bus.(*Bus).sendJoinPeer join handshake
message-bus/pb.BusMessage_Status_CodeStatus codes
message-bus/pb.BusMessage_EncryptedBusMessage_EncryptionTypeOptional encryption

Observer hooks: OnBusConnect, OnBusDisconnect, OnMessage, OnPeerJoin, OnPeerLeave.


Deployment

ItemEvidence
Pathservices/gs2/dummy-svc.exe
ConfigUses default MB config path via getDefaultConfigPath
LogsNo dedicated log file matched in logs/ snapshot

Other seat services (mb-repeater, GSP NvContainer) connect to the bus instance this service exposes. services/AutoOnboarder/mb.conf shows seat-local bus port 65000 for AutoOnboarder stack — separate from GS2 repeater port 8100.


PE metadata

FieldValue
Size14,725,120 bytes
SubsystemWindows CUI
Importskernel32.dll only (Go runtime)

Relationships

ComponentInteraction
mb-repeater.exeBridges this bus to remote
NvContainerGSP/GCIS/NDCNvContainer plugins use MessageBus DLL variants
gs2-agent.exeSame GS2 bundle; different role (gRPC agent)

Not verified

  • Windows Service name as registered in SCM (not in logs).
  • Exact TCP/UDP port bound by dummy-svc (default from MB conf not in workspace).
  • Whether dummy-svc is started by Pandora startup vs manual install.

Evidence

  • strings on services/gs2/dummy-svc.exe (docs/reverse-engineering/_analysis/dummy-svc.strings.txt)

admindesk.top — Reversed & documented from Asgard rig backups and GCIS plugin binaries.