#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
+#include "qemu/bswap.h"
#include "block/snapshot.h"
#include "qapi/util.h"
#include "qapi/qmp/qstring.h"
#include "qom/object_interfaces.h"
#include "io/channel-socket.h"
+#include "crypto/init.h"
#include <getopt.h>
#include <libgen.h>
#define QEMU_NBD_OPT_TLSCREDS 261
#define QEMU_NBD_OPT_IMAGE_OPTS 262
+#define MBR_SIZE 512
+
static NBDExport *exp;
static bool newproto;
static int verbose;
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
" -t, --persistent don't exit on the last connection\n"
" -v, --verbose display extra debugging information\n"
+" -x, --export-name=NAME expose export by name\n"
"\n"
"Exposing part of the image:\n"
" -o, --offset=OFFSET offset into the image\n"
r->end_cylinder = p[7] | ((p[6] << 2) & 0x300);
r->end_sector = p[6] & 0x3f;
- r->start_sector_abs = le32_to_cpup((uint32_t *)(p + 8));
- r->nb_sectors_abs = le32_to_cpup((uint32_t *)(p + 12));
+ r->start_sector_abs = ldl_le_p(p + 8);
+ r->nb_sectors_abs = ldl_le_p(p + 12);
}
static int find_partition(BlockBackend *blk, int partition,
off_t *offset, off_t *size)
{
struct partition_record mbr[4];
- uint8_t data[512];
+ uint8_t data[MBR_SIZE];
int i;
int ext_partnum = 4;
int ret;
- if ((ret = blk_read(blk, 0, data, 1)) < 0) {
+ ret = blk_pread(blk, 0, data, sizeof(data));
+ if (ret < 0) {
error_report("error while reading: %s", strerror(-ret));
exit(EXIT_FAILURE);
}
if (mbr[i].system == 0xF || mbr[i].system == 0x5) {
struct partition_record ext[4];
- uint8_t data1[512];
+ uint8_t data1[MBR_SIZE];
int j;
- if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
+ ret = blk_pread(blk, mbr[i].start_sector_abs * MBR_SIZE,
+ data1, sizeof(data1));
+ if (ret < 0) {
error_report("error while reading: %s", strerror(-ret));
exit(EXIT_FAILURE);
}
static void termsig_handler(int signum)
{
- state = TERMINATE;
+ atomic_cmpxchg(&state, RUNNING, TERMINATE);
qemu_notify_event();
}
const char *export_name = NULL;
const char *tlscredsid = NULL;
bool imageOpts = false;
+ bool writethrough = true;
/* The client thread uses SIGTERM to interrupt the server. A signal
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
sa_sigterm.sa_handler = termsig_handler;
sigaction(SIGTERM, &sa_sigterm, NULL);
+
+ qcrypto_init(&error_fatal);
+
module_call_init(MODULE_INIT_QOM);
qemu_add_opts(&qemu_object_opts);
qemu_init_exec_dir(argv[0]);
exit(EXIT_FAILURE);
}
seen_cache = true;
- if (bdrv_parse_cache_flags(optarg, &flags) == -1) {
+ if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) == -1) {
error_report("Invalid cache mode `%s'", optarg);
exit(EXIT_FAILURE);
}
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
- NULL, &local_err)) {
- error_report_err(local_err);
+ NULL, NULL)) {
exit(EXIT_FAILURE);
}
}
bs = blk_bs(blk);
+ blk_set_enable_write_cache(blk, !writethrough);
+
if (sn_opts) {
ret = bdrv_snapshot_load_tmp(bs,
qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),