-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce a privileged helper to run persistent reservation commands. This lets virtual machines send persistent reservations without using CAP_SYS_RAWIO or out-of-tree patches. The helper uses Unix permissions and SCM_RIGHTS to restrict access to processes that can access its socket and prove that they have an open file descriptor for a raw SCSI device. The next patch will also correct the usage of persistent reservations with multipath devices. It would also be possible to support for Linux's IOC_PR_* ioctls in the future, to support NVMe devices. For now, however, only SCSI is supported. Signed-off-by: Paolo Bonzini <[email protected]>
- Loading branch information
Showing
6 changed files
with
905 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
.. | ||
====================================== | ||
Persistent reservation helper protocol | ||
====================================== | ||
|
||
QEMU's SCSI passthrough devices, ``scsi-block`` and ``scsi-generic``, | ||
can delegate implementation of persistent reservations to an external | ||
(and typically privileged) program. Persistent Reservations allow | ||
restricting access to block devices to specific initiators in a shared | ||
storage setup. | ||
|
||
For a more detailed reference please refer the the SCSI Primary | ||
Commands standard, specifically the section on Reservations and the | ||
"PERSISTENT RESERVE IN" and "PERSISTENT RESERVE OUT" commands. | ||
|
||
This document describes the socket protocol used between QEMU's | ||
``pr-manager-helper`` object and the external program. | ||
|
||
.. contents:: | ||
|
||
Connection and initialization | ||
----------------------------- | ||
|
||
All data transmitted on the socket is big-endian. | ||
|
||
After connecting to the helper program's socket, the helper starts a simple | ||
feature negotiation process by writing four bytes corresponding to | ||
the features it exposes (``supported_features``). QEMU reads it, | ||
then writes four bytes corresponding to the desired features of the | ||
helper program (``requested_features``). | ||
|
||
If a bit is 1 in ``requested_features`` and 0 in ``supported_features``, | ||
the corresponding feature is not supported by the helper and the connection | ||
is closed. On the other hand, it is acceptable for a bit to be 0 in | ||
``requested_features`` and 1 in ``supported_features``; in this case, | ||
the helper will not enable the feature. | ||
|
||
Right now no feature is defined, so the two parties always write four | ||
zero bytes. | ||
|
||
Command format | ||
-------------- | ||
|
||
It is invalid to send multiple commands concurrently on the same | ||
socket. It is however possible to connect multiple sockets to the | ||
helper and send multiple commands to the helper for one or more | ||
file descriptors. | ||
|
||
A command consists of a request and a response. A request consists | ||
of a 16-byte SCSI CDB. A file descriptor must be passed to the helper | ||
together with the SCSI CDB using ancillary data. | ||
|
||
The CDB has the following limitations: | ||
|
||
- the command (stored in the first byte) must be one of 0x5E | ||
(PERSISTENT RESERVE IN) or 0x5F (PERSISTENT RESERVE OUT). | ||
|
||
- the allocation length (stored in bytes 7-8 of the CDB for PERSISTENT | ||
RESERVE IN) or parameter list length (stored in bytes 5-8 of the CDB | ||
for PERSISTENT RESERVE OUT) is limited to 8 KiB. | ||
|
||
For PERSISTENT RESERVE OUT, the parameter list is sent right after the | ||
CDB. The length of the parameter list is taken from the CDB itself. | ||
|
||
The helper's reply has the following structure: | ||
|
||
- 4 bytes for the SCSI status | ||
|
||
- 4 bytes for the payload size (nonzero only for PERSISTENT RESERVE IN | ||
and only if the SCSI status is 0x00, i.e. GOOD) | ||
|
||
- 96 bytes for the SCSI sense data | ||
|
||
- if the size is nonzero, the payload follows | ||
|
||
The sense data is always sent to keep the protocol simple, even though | ||
it is only valid if the SCSI status is CHECK CONDITION (0x02). | ||
|
||
The payload size is always less than or equal to the allocation length | ||
specified in the CDB for the PERSISTENT RESERVE IN command. | ||
|
||
If the protocol is violated, the helper closes the socket. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* Definitions for QEMU's persistent reservation helper daemon | ||
* | ||
* Copyright (C) 2017 Red Hat, Inc. | ||
* | ||
* Author: | ||
* Paolo Bonzini <[email protected]> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to | ||
* deal in the Software without restriction, including without limitation the | ||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
* sell copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
* IN THE SOFTWARE. | ||
*/ | ||
#ifndef QEMU_PR_HELPER_H | ||
#define QEMU_PR_HELPER_H 1 | ||
|
||
#include <stdint.h> | ||
|
||
#define PR_HELPER_CDB_SIZE 16 | ||
#define PR_HELPER_SENSE_SIZE 96 | ||
#define PR_HELPER_DATA_SIZE 8192 | ||
|
||
typedef struct PRHelperResponse { | ||
int32_t result; | ||
int32_t sz; | ||
uint8_t sense[PR_HELPER_SENSE_SIZE]; | ||
} PRHelperResponse; | ||
|
||
#endif |
Oops, something went wrong.