Commit b48c0134 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'qmp/queue/qmp' into staging

* qmp/queue/qmp:
  block: use proper qerrors in qmp_block_resize
  qerror: restore alphabetical order over qerrors
  qerror: add check-qerror.sh to verify alphabetical order
  qmp: Add missing gcc format attribute and fix format string
  qapi: Convert block_set_io_throttle
  qapi: Convert change
  qerror: Extend QERR_DEVICE_ENCRYPTED
  qapi: Introduce change-vnc-password
  monitor: expose readline state
  qapi: Convert eject
  block: eject_device(): Use error_set()
  qapi: Convert expire_password
  qapi: Convert set_password
  vnc: Simplify vnc_display_password()
parents 5414b325 939a1cc3
Loading
Loading
Loading
Loading
+86 −69
Original line number Diff line number Diff line
@@ -665,35 +665,35 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
    }
}

static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
static void eject_device(BlockDriverState *bs, int force, Error **errp)
{
    if (!bdrv_dev_has_removable_media(bs)) {
        qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
        return -1;
        error_set(errp, QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
        return;
    }

    if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
        bdrv_dev_eject_request(bs, force);
        if (!force) {
            qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
            return -1;
            error_set(errp, QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
            return;
        }
    }

    bdrv_close(bs);
    return 0;
}

int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)
void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
{
    BlockDriverState *bs;
    int force = qdict_get_try_bool(qdict, "force", 0);
    const char *filename = qdict_get_str(qdict, "device");

    bs = bdrv_find(filename);
    bs = bdrv_find(device);
    if (!bs) {
        qerror_report(QERR_DEVICE_NOT_FOUND, filename);
        return -1;
        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
        return;
    }
    return eject_device(mon, bs, force);

    eject_device(bs, force, errp);
}

void qmp_block_passwd(const char *device, const char *password, Error **errp)
@@ -717,78 +717,87 @@ void qmp_block_passwd(const char *device, const char *password, Error **errp)
    }
}

int do_change_block(Monitor *mon, const char *device,
                    const char *filename, const char *fmt)
static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
                                    int bdrv_flags, BlockDriver *drv,
                                    const char *password, Error **errp)
{
    if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
        return;
    }

    if (bdrv_key_required(bs)) {
        if (password) {
            if (bdrv_set_key(bs, password) < 0) {
                error_set(errp, QERR_INVALID_PASSWORD);
            }
        } else {
            error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),
                      bdrv_get_encrypted_filename(bs));
        }
    } else if (password) {
        error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
    }
}

void qmp_change_blockdev(const char *device, const char *filename,
                         bool has_format, const char *format, Error **errp)
{
    BlockDriverState *bs;
    BlockDriver *drv = NULL;
    int bdrv_flags;
    Error *err = NULL;

    bs = bdrv_find(device);
    if (!bs) {
        qerror_report(QERR_DEVICE_NOT_FOUND, device);
        return -1;
        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
        return;
    }
    if (fmt) {
        drv = bdrv_find_whitelisted_format(fmt);

    if (format) {
        drv = bdrv_find_whitelisted_format(format);
        if (!drv) {
            qerror_report(QERR_INVALID_BLOCK_FORMAT, fmt);
            return -1;
            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
            return;
        }
    }
    if (eject_device(mon, bs, 0) < 0) {
        return -1;

    eject_device(bs, 0, &err);
    if (error_is_set(&err)) {
        error_propagate(errp, err);
        return;
    }

    bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
    bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
    if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
        qerror_report(QERR_OPEN_FILE_FAILED, filename);
        return -1;
    }
    return monitor_read_bdrv_key_start(mon, bs, NULL, NULL);

    qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp);
}

/* throttling disk I/O limits */
int do_block_set_io_throttle(Monitor *mon,
                       const QDict *qdict, QObject **ret_data)
void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
                               int64_t bps_wr, int64_t iops, int64_t iops_rd,
                               int64_t iops_wr, Error **errp)
{
    BlockIOLimit io_limits;
    const char *devname = qdict_get_str(qdict, "device");
    BlockDriverState *bs;

    io_limits.bps[BLOCK_IO_LIMIT_TOTAL]
                        = qdict_get_try_int(qdict, "bps", -1);
    io_limits.bps[BLOCK_IO_LIMIT_READ]
                        = qdict_get_try_int(qdict, "bps_rd", -1);
    io_limits.bps[BLOCK_IO_LIMIT_WRITE]
                        = qdict_get_try_int(qdict, "bps_wr", -1);
    io_limits.iops[BLOCK_IO_LIMIT_TOTAL]
                        = qdict_get_try_int(qdict, "iops", -1);
    io_limits.iops[BLOCK_IO_LIMIT_READ]
                        = qdict_get_try_int(qdict, "iops_rd", -1);
    io_limits.iops[BLOCK_IO_LIMIT_WRITE]
                        = qdict_get_try_int(qdict, "iops_wr", -1);

    bs = bdrv_find(devname);
    bs = bdrv_find(device);
    if (!bs) {
        qerror_report(QERR_DEVICE_NOT_FOUND, devname);
        return -1;
        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
        return;
    }

    if ((io_limits.bps[BLOCK_IO_LIMIT_TOTAL] == -1)
        || (io_limits.bps[BLOCK_IO_LIMIT_READ] == -1)
        || (io_limits.bps[BLOCK_IO_LIMIT_WRITE] == -1)
        || (io_limits.iops[BLOCK_IO_LIMIT_TOTAL] == -1)
        || (io_limits.iops[BLOCK_IO_LIMIT_READ] == -1)
        || (io_limits.iops[BLOCK_IO_LIMIT_WRITE] == -1)) {
        qerror_report(QERR_MISSING_PARAMETER,
                      "bps/bps_rd/bps_wr/iops/iops_rd/iops_wr");
        return -1;
    }
    io_limits.bps[BLOCK_IO_LIMIT_TOTAL] = bps;
    io_limits.bps[BLOCK_IO_LIMIT_READ]  = bps_rd;
    io_limits.bps[BLOCK_IO_LIMIT_WRITE] = bps_wr;
    io_limits.iops[BLOCK_IO_LIMIT_TOTAL]= iops;
    io_limits.iops[BLOCK_IO_LIMIT_READ] = iops_rd;
    io_limits.iops[BLOCK_IO_LIMIT_WRITE]= iops_wr;

    if (!do_check_io_limits(&io_limits)) {
        qerror_report(QERR_INVALID_PARAMETER_COMBINATION);
        return -1;
        error_set(errp, QERR_INVALID_PARAMETER_COMBINATION);
        return;
    }

    bs->io_limits = io_limits;
@@ -803,8 +812,6 @@ int do_block_set_io_throttle(Monitor *mon,
            qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock));
        }
    }

    return 0;
}

int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
@@ -841,11 +848,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
    return 0;
}

/*
 * XXX: replace the QERR_UNDEFINED_ERROR errors with real values once the
 * existing QERR_ macro mess is cleaned up.  A good example for better
 * error reports can be found in the qemu-img resize code.
 */
void qmp_block_resize(const char *device, int64_t size, Error **errp)
{
    BlockDriverState *bs;
@@ -857,12 +859,27 @@ void qmp_block_resize(const char *device, int64_t size, Error **errp)
    }

    if (size < 0) {
        error_set(errp, QERR_UNDEFINED_ERROR);
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
        return;
    }

    if (bdrv_truncate(bs, size)) {
    switch (bdrv_truncate(bs, size)) {
    case 0:
        break;
    case -ENOMEDIUM:
        error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
        break;
    case -ENOTSUP:
        error_set(errp, QERR_UNSUPPORTED);
        break;
    case -EACCES:
        error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
        break;
    case -EBUSY:
        error_set(errp, QERR_DEVICE_IN_USE, device);
        break;
    default:
        error_set(errp, QERR_UNDEFINED_ERROR);
        return;
        break;
    }
}
+3 −5
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#define BLOCKDEV_H

#include "block.h"
#include "error.h"
#include "qemu-queue.h"

void blockdev_mark_auto_del(BlockDriverState *bs);
@@ -57,11 +58,8 @@ DriveInfo *drive_init(QemuOpts *arg, int default_to_scsi);

DriveInfo *add_init_drive(const char *opts);

void qmp_change_blockdev(const char *device, const char *filename,
                         bool has_format, const char *format, Error **errp);
void do_commit(Monitor *mon, const QDict *qdict);
int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_change_block(Monitor *mon, const char *device,
                    const char *filename, const char *fmt);
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_set_io_throttle(Monitor *mon,
                             const QDict *qdict, QObject **ret_data);
#endif
+0 −3
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@
#include "qemu-char.h"
#include "qdict.h"
#include "notify.h"
#include "qerror.h"
#include "monitor.h"

/* keyboard/mouse support */
@@ -384,12 +383,10 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires);
#else
static inline int vnc_display_password(DisplayState *ds, const char *password)
{
    qerror_report(QERR_FEATURE_DISABLED, "vnc");
    return -ENODEV;
}
static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
    qerror_report(QERR_FEATURE_DISABLED, "vnc");
    return -ENODEV;
};
#endif
+5 −10
Original line number Diff line number Diff line
@@ -75,8 +75,7 @@ ETEXI
        .args_type  = "force:-f,device:B",
        .params     = "[-f] device",
        .help       = "eject a removable medium (use -f to force it)",
        .user_print = monitor_user_noop,
        .mhandler.cmd_new = do_eject,
        .mhandler.cmd = hmp_eject,
    },

STEXI
@@ -108,8 +107,7 @@ ETEXI
        .args_type  = "device:B,target:F,arg:s?",
        .params     = "device filename [format]",
        .help       = "change a removable medium, optional format",
        .user_print = monitor_user_noop,
        .mhandler.cmd_new = do_change,
        .mhandler.cmd = hmp_change,
    },

STEXI
@@ -1204,8 +1202,7 @@ ETEXI
        .args_type  = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
        .params     = "device bps bps_rd bps_wr iops iops_rd iops_wr",
        .help       = "change I/O throttle limits for a block drive",
        .user_print = monitor_user_noop,
        .mhandler.cmd_new = do_block_set_io_throttle,
        .mhandler.cmd = hmp_block_set_io_throttle,
    },

STEXI
@@ -1219,8 +1216,7 @@ ETEXI
        .args_type  = "protocol:s,password:s,connected:s?",
        .params     = "protocol password action-if-connected",
        .help       = "set spice/vnc password",
        .user_print = monitor_user_noop,
        .mhandler.cmd_new = set_password,
        .mhandler.cmd = hmp_set_password,
    },

STEXI
@@ -1240,8 +1236,7 @@ ETEXI
        .args_type  = "protocol:s,time:s",
        .params     = "protocol time",
        .help       = "set spice/vnc password expire-time",
        .user_print = monitor_user_noop,
        .mhandler.cmd_new = expire_password,
        .mhandler.cmd = hmp_expire_password,
    },

STEXI
+102 −0
Original line number Diff line number Diff line
@@ -681,3 +681,105 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
    int64_t value = qdict_get_int(qdict, "value");
    qmp_migrate_set_speed(value, NULL);
}

void hmp_set_password(Monitor *mon, const QDict *qdict)
{
    const char *protocol  = qdict_get_str(qdict, "protocol");
    const char *password  = qdict_get_str(qdict, "password");
    const char *connected = qdict_get_try_str(qdict, "connected");
    Error *err = NULL;

    qmp_set_password(protocol, password, !!connected, connected, &err);
    hmp_handle_error(mon, &err);
}

void hmp_expire_password(Monitor *mon, const QDict *qdict)
{
    const char *protocol  = qdict_get_str(qdict, "protocol");
    const char *whenstr = qdict_get_str(qdict, "time");
    Error *err = NULL;

    qmp_expire_password(protocol, whenstr, &err);
    hmp_handle_error(mon, &err);
}

void hmp_eject(Monitor *mon, const QDict *qdict)
{
    int force = qdict_get_try_bool(qdict, "force", 0);
    const char *device = qdict_get_str(qdict, "device");
    Error *err = NULL;

    qmp_eject(device, true, force, &err);
    hmp_handle_error(mon, &err);
}

static void hmp_change_read_arg(Monitor *mon, const char *password,
                                void *opaque)
{
    qmp_change_vnc_password(password, NULL);
    monitor_read_command(mon, 1);
}

static void cb_hmp_change_bdrv_pwd(Monitor *mon, const char *password,
                                   void *opaque)
{
    Error *encryption_err = opaque;
    Error *err = NULL;
    const char *device;

    device = error_get_field(encryption_err, "device");

    qmp_block_passwd(device, password, &err);
    hmp_handle_error(mon, &err);
    error_free(encryption_err);

    monitor_read_command(mon, 1);
}

void hmp_change(Monitor *mon, const QDict *qdict)
{
    const char *device = qdict_get_str(qdict, "device");
    const char *target = qdict_get_str(qdict, "target");
    const char *arg = qdict_get_try_str(qdict, "arg");
    Error *err = NULL;

    if (strcmp(device, "vnc") == 0 &&
            (strcmp(target, "passwd") == 0 ||
             strcmp(target, "password") == 0)) {
        if (!arg) {
            monitor_read_password(mon, hmp_change_read_arg, NULL);
            return;
        }
    }

    qmp_change(device, target, !!arg, arg, &err);
    if (error_is_type(err, QERR_DEVICE_ENCRYPTED)) {
        monitor_printf(mon, "%s (%s) is encrypted.\n",
                       error_get_field(err, "device"),
                       error_get_field(err, "filename"));
        if (!monitor_get_rs(mon)) {
            monitor_printf(mon,
                    "terminal does not support password prompting\n");
            error_free(err);
            return;
        }
        readline_start(monitor_get_rs(mon), "Password: ", 1,
                       cb_hmp_change_bdrv_pwd, err);
        return;
    }
    hmp_handle_error(mon, &err);
}

void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
{
    Error *err = NULL;

    qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
                              qdict_get_int(qdict, "bps"),
                              qdict_get_int(qdict, "bps_rd"),
                              qdict_get_int(qdict, "bps_wr"),
                              qdict_get_int(qdict, "iops"),
                              qdict_get_int(qdict, "iops_rd"),
                              qdict_get_int(qdict, "iops_wr"), &err);
    hmp_handle_error(mon, &err);
}
Loading