qemu: Implement qemuDomainQemuMonitorCommandWithFiles

Add support for sending one FD from the client along with a monitor
command so that it's possible to use 'getfd' and 'add-fd' to use FDs
passed from the client with other QMP commands.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2022-01-28 14:39:24 +01:00
parent 43edde82af
commit da3acb8d55
6 changed files with 53 additions and 13 deletions

View File

@ -13920,21 +13920,44 @@ qemuDomainBackupGetXMLDesc(virDomainPtr domain,
} }
static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd, static int
char **result, unsigned int flags) qemuDomainQemuMonitorCommandWithFiles(virDomainPtr domain,
const char *cmd,
unsigned int ninfds,
int *infds,
unsigned int *noutfds,
int **outfds,
char **result,
unsigned int flags)
{ {
virQEMUDriver *driver = domain->conn->privateData; virQEMUDriver *driver = domain->conn->privateData;
virDomainObj *vm = NULL; virDomainObj *vm = NULL;
int ret = -1; int ret = -1;
qemuDomainObjPrivate *priv; qemuDomainObjPrivate *priv;
bool hmp; bool hmp;
int fd = -1;
virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP, -1); virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP, -1);
/* currently we don't pass back any fds */
if (outfds)
*outfds = NULL;
if (noutfds)
*noutfds = 0;
if (ninfds > 1) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("at most 1 fd can be passed to qemu along with a command"));
return -1;
}
if (ninfds == 1)
fd = infds[0];
if (!(vm = qemuDomainObjFromDomain(domain))) if (!(vm = qemuDomainObjFromDomain(domain)))
goto cleanup; goto cleanup;
if (virDomainQemuMonitorCommandEnsureACL(domain->conn, vm->def) < 0) if (virDomainQemuMonitorCommandWithFilesEnsureACL(domain->conn, vm->def) < 0)
goto cleanup; goto cleanup;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
@ -13950,7 +13973,7 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP); hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp); ret = qemuMonitorArbitraryCommand(priv->mon, cmd, fd, result, hmp);
qemuDomainObjExitMonitor(driver, vm); qemuDomainObjExitMonitor(driver, vm);
endjob: endjob:
@ -13962,6 +13985,16 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
} }
static int
qemuDomainQemuMonitorCommand(virDomainPtr domain,
const char *cmd,
char **result,
unsigned int flags)
{
return qemuDomainQemuMonitorCommandWithFiles(domain, cmd, 0, NULL, NULL, NULL, result, flags);
}
static int static int
qemuDomainOpenConsole(virDomainPtr dom, qemuDomainOpenConsole(virDomainPtr dom,
const char *dev_name, const char *dev_name,
@ -20923,6 +20956,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainRevertToSnapshot = qemuDomainRevertToSnapshot, /* 0.8.0 */ .domainRevertToSnapshot = qemuDomainRevertToSnapshot, /* 0.8.0 */
.domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */ .domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */
.domainQemuMonitorCommand = qemuDomainQemuMonitorCommand, /* 0.8.3 */ .domainQemuMonitorCommand = qemuDomainQemuMonitorCommand, /* 0.8.3 */
.domainQemuMonitorCommandWithFiles = qemuDomainQemuMonitorCommandWithFiles, /* 8.2.0 */
.domainQemuAttach = NULL, /* 0.9.4 - 5.5.0 */ .domainQemuAttach = NULL, /* 0.9.4 - 5.5.0 */
.domainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */ .domainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */
.connectDomainQemuMonitorEventRegister = qemuConnectDomainQemuMonitorEventRegister, /* 1.2.3 */ .connectDomainQemuMonitorEventRegister = qemuConnectDomainQemuMonitorEventRegister, /* 1.2.3 */

View File

@ -3074,17 +3074,18 @@ qemuMonitorDrivePivot(qemuMonitor *mon,
int int
qemuMonitorArbitraryCommand(qemuMonitor *mon, qemuMonitorArbitraryCommand(qemuMonitor *mon,
const char *cmd, const char *cmd,
int fd,
char **reply, char **reply,
bool hmp) bool hmp)
{ {
VIR_DEBUG("cmd=%s, reply=%p, hmp=%d", cmd, reply, hmp); VIR_DEBUG("cmd=%s, fd=%d, reply=%p, hmp=%d", cmd, fd, reply, hmp);
QEMU_CHECK_MONITOR(mon); QEMU_CHECK_MONITOR(mon);
if (hmp) if (hmp)
return qemuMonitorJSONHumanCommand(mon, cmd, reply); return qemuMonitorJSONHumanCommand(mon, cmd, fd, reply);
else else
return qemuMonitorJSONArbitraryCommand(mon, cmd, reply); return qemuMonitorJSONArbitraryCommand(mon, cmd, fd, reply);
} }

View File

@ -1088,6 +1088,7 @@ char *qemuMonitorDiskNameLookup(qemuMonitor *mon,
int qemuMonitorArbitraryCommand(qemuMonitor *mon, int qemuMonitorArbitraryCommand(qemuMonitor *mon,
const char *cmd, const char *cmd,
int fd,
char **reply, char **reply,
bool hmp); bool hmp);

View File

@ -1438,6 +1438,7 @@ qemuMonitorJSONHandleGuestCrashloaded(qemuMonitor *mon,
int int
qemuMonitorJSONHumanCommand(qemuMonitor *mon, qemuMonitorJSONHumanCommand(qemuMonitor *mon,
const char *cmd_str, const char *cmd_str,
int fd,
char **reply_str) char **reply_str)
{ {
g_autoptr(virJSONValue) cmd = NULL; g_autoptr(virJSONValue) cmd = NULL;
@ -1449,7 +1450,7 @@ qemuMonitorJSONHumanCommand(qemuMonitor *mon,
"s:command-line", cmd_str, "s:command-line", cmd_str,
NULL); NULL);
if (!cmd || qemuMonitorJSONCommand(mon, cmd, &reply) < 0) if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply) < 0)
return -1; return -1;
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
@ -4471,6 +4472,7 @@ qemuMonitorJSONDiskNameLookup(qemuMonitor *mon,
int qemuMonitorJSONArbitraryCommand(qemuMonitor *mon, int qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
const char *cmd_str, const char *cmd_str,
int fd,
char **reply_str) char **reply_str)
{ {
g_autoptr(virJSONValue) cmd = NULL; g_autoptr(virJSONValue) cmd = NULL;
@ -4479,7 +4481,7 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
if (!(cmd = virJSONValueFromString(cmd_str))) if (!(cmd = virJSONValueFromString(cmd_str)))
return -1; return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) if (qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply) < 0)
return -1; return -1;
if (!(*reply_str = virJSONValueToString(reply, false))) if (!(*reply_str = virJSONValueToString(reply, false)))

View File

@ -43,6 +43,7 @@ qemuMonitorJSONIOProcess(qemuMonitor *mon,
int int
qemuMonitorJSONHumanCommand(qemuMonitor *mon, qemuMonitorJSONHumanCommand(qemuMonitor *mon,
const char *cmd, const char *cmd,
int fd,
char **reply); char **reply);
int int
@ -369,6 +370,7 @@ qemuMonitorJSONDiskNameLookup(qemuMonitor *mon,
int int
qemuMonitorJSONArbitraryCommand(qemuMonitor *mon, qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
const char *cmd_str, const char *cmd_str,
int fd,
char **reply_str); char **reply_str);
int int

View File

@ -43,7 +43,7 @@ int qemuMonitorTextAddDrive(qemuMonitor *mon,
* address required when attaching drives to a controller */ * address required when attaching drives to a controller */
cmd = g_strdup_printf("drive_add dummy %s", drivestr); cmd = g_strdup_printf("drive_add dummy %s", drivestr);
if (qemuMonitorJSONHumanCommand(mon, cmd, &reply) < 0) if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply) < 0)
return -1; return -1;
if (strstr(reply, "unknown command:")) { if (strstr(reply, "unknown command:")) {
@ -93,7 +93,7 @@ int qemuMonitorTextDriveDel(qemuMonitor *mon,
cmd = g_strdup_printf("drive_del %s", drivestr); cmd = g_strdup_printf("drive_del %s", drivestr);
if (qemuMonitorJSONHumanCommand(mon, cmd, &reply) < 0) if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply) < 0)
return -1; return -1;
if (strstr(reply, "unknown command:")) { if (strstr(reply, "unknown command:")) {
@ -124,7 +124,7 @@ qemuMonitorTextCreateSnapshot(qemuMonitor *mon,
cmd = g_strdup_printf("savevm \"%s\"", name); cmd = g_strdup_printf("savevm \"%s\"", name);
if (qemuMonitorJSONHumanCommand(mon, cmd, &reply)) if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
return -1; return -1;
if (strstr(reply, "Error while creating snapshot") || if (strstr(reply, "Error while creating snapshot") ||
@ -150,7 +150,7 @@ int qemuMonitorTextDeleteSnapshot(qemuMonitor *mon, const char *name)
g_autofree char *reply = NULL; g_autofree char *reply = NULL;
cmd = g_strdup_printf("delvm \"%s\"", name); cmd = g_strdup_printf("delvm \"%s\"", name);
if (qemuMonitorJSONHumanCommand(mon, cmd, &reply)) if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
return -1; return -1;
if (strstr(reply, "No block device supports snapshots")) { if (strstr(reply, "No block device supports snapshots")) {