pr-manager-helper: add PR_HELPER_CLEANUP command support

qemu-pr-helper now supports the vendor-specific PR_HELPER_CLEANUP SCSI
command. Add support to the client side.

pr_manager_helper_run() uses scsi_cdb_xfer() to determine the number of
bytes to transfer. Extend scsi_cdb_xfer() to know that this
vendor-specific command does not transfer any bytes.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Link: https://lore.kernel.org/r/20261013181752.1299456-6-stefanha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Stefan Hajnoczi authored and Paolo Bonzini committed 2026-10-15 10:55:17 +02:00
1 parent e974bdd134
commit 179e9fa5f3
2 files changed
+20 -3

No files matched your search

+17 -3
View File
@@ -38,6 +38,8 @@ struct PRManagerHelper {
QemuMutex lock; QemuMutex lock;
QIOChannel *ioc; QIOChannel *ioc;
uint32_t proto_flags; /* flags negotiated with pr-helper */
}; };
static void pr_manager_send_status_changed_event(PRManagerHelper *pr_mgr) static void pr_manager_send_status_changed_event(PRManagerHelper *pr_mgr)
@@ -129,7 +131,9 @@ static int pr_manager_helper_initialize(PRManagerHelper *pr_mgr,
goto out_close; goto out_close;
} }
flags = 0; pr_mgr->proto_flags = be32_to_cpu(flags) & PR_HELPER_FEATURE_CLEANUP;
flags = cpu_to_be32(pr_mgr->proto_flags);
r = pr_manager_helper_write(pr_mgr, -1, &flags, sizeof(flags), errp); r = pr_manager_helper_write(pr_mgr, -1, &flags, sizeof(flags), errp);
if (r < 0) { if (r < 0) {
goto out_close; goto out_close;
@@ -161,9 +165,19 @@ static int pr_manager_helper_run(PRManager *p,
} }
memcpy(cdb, io_hdr->cmdp, io_hdr->cmd_len); memcpy(cdb, io_hdr->cmdp, io_hdr->cmd_len);
assert(cdb[0] == PERSISTENT_RESERVE_OUT || cdb[0] == PERSISTENT_RESERVE_IN); assert(cdb[0] == PERSISTENT_RESERVE_OUT ||
cdb[0] == PERSISTENT_RESERVE_IN ||
cdb[0] == PR_HELPER_CLEANUP);
/* The command is only available when pr-helper supports it */
if (cdb[0] == PR_HELPER_CLEANUP &&
!(pr_mgr->proto_flags & PR_HELPER_FEATURE_CLEANUP)) {
return -ENOTSUP;
}
expected_dir = expected_dir =
(cdb[0] == PERSISTENT_RESERVE_OUT ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV); (cdb[0] == PERSISTENT_RESERVE_IN ?
SG_DXFER_FROM_DEV : SG_DXFER_TO_DEV);
if (io_hdr->dxfer_direction != expected_dir) { if (io_hdr->dxfer_direction != expected_dir) {
return -EINVAL; return -EINVAL;
} }
+3
View File
@@ -29,6 +29,9 @@ uint32_t scsi_data_cdb_xfer(uint8_t *buf)
uint32_t scsi_cdb_xfer(uint8_t *buf) uint32_t scsi_cdb_xfer(uint8_t *buf)
{ {
if (buf[0] == PR_HELPER_CLEANUP) {
return 0;
}
switch (buf[0] >> 5) { switch (buf[0] >> 5) {
case 0: case 0:
return buf[4]; return buf[4];