qmp

Crates.ioqmp
lib.rsqmp
version0.1.1
created_at2026-01-07 13:54:10.965949+00
updated_at2026-01-07 13:54:10.965949+00
descriptionQEMU QMP client library
homepagehttps://github.com/lvillis/qmp-rs
repositoryhttps://github.com/lvillis/qmp-rs
max_upload_size
id2028292
size91,784
(lvillis)

documentation

https://docs.rs/qmp

README

qmp

QEMU QMP client library.

Goals:

  • Pure Rust, async-first.
  • Unix/TCP socket support.
  • Correct greeting + qmp_capabilities negotiation.
  • JSON request/response encoding/decoding with serde.
  • Event stream (subscribe, multi-consumer).
  • Command calls with timeout and cooperative cancellation.
  • Optional, higher-level safe ops layer:
    • allow-list policies (white-list)
    • per-command mutex / idempotency
    • retry/backoff with jitter
    • structured errors
    • (optional) tracing observability

Quick start

Low-level client

use qmp::{Client, Endpoint};

# async fn demo() -> qmp::Result<()> {
let client = Client::connect(Endpoint::unix("/var/run/qemu-server/100.qmp")).await?;

let status: serde_json::Value = client.execute("query-status", Option::<()>::None).await?;
println!("status = {status}");

let mut events = client.events();
while let Ok(ev) = events.recv().await {
    println!("event: {} data={}", ev.name, ev.data);
}
# Ok(()) }

Safe ops layer

use qmp::{Client, Endpoint};
use qmp::ops::{OpsClient, Profile};

# async fn demo() -> qmp::Result<()> {
let client = Client::connect(Endpoint::unix("/var/run/qemu-server/100.qmp")).await?;

// Read-only allow-list by default.
let ops = OpsClient::from_profile(client, Profile::ReadOnly);

let v = ops.query_version().await?;
println!("qemu {}.{}.{} ({})", v.qemu.major, v.qemu.minor, v.qemu.micro, v.package);
# Ok(()) }
Commit count: 7

cargo fmt