libvirt-qemu.c 7.3 KB
Newer Older
C
Chris Lalancette 已提交
1 2 3 4
/*
 * libvirt-qemu.c: Interfaces for the libvirt library to handle qemu-specific
 *                 APIs.
 *
5
 * Copyright (C) 2010-2014 Red Hat, Inc.
C
Chris Lalancette 已提交
6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
C
Chris Lalancette 已提交
20 21 22 23 24 25
 *
 * Author: Chris Lalancette <clalance@redhat.com>
 */

#include <config.h>

26
#include "virerror.h"
27
#include "virlog.h"
28
#include "viruuid.h"
C
Chris Lalancette 已提交
29 30
#include "datatypes.h"

31 32
#define VIR_FROM_THIS VIR_FROM_NONE

33 34
#define virLibConnError(conn, error, info)                              \
    virReportErrorHelper(VIR_FROM_NONE, error, __FILE__, __FUNCTION__,  \
C
Chris Lalancette 已提交
35 36 37
                         __LINE__, info)

#define virLibDomainError(domain, error, info)                          \
38
    virReportErrorHelper(VIR_FROM_DOM, error, __FILE__, __FUNCTION__,   \
C
Chris Lalancette 已提交
39 40
                         __LINE__, info)

41 42 43 44 45 46 47
/**
 * virDomainQemuMonitorCommand:
 * @domain: a domain object
 * @cmd: the qemu monitor command string
 * @result: a string returned by @cmd
 * @flags: bitwise-or of supported virDomainQemuMonitorCommandFlags
 *
E
Eric Blake 已提交
48
 * This API is QEMU specific, so it will only work with hypervisor
49 50 51 52
 * connections to the QEMU driver.
 *
 * Send an arbitrary monitor command @cmd to @domain through the
 * qemu monitor. There are several requirements to safely and
E
Eric Blake 已提交
53
 * successfully use this API:
54
 *
E
Eric Blake 已提交
55 56 57 58 59 60
 *   - A @cmd that queries state without making any modifications is safe
 *   - A @cmd that alters state that is also tracked by libvirt is unsafe,
 *     and may cause libvirtd to crash
 *   - A @cmd that alters state not tracked by the current version of
 *     libvirt is possible as a means to test new qemu features before
 *     they have support in libvirt, but no guarantees are made to safety
61 62 63 64 65 66
 *
 * If VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP is set, the command is
 * considered to be a human monitor command and libvirt will automatically
 * convert it into QMP if needed.  In that case the @result will also
 * be converted back from QMP.
 *
E
Eric Blake 已提交
67 68
 * If successful, @result will be filled with the string output of the
 * @cmd, and the caller must free this string.
69 70 71 72
 *
 * Returns 0 in case of success, -1 in case of failure
 *
 */
C
Chris Lalancette 已提交
73 74 75 76 77 78
int
virDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
                            char **result, unsigned int flags)
{
    virConnectPtr conn;

79 80
    VIR_DOMAIN_DEBUG(domain, "cmd=%s, result=%p, flags=%x",
                     cmd, result, flags);
C
Chris Lalancette 已提交
81 82 83 84 85 86 87 88 89 90 91

    virResetLastError();

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return -1;
    }

    conn = domain->conn;

92
    virCheckNonNullArgGoto(result, error);
93
    virCheckReadOnlyGoto(conn->flags, error);
C
Chris Lalancette 已提交
94

95
    if (conn->driver->domainQemuMonitorCommand) {
C
Chris Lalancette 已提交
96
        int ret;
97
        ret = conn->driver->domainQemuMonitorCommand(domain, cmd, result,
C
Chris Lalancette 已提交
98 99 100 101 102 103
                                                     flags);
        if (ret < 0)
            goto error;
        return ret;
    }

104
    virReportUnsupportedError();
C
Chris Lalancette 已提交
105 106 107 108 109

error:
    virDispatchError(conn);
    return -1;
}
110

111

112 113 114
/**
 * virDomainQemuAttach:
 * @conn: pointer to a hypervisor connection
115
 * @pid_value: the UNIX process ID of the external QEMU process
116 117
 * @flags: optional flags, currently unused
 *
E
Eric Blake 已提交
118
 * This API is QEMU specific, so it will only work with hypervisor
119 120 121
 * connections to the QEMU driver.
 *
 * This API will attach to an externally launched QEMU process
E
Eric Blake 已提交
122
 * identified by @pid. There are several requirements to successfully
123 124 125 126 127 128 129 130 131
 * attach to an external QEMU process:
 *
 *   - It must have been started with a monitor socket using the UNIX
 *     domain socket protocol.
 *   - No device hotplug/unplug, or other configuration changes can
 *     have been made via the monitor since it started.
 *   - The '-name' and '-uuid' arguments should have been set (not
 *     mandatory, but strongly recommended)
 *
132 133 134 135
 * To date, the only platforms we know of where pid_t is larger than
 * unsigned int (64-bit Windows) also lack UNIX sockets, so the choice
 * of @pid_value as an unsigned int should not present any difficulties.
 *
136 137
 * If successful, then the guest will appear in the list of running
 * domains for this connection, and other APIs should operate
E
Eric Blake 已提交
138
 * normally (provided the above requirements were honored).
139 140 141 142 143
 *
 * Returns a new domain object on success, NULL otherwise
 */
virDomainPtr
virDomainQemuAttach(virConnectPtr conn,
144
                    unsigned int pid_value,
145 146
                    unsigned int flags)
{
147 148
    pid_t pid = pid_value;
    VIR_DEBUG("conn=%p, pid=%u, flags=%x", conn, pid_value, flags);
149 150 151 152 153 154 155 156 157

    virResetLastError();

    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

158 159 160 161 162
    virCheckPositiveArgGoto(pid_value, error);
    if (pid != pid_value) {
        virReportInvalidArg(pid_value,
                            _("pid_value in %s is too large"),
                            __FUNCTION__);
163 164 165
        goto error;
    }

166
    virCheckReadOnlyGoto(conn->flags, error);
167

168
    if (conn->driver->domainQemuAttach) {
169
        virDomainPtr ret;
170
        ret = conn->driver->domainQemuAttach(conn, pid_value, flags);
171 172 173 174 175
        if (!ret)
            goto error;
        return ret;
    }

176
    virReportUnsupportedError();
177 178 179 180 181

error:
    virDispatchError(conn);
    return NULL;
}
182

183

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
/**
 * virDomainQemuAgentCommand:
 * @domain: a domain object
 * @cmd: the guest agent command string
 * @timeout: timeout seconds
 * @flags: execution flags
 *
 * Execute an arbitrary Guest Agent command.
 *
 * Issue @cmd to the guest agent running in @domain.
 * @timeout must be -2, -1, 0 or positive.
 * VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK(-2): meaning to block forever waiting for
 * a result.
 * VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT(-1): use default timeout value.
 * VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT(0): does not wait.
 * positive value: wait for @timeout seconds
 *
 * Returns strings if success, NULL in failure.
 */
char *
virDomainQemuAgentCommand(virDomainPtr domain,
                          const char *cmd,
                          int timeout,
                          unsigned int flags)
{
    virConnectPtr conn;
210
    char *ret;
211

212 213
    VIR_DOMAIN_DEBUG(domain, "cmd=%s, timeout=%d, flags=%x",
                     cmd, timeout, flags);
214

215 216
    virResetLastError();

217 218 219 220 221 222 223 224
    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
        virDispatchError(NULL);
        return NULL;
    }

    conn = domain->conn;

225
    virCheckReadOnlyGoto(conn->flags, error);
226

227
    if (conn->driver->domainQemuAgentCommand) {
228 229 230 231 232
        ret = conn->driver->domainQemuAgentCommand(domain, cmd,
                                                   timeout, flags);
        if (!ret)
            goto error;
        return ret;
233 234
    }

235
    virReportUnsupportedError();
236

237
error:
238 239 240
    virDispatchError(conn);
    return NULL;
}