qemu_monitor_text.c 7.4 KB
Newer Older
1 2 3
/*
 * qemu_monitor_text.c: interaction with QEMU monitor console
 *
4
 * Copyright (C) 2006-2014 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * 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/>.
20 21 22 23 24 25
 */

#include <config.h>


#include "qemu_monitor_text.h"
26
#include "viralloc.h"
27
#include "virlog.h"
28
#include "virerror.h"
29
#include "virstring.h"
30

31
#define VIR_FROM_THIS VIR_FROM_QEMU
32

33
VIR_LOG_INIT("qemu.qemu_monitor_text");
34

35 36 37 38 39 40 41 42 43
int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
                            const char *drivestr)
{
    char *cmd = NULL;
    char *reply = NULL;
    int ret = -1;
    char *safe_str;

    safe_str = qemuMonitorEscapeArg(drivestr);
44
    if (!safe_str)
45 46 47 48
        return -1;

    /* 'dummy' here is just a placeholder since there is no PCI
     * address required when attaching drives to a controller */
49
    if (virAsprintf(&cmd, "drive_add dummy %s", safe_str) < 0)
50 51
        goto cleanup;

52
    if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
53 54
        goto cleanup;

55
    if (strstr(reply, "unknown command:")) {
56 57
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       _("drive hotplug is not supported"));
58 59 60
        goto cleanup;
    }

61
    if (strstr(reply, "could not open disk image")) {
62 63
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       _("open disk image file failed"));
64 65 66
        goto cleanup;
    }

67 68 69 70 71 72 73 74 75 76
    if (strstr(reply, "Could not open")) {
        size_t len = strlen(reply);
        if (reply[len - 1] == '\n')
            reply[len - 1] = '\0';

        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       reply);
        goto cleanup;
    }

77 78 79 80 81 82
    if (strstr(reply, "Image is not in")) {
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                       _("Incorrect disk format"));
        goto cleanup;
    }

83 84
    ret = 0;

85
 cleanup:
86 87 88 89 90
    VIR_FREE(cmd);
    VIR_FREE(reply);
    VIR_FREE(safe_str);
    return ret;
}
91

92

93 94
int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
                            const char *drivestr)
95 96 97 98 99 100
{
    char *cmd = NULL;
    char *reply = NULL;
    char *safedev;
    int ret = -1;

101
    if (!(safedev = qemuMonitorEscapeArg(drivestr)))
102 103
        goto cleanup;

104
    if (virAsprintf(&cmd, "drive_del %s", safedev) < 0)
105 106
        goto cleanup;

107
    if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
108 109 110
        goto cleanup;

    if (strstr(reply, "unknown command:")) {
111
        VIR_ERROR(_("deleting drive is not supported.  "
112 113 114
                    "This may leak data if disk is reassigned"));
        ret = 1;
        goto cleanup;
115 116 117

    /* (qemu) drive_del wark
     * Device 'wark' not found */
118
    } else if (strstr(reply, "Device '") && strstr(reply, "not found")) {
119 120
        /* NB: device not found errors mean the drive was auto-deleted and we
         * ignore the error */
121
    } else if (STRNEQ(reply, "")) {
122 123
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("deleting %s drive failed: %s"), drivestr, reply);
124 125 126 127 128
        goto cleanup;
    }

    ret = 0;

129
 cleanup:
130 131 132 133 134
    VIR_FREE(cmd);
    VIR_FREE(reply);
    VIR_FREE(safedev);
    return ret;
}
135

136 137 138
int
qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon,
                              const char *name)
C
Chris Lalancette 已提交
139
{
140
    char *cmd = NULL;
C
Chris Lalancette 已提交
141 142
    char *reply = NULL;
    int ret = -1;
143
    char *safename;
C
Chris Lalancette 已提交
144

145
    if (!(safename = qemuMonitorEscapeArg(name)) ||
146
        virAsprintf(&cmd, "savevm \"%s\"", safename) < 0)
147
        goto cleanup;
C
Chris Lalancette 已提交
148

149
    if (qemuMonitorHMPCommand(mon, cmd, &reply))
C
Chris Lalancette 已提交
150 151
        goto cleanup;

152 153
    if (strstr(reply, "Error while creating snapshot") ||
        strstr(reply, "Could not open VM state file") ||
154
        strstr(reply, "State blocked by non-migratable device") ||
155
        strstr(reply, "Error: ") ||
156
        (strstr(reply, "Error") && strstr(reply, "while writing VM"))) {
157 158
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("Failed to take snapshot: %s"), reply);
C
Chris Lalancette 已提交
159
        goto cleanup;
160
    } else if (strstr(reply, "No block device can accept snapshots")) {
161 162
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("this domain does not have a device to take snapshots"));
C
Chris Lalancette 已提交
163 164 165 166 167
        goto cleanup;
    }

    ret = 0;

168
 cleanup:
169
    VIR_FREE(safename);
C
Chris Lalancette 已提交
170 171 172 173 174 175 176
    VIR_FREE(cmd);
    VIR_FREE(reply);
    return ret;
}

int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name)
{
177
    char *cmd = NULL;
C
Chris Lalancette 已提交
178 179
    char *reply = NULL;
    int ret = -1;
180
    char *safename;
C
Chris Lalancette 已提交
181

182
    if (!(safename = qemuMonitorEscapeArg(name)) ||
183
        virAsprintf(&cmd, "loadvm \"%s\"", safename) < 0)
184
        goto cleanup;
C
Chris Lalancette 已提交
185

186
    if (qemuMonitorHMPCommand(mon, cmd, &reply))
C
Chris Lalancette 已提交
187 188
        goto cleanup;

189
    if (strstr(reply, "No block device supports snapshots")) {
190 191
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("this domain does not have a device to load snapshots"));
C
Chris Lalancette 已提交
192
        goto cleanup;
193
    } else if (strstr(reply, "Could not find snapshot")) {
194 195 196
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("the snapshot '%s' does not exist, and was not loaded"),
                       name);
C
Chris Lalancette 已提交
197
        goto cleanup;
198 199 200
    } else if (strstr(reply, "Snapshots not supported on device")) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("Failed to load snapshot: %s"), reply);
C
Chris Lalancette 已提交
201
        goto cleanup;
202
    } else if (strstr(reply, "Could not open VM state file") ||
203
               strstr(reply, "Error: ") ||
204 205 206 207 208
               (strstr(reply, "Error") &&
                (strstr(reply, "while loading VM state") ||
                 strstr(reply, "while activating snapshot on")))) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("Failed to load snapshot: %s"), reply);
C
Chris Lalancette 已提交
209 210 211 212 213
        goto cleanup;
    }

    ret = 0;

214
 cleanup:
215
    VIR_FREE(safename);
C
Chris Lalancette 已提交
216 217 218 219 220 221 222
    VIR_FREE(cmd);
    VIR_FREE(reply);
    return ret;
}

int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name)
{
223
    char *cmd = NULL;
C
Chris Lalancette 已提交
224 225
    char *reply = NULL;
    int ret = -1;
226
    char *safename;
C
Chris Lalancette 已提交
227

228
    if (!(safename = qemuMonitorEscapeArg(name)) ||
229
        virAsprintf(&cmd, "delvm \"%s\"", safename) < 0)
230
        goto cleanup;
231
    if (qemuMonitorHMPCommand(mon, cmd, &reply))
C
Chris Lalancette 已提交
232 233
        goto cleanup;

234
    if (strstr(reply, "No block device supports snapshots")) {
235 236
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("this domain does not have a device to delete snapshots"));
C
Chris Lalancette 已提交
237
        goto cleanup;
238
    } else if (strstr(reply, "Snapshots not supported on device")) {
239
        virReportError(VIR_ERR_OPERATION_INVALID, "%s", reply);
C
Chris Lalancette 已提交
240
        goto cleanup;
241 242 243
    } else if (strstr(reply, "Error: ") ||
               (strstr(reply, "Error") &&
                strstr(reply, "while deleting snapshot"))) {
244 245
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("Failed to delete snapshot: %s"), reply);
C
Chris Lalancette 已提交
246 247 248 249 250
        goto cleanup;
    }

    ret = 0;

251
 cleanup:
252
    VIR_FREE(safename);
C
Chris Lalancette 已提交
253 254 255 256
    VIR_FREE(cmd);
    VIR_FREE(reply);
    return ret;
}