经典例子
如果直通了一个设备,然后尝试热迁移,在执行 qmp 命令的时候, 可以接受到这个错误:
(qemu) migrate -d file:/tmp/qemu_mig
Error: 0000:03:00.0: VFIO migration is not supported in kernel
add_blockers
注册错误的位置在:
error_setg(&err, "%s: VFIO migration is not supported in kernel",
vbasedev->name);
而最后打印错误的位置在:
bool migration_is_blocked(Error **errp)
{
GSList *blockers = migration_blockers[migrate_mode()];
if (qemu_savevm_state_blocked(errp)) {
return true;
}
if (blockers) {
error_propagate(errp, error_copy(blockers->data));
return true;
}
return false;
}
文档
devel/style.rst devel/qapi-code-gen.rst
report
不要用 printf ,而是去使用 error_report 和 warn_report ,qemu 需要控制 stdout 的正确 使用。 error_setg
propagate
bdrv_snapshot_goto 中经典例子:
首先,定义一个错误,然后在 error_propagate 中检查错误类型并且处理:
Error *local_err = NULL;
// ...
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
qobject_unref(options);
if (open_ret < 0) {
bdrv_unref(fallback_bs);
bs->drv = NULL;
/* A bdrv_snapshot_goto() error takes precedence */
error_propagate(errp, local_err);
return ret < 0 ? ret : open_ret;
}
更加经典的例子是:
host_memory_backend_memory_complete
bc->alloc(backend, &local_err);
if (local_err) {
goto out;
}
// ...
out:
error_propagate(errp, local_err);
bc::alloc 会会调用 file_backend_memory_alloc ,在 file_backend_memory_alloc 中
这个是做什么的?
ERRP_GUARD
这就是一个经典例子: vhost_user_blk_device_realize
为什么调用 error_propagate ,还是直接返回
error_propagate -> error_handle ,调用之后,会将 errp 中内容替换为 errp
简单来说,如果有本地的 Error ,而且调用函数的时候传递的是本地的 Error, 那么调用 error_propagate ,将本地的 Error 赋值到 errp 中。
那么问题来了,为什么需要 error_propagate ?
static void audio_validate_opts(Audiodev *dev, Error **errp)
{
Error *err = NULL;
audio_create_pdos(dev);
audio_validate_per_direction_opts(audio_get_pdo_in(dev), &err);
if (err) {
error_propagate(errp, err);
return;
}
audio_validate_per_direction_opts(audio_get_pdo_out(dev), &err);
if (err) {
error_propagate(errp, err);
return;
}
if (!dev->has_timer_period) {
dev->has_timer_period = true;
dev->timer_period = 10000; /* 100Hz -> 10ms */
}
}
一共两个文件
#include “qapi/error.h” #include “qemu/error-report.h”
看看这个是如何使用的?
void migrate_set_error(MigrationState *s, const Error *error)
{
QEMU_LOCK_GUARD(&s->error_mutex);
trace_migrate_error(error_get_pretty(error));
if (!s->error) {
s->error = error_copy(error);
}
}
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。