mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
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:
parent
43edde82af
commit
da3acb8d55
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)))
|
||||||
|
@ -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
|
||||||
|
@ -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")) {
|
||||||
|
Loading…
Reference in New Issue
Block a user