Skip to content

Latest commit

 

History

History
874 lines (696 loc) · 16.1 KB

File metadata and controls

874 lines (696 loc) · 16.1 KB

UROAM API Reference

Complete reference for the UROAM daemon (uroamd) JSON-RPC 2.0 API over Unix socket.

Table of Contents


Overview

UROAM daemon (uroamd) exposes a JSON-RPC 2.0 API over a Unix domain socket for inter-process communication with the CLI tool (ramctl) and third-party applications.

Key Features

  • Protocol: JSON-RPC 2.0 (spec: jsonrpc.org)
  • Transport: Unix domain socket
  • Socket Location: /run/uroam/uroamd.sock
  • Authentication: Unix socket permissions + PolicyKit (for privileged operations)

Connection Details

Socket Path

/run/uroam/uroamd.sock

Socket Permissions

# Check socket permissions
ls -l /run/uroam/uroamd.sock

# Typical output:
# srw-rw---- 1 uroam uroam 0 May  2 12:00 /run/uroam/uroamd.sock

Connecting to the Socket

Using socat (Recommended for testing)

# Send a command
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | socat - UNIX-CONNECT:/run/uroam/uroamd.sock

# Monitor with continuous output
socat UNIX-CONNECT:/run/uroam/uroamd.sock -

Using nc (netcat)

# Send a command
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | nc -U /run/uroam/uroamd.sock

Using Python

import socket
import json

def uroam_request(method, params={}):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sock.connect('/run/uroam/uroamd.sock')
    
    request = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1
    }
    
    sock.sendall(json.dumps(request).encode())
    response = sock.recv(4096)
    sock.close()
    
    return json.loads(response)

# Example: get status
status = uroam_request("status")
print(json.dumps(status, indent=2))

Using Rust

use std::os::unix::net::UnixStream;
use std::io::{Read, Write};
use serde_json::json;

fn uroam_request(method: &str, params: serde_json::Value) -> Result<String, Box<dyn std::error::Error>> {
    let mut stream = UnixStream::connect("/run/uroam/uroamd.sock")?;
    
    let request = json!({
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1
    });
    
    stream.write_all(request.to_string().as_bytes())?;
    
    let mut response = String::new();
    stream.read_to_string(&mut response)?;
    
    Ok(response)
}

Protocol Format

Request Format

{
  "jsonrpc": "2.0",
  "method": "<command_name>",
  "params": {
    // Command-specific parameters
  },
  "id": <request_id>
}

Response Format (Success)

{
  "jsonrpc": "2.0",
  "result": {
    // Command-specific result data
  },
  "id": <request_id>
}

Response Format (Error)

{
  "jsonrpc": "2.0",
  "error": {
    "code": <error_code>,
    "message": "<error_message>",
    "data": {
      // Optional additional error details
    }
  },
  "id": <request_id>
}

Commands

status

Get current system memory status, workload classification, and optimization state.

Request

{
  "jsonrpc": "2.0",
  "method": "status",
  "params": {
    "verbose": false
  },
  "id": 1
}
Parameter Type Required Description
verbose boolean No Include detailed per-process information

Response

{
  "jsonrpc": "2.0",
  "result": {
    "memory": {
      "total": 16777216,
      "used": 8388608,
      "available": 8388608,
      "used_percent": 50.0,
      "swap_total": 4194304,
      "swap_used": 1048576,
      "swap_used_percent": 25.0
    },
    "zram": {
      "enabled": true,
      "algorithm": "lz4",
      "size_mb": 8192,
      "used_mb": 2048,
      "compression_ratio": 2.5
    },
    "zswap": {
      "enabled": true,
      "compressor": "lz4",
      "pool_percent": 20
    },
    "workload": {
      "type": "gaming",
      "priority": 0,
      "confidence": 0.95,
      "active_processes": 3
    },
    "optimizations": {
      "swappiness": 1,
      "thp_mode": "always",
      "ksm_enabled": false,
      "cache_pressure": 50
    },
    "profile": "gaming",
    "idle": false
  },
  "id": 1
}

optimize

Trigger immediate memory optimization pass.

Request

{
  "jsonrpc": "2.0",
  "method": "optimize",
  "params": {
    "level": "normal"
  },
  "id": 2
}
Parameter Type Required Description
level string No Optimization level: "light", "normal", "aggressive" (default: "normal")

Response

{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "actions_taken": [
      "Set swappiness to 1",
      "Enabled THP",
      "Dropped page caches"
    ],
    "memory_freed_mb": 512,
    "duration_ms": 150
  },
  "id": 2
}

profile_set

Set the active optimization profile.

Request

{
  "jsonrpc": "2.0",
  "method": "profile_set",
  "params": {
    "profile": "gaming"
  },
  "id": 3
}
Parameter Type Required Description
profile string Yes Profile name: "ai", "gaming", "balanced", "powersaver"

Response

{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "previous_profile": "balanced",
    "active_profile": "gaming",
    "settings_applied": {
      "swappiness": 1,
      "zram_algorithm": "lz4",
      "zram_size_percent": 30,
      "ksm_enabled": false,
      "thp_mode": "always"
    }
  },
  "id": 3
}

profile_get

Get the currently active profile and its settings.

Request

{
  "jsonrpc": "2.0",
  "method": "profile_get",
  "params": {},
  "id": 4
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "active_profile": "gaming",
    "settings": {
      "swappiness": 1,
      "zram_algorithm": "lz4",
      "zram_size_percent": 30,
      "ksm_enabled": false,
      "thp_mode": "always",
      "cache_pressure": 50
    },
    "available_profiles": ["ai", "gaming", "balanced", "powersaver"]
  },
  "id": 4
}

clean

Perform aggressive memory cleanup (drops caches, compacts memory, triggers KSM).

Request

{
  "jsonrpc": "2.0",
  "method": "clean",
  "params": {
    "confirm": true,
    "level": "normal"
  },
  "id": 5
}
Parameter Type Required Description
confirm boolean Yes Must be true to confirm the operation
level string No Cleanup level: "light", "normal", "aggressive" (default: "normal")

Response

{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "actions_taken": [
      "Dropped page caches (level 3)",
      "Compacted memory",
      "Triggered KSM scan"
    ],
    "memory_freed_mb": 1024,
    "caches_dropped_mb": 512
  },
  "id": 5
}

monitor

Start real-time monitoring mode (streaming responses).

Request

{
  "jsonrpc": "2.0",
  "method": "monitor",
  "params": {
    "interval_ms": 1000,
    "duration_secs": 0
  },
  "id": 6
}
Parameter Type Required Description
interval_ms integer No Update interval in milliseconds (default: 1000)
duration_secs integer No Monitoring duration (0 = indefinite)

Response (Streaming)

The monitor command sends multiple responses at the specified interval:

{
  "jsonrpc": "2.0",
  "result": {
    "timestamp": "2026-05-02T12:00:00Z",
    "memory": {
      "used_percent": 50.0,
      "swap_used_percent": 25.0
    },
    "psi": {
      "some_10": 2.5,
      "some_60": 1.8,
      "some_300": 1.2
    },
    "workload": {
      "type": "gaming",
      "priority": 0
    }
  },
  "id": 6
}

Note: To stop monitoring, send a SIGINT (Ctrl+C) or close the socket connection.


zram_status

Get ZRAM device status and statistics.

Request

{
  "jsonrpc": "2.0",
  "method": "zram_status",
  "params": {},
  "id": 7
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "enabled": true,
    "devices": [
      {
        "device": "/dev/zram0",
        "algorithm": "lz4",
        "disksize_mb": 8192,
        "compr_data_size_mb": 2048,
        "mem_used_total_mb": 512,
        "compression_ratio": 4.0,
        "num_reads": 1000,
        "num_writes": 5000
      }
    ],
    "total_stats": {
      "original_mb": 8192,
      "compressed_mb": 2048,
      "savings_mb": 6144,
      "savings_percent": 75.0
    }
  },
  "id": 7
}

config_reload

Reload configuration from /etc/uroam/uroam.toml.

Request

{
  "jsonrpc": "2.0",
  "method": "config_reload",
  "params": {},
  "id": 8
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "config_path": "/etc/uroam/uroam.toml",
    "changes_applied": [
      "Updated polling interval to 500ms",
      "Applied new ZRAM settings"
    ],
    "warnings": []
  },
  "id": 8
}

If the configuration file has errors:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid configuration",
    "data": {
      "line": 15,
      "field": "zram.size_percent",
      "error": "Value must be between 0 and 100"
    }
  },
  "id": 8
}

daemon_stop

Gracefully stop the UROAM daemon.

Request

{
  "jsonrpc": "2.0",
  "method": "daemon_stop",
  "params": {
    "force": false
  },
  "id": 9
}
Parameter Type Required Description
force boolean No Force stop without cleanup (default: false)

Response

{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "message": "Daemon stopping gracefully",
    "cleanup_actions": [
      "Restored swappiness to 60",
      "Disabled KSM",
      "Reset THP to madvise"
    ]
  },
  "id": 9
}

Error Codes

UROAM uses standard JSON-RPC 2.0 error codes with custom extensions.

Standard JSON-RPC Error Codes

Code Message Description
-32700 Parse error Invalid JSON was received
-32600 Invalid Request The JSON sent is not a valid Request object
-32601 Method not found The method does not exist / is not available
-32602 Invalid params Invalid method parameters
-32603 Internal error Internal JSON-RPC error

UROAM-Specific Error Codes

Code Message Description
1000 Daemon not initialized Daemon is still initializing
1001 Profile not found Specified profile does not exist
1002 Invalid profile settings Profile settings are invalid
1003 Optimization failed Memory optimization could not be applied
1004 ZRAM error ZRAM device error (not available, full, etc.)
1005 Permission denied Insufficient privileges for operation
1006 Config error Configuration file error
1007 Socket error Unix socket communication error
1008 Workload detection failed Could not classify current workload

Error Response Examples

Parse Error

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32700,
    "message": "Parse error",
    "data": {
      "detail": "Unexpected token ':' at position 25"
    }
  },
  "id": null
}

Method Not Found

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "Method not found",
    "data": {
      "method": "unknown_command"
    }
  },
  "id": 10
}

Invalid Parameters

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": {
      "field": "profile",
      "expected": ["ai", "gaming", "balanced", "powersaver"],
      "received": "invalid_profile"
    }
  },
  "id": 11
}

Permission Denied

{
  "jsonrpc": "2.0",
  "error": {
    "code": 1005,
    "message": "Permission denied",
    "data": {
      "operation": "profile_set",
      "required_capability": "CAP_SYS_ADMIN",
      "hint": "Run with sudo or use PolicyKit authentication"
    }
  },
  "id": 12
}

Examples

Using ramctl CLI (Recommended)

The ramctl CLI tool handles all JSON-RPC communication for you:

# Get status
ramctl status

# Get JSON output
ramctl status --json

# Set profile
ramctl profile set gaming

# Trigger optimization
ramctl optimize

# Monitor in real-time
ramctl monitor --interval 2

# Clean memory
ramctl clean

# Reload configuration
ramctl config reload

Using curl with socat

# Wrap curl-like syntax with socat
alias uroam-call='socat -T2 UNIX-CONNECT:/run/uroam/uroamd.sock -'

# Get status
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | uroam-call

# Set profile
echo '{"jsonrpc":"2.0","method":"profile_set","params":{"profile":"gaming"},"id":2}' | uroam-call

# Trigger optimization
echo '{"jsonrpc":"2.0","method":"optimize","params":{},"id":3}' | uroam-call

Python Script Example

#!/usr/bin/env python3
import socket
import json
import sys

class UroamClient:
    def __init__(self, socket_path="/run/uroam/uroamd.sock"):
        self.socket_path = socket_path
        self.request_id = 0
    
    def _call(self, method, params={}):
        self.request_id += 1
        request = {
            "jsonrpc": "2.0",
            "method": method,
            "params": params,
            "id": self.request_id
        }
        
        try:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect(self.socket_path)
            sock.sendall(json.dumps(request).encode() + b'\n')
            
            response = b""
            while True:
                chunk = sock.recv(4096)
                if not chunk:
                    break
                response += chunk
                if b'\n' in chunk:
                    break
            
            sock.close()
            return json.loads(response.decode())
        except Exception as e:
            return {"error": str(e)}
    
    def status(self):
        return self._call("status")
    
    def optimize(self):
        return self._call("optimize")
    
    def set_profile(self, profile):
        return self._call("profile_set", {"profile": profile})
    
    def get_profile(self):
        return self._call("profile_get")
    
    def clean(self):
        return self._call("clean", {"confirm": True})

if __name__ == "__main__":
    client = UroamClient()
    
    if len(sys.argv) < 2:
        print("Usage: uroam_client.py <status|optimize|profile_set|clean>")
        sys.exit(1)
    
    command = sys.argv[1]
    
    if command == "status":
        result = client.status()
    elif command == "optimize":
        result = client.optimize()
    elif command == "profile_set":
        if len(sys.argv) < 3:
            print("Usage: uroam_client.py profile_set <profile_name>")
            sys.exit(1)
        result = client.set_profile(sys.argv[2])
    elif command == "clean":
        result = client.clean()
    else:
        print(f"Unknown command: {command}")
        sys.exit(1)
    
    print(json.dumps(result, indent=2))

Bash Script Example

#!/bin/bash
# uroam-api.sh - Simple bash client for UROAM API

SOCKET="/run/uroam/uroamd.sock"
ID=0

uroam_call() {
    local method="$1"
    local params="$2"
    ((ID++))
    
    local request="{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":$params,\"id\":$ID}"
    
    echo "$request" | socat -T2 UNIX-CONNECT:"$SOCKET" -
}

# Get status
uroam_call "status" "{}"

# Set profile
uroam_call "profile_set" "{\"profile\":\"gaming\"}"

# Trigger optimization
uroam_call "optimize" "{}"

See Also