CasaOS Storage Mounting and Unmounting: How SMB, rclone, and Network Drives Work

CasaOS abstracts storage operations through a service layer that communicates with the rclone HTTP API over a Unix socket and manages Samba configurations directly, enabling unified handling of SMB shares, WebDAV, and cloud remotes through a single interface.

The CasaOS storage architecture unifies diverse network storage protocols under a consistent Go-based service layer. By delegating mount operations to the rclone HTTP API via /var/run/rclone/rclone.sock and maintaining custom Samba configurations in /etc/samba/smb.casa.conf, the system provides predictable mounting and unmounting behavior across SMB, cloud drives, and other network-attached storage.

Storage Service Interface

The high-level storage API is defined in service/storage.go through the StorageService interface. This contract declares the essential operations used throughout the CasaOS codebase:

type StorageService interface {
    MountStorage(mountPoint, fs string) error
    UnmountStorage(mountPoint string) error
    GetStorages() (httper.MountList, error)
    // … other helpers for rclone config
}

The concrete implementation (storageStruct) delegates actual mounting logic to the httper helper package located in pkg/utils/httper/drive.go. This abstraction ensures that higher-level components interact with a unified interface regardless of whether the underlying storage is SMB, WebDAV, or a cloud provider.

rclone HTTP Communication Layer

CasaOS communicates with rclone through a dedicated HTTP client implemented in pkg/utils/httper/drive.go. The client uses the resty library to send requests to the rclone HTTP API over a Unix socket at /var/run/rclone/rclone.sock.

Mount operations use a POST request to /mount/mount with the target filesystem and mount point:

svc := service.NewStorageService()
err := svc.MountStorage("/mnt/smb-share", "smbremote:")
if err != nil {
    // handle error
}

Unmount operations send a POST to /mount/unmount specifying the mount point to release:

svc := service.NewStorageService()
_ = svc.UnmountStorage("/mnt/smb-share")

The same client handles configuration management through methods like CreateConfig, GetConfigByName, GetAllConfigName, and DeleteConfigByName. Because all requests route through the same Unix socket, any storage backend supported by rclone—whether SMB, Nextcloud, WebDAV, or S3—can be managed through this single code path.

SMB Share Management

For serving directories over SMB, CasaOS maintains a separate service in service/shares.go. This component manages a SQLite table of user-defined shares and handles the lifecycle of Samba configuration files.

When creating a share, the service generates a per-share stanza (e.g., [MyShare] … path = /mnt/myshare) and writes it to /etc/samba/smb.casa.conf. The UpdateConfigFile() function then aggregates these stanzas into /etc/samba/smb.conf while preserving CasaOS-specific defaults, and triggers RestartSMBD to reload the Samba daemon.

share := model.SharesDBModel{
    Name:      "MyShare",
    Path:      "/mnt/smb-share",
    Anonymous: true,
}
shares := service.NewSharesService(db)
shares.CreateShare(share) // Writes config and restarts Samba

This separation allows CasaOS to distinguish between mounting remote storage (handled by rclone) and serving local directories via SMB (handled by the system Samba daemon).

Automatic Mount Reconciliation

To ensure persistence across reboots, CasaOS implements CheckAndMountAll() in the storage service. This function iterates through every rclone remote returned by GetAllConfigName() and checks whether configured mount points are currently active by comparing against GetMountList().

For each remote that defines a mount_point but is not currently mounted, the system automatically invokes MountStorage(mountPoint, remote+":"). This reconciliation loop ensures that network drives are reattached without manual intervention after system restarts or configuration changes.

Unmount Cleanup Behavior

The UnmountStorage() method implements a two-phase cleanup process. First, it sends the unmount command to rclone via the HTTP API. If the unmount succeeds and the mount directory is empty, the function calls file.RMDir from pkg/utils/file/file.go to remove the directory. This prevents orphaned empty mount points from accumulating in the filesystem.

To create a new rclone configuration for an SMB remote with automatic mounting:

cfg := map[string]string{
    "type":          "smb",
    "host":          "192.168.1.100",
    "user":          "guest",
    "pass":          "guest",
    "mount_point":   "/mnt/smb-share",
}
svc := service.NewStorageService()
_ = svc.CreateConfig(cfg, "smbremote", "smb")
_ = svc.CheckAndMountByName("smbremote")

Summary

  • Unified Interface: service/storage.go provides a consistent StorageService interface for all mount operations, delegating to rclone via pkg/utils/httper/drive.go.
  • rclone Integration: All mount and unmount operations communicate with the rclone HTTP API over the Unix socket /var/run/rclone/rclone.sock, supporting any rclone-compatible backend.
  • Native SMB Handling: service/shares.go manages Samba configurations in /etc/samba/smb.casa.conf and restarts the daemon via RestartSMBD to serve local directories.
  • Automatic Recovery: CheckAndMountAll() ensures configured remotes are automatically mounted after reboots by reconciling rclone configurations against active mounts.
  • Cleanup Logic: UnmountStorage() removes empty mount directories after successful unmounts to prevent filesystem clutter.

Frequently Asked Questions

How does CasaOS communicate with rclone?

CasaOS establishes a resty HTTP client in pkg/utils/httper/drive.go that sends requests to the rclone HTTP API over a Unix domain socket at /var/run/rclone/rclone.sock. This allows the system to mount, unmount, and configure remotes using standard HTTP POST requests to endpoints like /mount/mount and /mount/unmount.

Where does CasaOS store Samba share configurations?

User-defined SMB shares are stored in an SQLite database, but the actual Samba configuration is written to /etc/samba/smb.casa.conf. The UpdateConfigFile() function in service/shares.go aggregates these into /etc/samba/smb.conf and triggers RestartSMBD to apply changes without restarting the entire system.

What happens to mount points after unmounting?

When UnmountStorage() is called, CasaOS first requests the unmount from rclone. If successful and the directory is empty, the system removes the mount point using file.RMDir from pkg/utils/file/file.go. This ensures that unused directories do not persist in /mnt or other mount locations.

How does CasaOS handle mounts after a system reboot?

The CheckAndMountAll() function iterates through all rclone configurations returned by GetAllConfigName(). For each remote that specifies a mount_point and is not currently listed in GetMountList(), it automatically executes the mount operation. This reconciliation ensures that network drives defined in the CasaOS database are automatically attached when the system starts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →