#include "hw/loader.h"
#include "bt-host.h"
#include "net.h"
+#include "net/slirp.h"
#include "monitor.h"
#include "console.h"
#include "sysemu.h"
struct hpet_info info;
int r, fd;
- fd = open("/dev/hpet", O_RDONLY);
+ fd = qemu_open("/dev/hpet", O_RDONLY);
if (fd < 0)
return -1;
int rtc_fd;
unsigned long current_rtc_freq = 0;
- TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
+ TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY));
if (rtc_fd < 0)
return -1;
ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq);
return "\0";
}
-BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
+BlockInterfaceErrorAction drive_get_on_error(
+ BlockDriverState *bdrv, int is_read)
{
DriveInfo *dinfo;
QTAILQ_FOREACH(dinfo, &drives, next) {
if (dinfo->bdrv == bdrv)
- return dinfo->onerror;
+ return is_read ? dinfo->on_read_error : dinfo->on_write_error;
}
- return BLOCK_ERR_STOP_ENOSPC;
+ return is_read ? BLOCK_ERR_REPORT : BLOCK_ERR_STOP_ENOSPC;
}
static void bdrv_format_print(void *opaque, const char *name)
qemu_free(dinfo);
}
+static int parse_block_error_action(const char *buf, int is_read)
+{
+ if (!strcmp(buf, "ignore")) {
+ return BLOCK_ERR_IGNORE;
+ } else if (!is_read && !strcmp(buf, "enospc")) {
+ return BLOCK_ERR_STOP_ENOSPC;
+ } else if (!strcmp(buf, "stop")) {
+ return BLOCK_ERR_STOP_ANY;
+ } else if (!strcmp(buf, "report")) {
+ return BLOCK_ERR_REPORT;
+ } else {
+ fprintf(stderr, "qemu: '%s' invalid %s error action\n",
+ buf, is_read ? "read" : "write");
+ return -1;
+ }
+}
+
DriveInfo *drive_init(QemuOpts *opts, void *opaque,
int *fatal_error)
{
int cache;
int aio = 0;
int ro = 0;
- int bdrv_flags, onerror;
+ int bdrv_flags;
+ int on_read_error, on_write_error;
const char *devaddr;
DriveInfo *dinfo;
int snapshot = 0;
}
}
- onerror = BLOCK_ERR_STOP_ENOSPC;
+ on_write_error = BLOCK_ERR_STOP_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
fprintf(stderr, "werror is no supported by this format\n");
return NULL;
}
- if (!strcmp(buf, "ignore"))
- onerror = BLOCK_ERR_IGNORE;
- else if (!strcmp(buf, "enospc"))
- onerror = BLOCK_ERR_STOP_ENOSPC;
- else if (!strcmp(buf, "stop"))
- onerror = BLOCK_ERR_STOP_ANY;
- else if (!strcmp(buf, "report"))
- onerror = BLOCK_ERR_REPORT;
- else {
- fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
+
+ on_write_error = parse_block_error_action(buf, 0);
+ if (on_write_error < 0) {
+ return NULL;
+ }
+ }
+
+ on_read_error = BLOCK_ERR_REPORT;
+ if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
+ if (type != IF_IDE && type != IF_VIRTIO) {
+ fprintf(stderr, "rerror is no supported by this format\n");
+ return NULL;
+ }
+
+ on_read_error = parse_block_error_action(buf, 1);
+ if (on_read_error < 0) {
return NULL;
}
}
dinfo->type = type;
dinfo->bus = bus_id;
dinfo->unit = unit_id;
- dinfo->onerror = onerror;
+ dinfo->on_read_error = on_read_error;
+ dinfo->on_write_error = on_write_error;
dinfo->opts = opts;
if (serial)
strncpy(dinfo->serial, serial, sizeof(serial));
return found;
}
-static uint64_t bytes_transferred = 0;
+static uint64_t bytes_transferred;
static ram_addr_t ram_save_remaining(void)
{
return last_ram_offset;
}
-static int ram_save_live(QEMUFile *f, int stage, void *opaque)
+static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
{
ram_addr_t addr;
uint64_t bytes_transferred_last;
double bwidth = 0;
uint64_t expected_time = 0;
+ if (stage < 0) {
+ cpu_physical_memory_set_dirty_tracking(0);
+ return 0;
+ }
+
if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
qemu_file_set_error(f);
return 0;
}
if (stage == 1) {
+ bytes_transferred = 0;
+
/* Make sure all dirty bits are set */
for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED);
}
#endif
- } else if (flags & RAM_SAVE_FLAG_PAGE)
+ } else if (flags & RAM_SAVE_FLAG_PAGE) {
qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
+ }
+ if (qemu_file_has_error(f)) {
+ return -EIO;
+ }
} while (!(flags & RAM_SAVE_FLAG_EOS));
return 0;
int err;
int fds[2];
- err = pipe(fds);
+ err = qemu_pipe(fds);
if (err == -1)
return -errno;
} else if (pid < 0)
exit(1);
+ close(fds[0]);
+ qemu_set_cloexec(fds[1]);
+
setsid();
pid = fork();
exit(1);
chdir("/");
- TFR(fd = open("/dev/null", O_RDWR));
+ TFR(fd = qemu_open("/dev/null", O_RDWR));
if (fd == -1)
exit(1);
}