Skip to content

Svc::FileManager Component

Overview

Svc::FileManager provides a set of ground commands for common file and filesystem operations. It is a wrapper around the OSAL file, filesystem and directory APIs. The component accepts commands, calls the corresponding OSAL operation, and reports the result through events, telemetry, and command responses.

Security Considerations

Every FileManager command takes filesystem paths from ground commands and operates on them with the process's full privileges. The component confines those paths with a sandbox directory set by configure(sandboxDir):

  • The sandbox is fail-closed: until configure is called, every command is rejected with a PathOutsideSandbox warning event and a VALIDATION_ERROR command response.
  • Each path argument is canonicalized (Os::FilePathUtils::resolveFromCwd: relative paths resolve against the current working directory; . and .. segments are collapsed textually, without following symlinks) and must resolve inside the configured directory (Os::FilePathUtils::checkContainment). The canonical path is what reaches the OS call; rejected commands perform no filesystem operation. On rejection the component emits the PathOutsideSandbox warning event (carrying the rejected path and the configured directory), increments the Errors telemetry channel, and returns VALIDATION_ERROR. For two-path commands (MoveFile, AppendFile) each argument is checked independently.
  • Configuring "/" permits any path, matching the component's historical behavior. The FileHandling and FileHandlingCfdp subtopologies configure "/" by default for backwards compatibility; deployments wishing restricted file management must call configure again from topology setup code with a restricted directory.

Functionality

Svc::FileManager supports common filesystem operations. They are currently:

  • CreateDirectory
  • RemoveDirectory
  • ListDirectory
  • MoveFile
  • RemoveFile
  • AppendFile
  • FileSize
  • CalculateCrc
  • GenerateDp

For each command, the component returns success or failure and emits status information for operators. Every path argument is validated against the configured sandbox directory before the operation runs (see Security Considerations and Configuration); events echo the path as commanded, while the filesystem operation acts on the canonical resolved path.

Configuration

configure(sandboxDir) must be called once during topology setup, before commanding. It sets the directory that confines every command path argument; the component is fail-closed and rejects all commands until it is called. sandboxDir may be absolute or relative to the process working directory, and "/" permits any path.

Deployments using the FileHandling or FileHandlingCfdp subtopology get this call in the autocoded configComponents phase (open, "/", for backwards compatibility — re-configure from topology setup code to restrict). Deployments instantiating Svc.FileManager directly must add the call themselves:

// e.g. in topology setup code
fileManager.configure("/data/");   // restrict to /data

Compile-time configuration lives in config/FileManagerConfig.hpp (FILES_PER_RATE_TICK, CHUNKS_PER_RATE_TICK, GENERATE_DP_MAX_CHUNK_SIZE, DEFAULT_DP_PRIORITY).

Ports

Name Type Kind Purpose
schedIn Svc.Sched sync input Rate group input used to pace long-running operations
pingIn Svc.Ping async input Ping input from health checker
pingOut Svc.Ping output Ping response to health checker
run n/a internal (drop) Internal port for delegating schedIn calls in a controlled fashion

The component also has the standard command, event, telemetry, time, and data product ports.

ListDirectory and Pacing

ListDirectory runs asynchronously: the command handler opens the directory and defers the command response. The schedIn handler enqueues at most one internal run call at a time (guarded by an atomic flag); the internal handler then processes up to FileManagerConfig::FILES_PER_RATE_TICK directory entries per rate tick to prevent event flooding, sending the command response when the listing completes. Paced (PACED mode) data product generation is metered the same way, processing FileManagerConfig::CHUNKS_PER_RATE_TICK chunks per tick.

GenerateDp

GenerateDp packages a file into data products. The command takes the file name, a chunk size, a begin and end offset, a container priority and an emission mode, and the requested range of the file is emitted one chunk at a time. An end offset of zero means the end of the file, so a begin and end offset of zero packages the whole file. Ranges let an operator retransmit part of a file, or spread a downlink over several commands when a project cannot fit the whole file into data products at once. Each chunk is written as a pair of records: a FileChunkHeaderRecord carrying the source file name, the offset of the chunk within the file and the number of data bytes, followed by a FileChunkDataRecord holding the chunk bytes. Ground tools reassemble the original file from these records, so the command works regardless of the size of the buffers allocated to data products.

The emission mode selects how the chunks are written. In PACED mode they are metered out by the rate group in the same way as directory listing, one chunk per tick by default, and the command response is deferred until the last chunk has been sent. In IMMEDIATE mode the whole range is written in the command handler, which suits projects that would rather finish quickly than spread the work over time.

A priority of zero uses Svc::FileManagerCfg::DEFAULT_DP_PRIORITY, which projects can adjust, while a non-zero priority applies to the containers of that request only. The requested chunk size is clamped to FileManagerConfig::GENERATE_DP_MAX_CHUNK_SIZE, which bounds the read buffer held by the component.

Failures during data product generation emit a warning event but still return a successful command response. A bad file name or a transient resource problem therefore does not stop a command sequence that happens to contain the command, while operators still see exactly what went wrong in the event log.

Because each chunk header carries the absolute offset within the source file, chunks produced by separate commands reassemble correctly on the ground with no extra bookkeeping. The data product ports are left for the deployment to connect; if they are not connected the command fails with an event rather than attempting to allocate a container.