*/
#include "qemu-common.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/nbd.h"
#include "qemu/main-loop.h"
r->end_head = p[5];
r->end_cylinder = p[7] | ((p[6] << 2) & 0x300);
r->end_sector = p[6] & 0x3f;
- r->start_sector_abs = p[8] | p[9] << 8 | p[10] << 16 | p[11] << 24;
- r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;
+
+ r->start_sector_abs = le32_to_cpup((uint32_t *)(p + 8));
+ r->nb_sectors_abs = le32_to_cpup((uint32_t *)(p + 12));
}
-static int find_partition(BlockDriverState *bs, int partition,
+static int find_partition(BlockBackend *blk, int partition,
off_t *offset, off_t *size)
{
struct partition_record mbr[4];
int ext_partnum = 4;
int ret;
- if ((ret = bdrv_read(bs, 0, data, 1)) < 0) {
+ if ((ret = blk_read(blk, 0, data, 1)) < 0) {
errno = -ret;
err(EXIT_FAILURE, "error while reading");
}
for (i = 0; i < 4; i++) {
read_partition(&data[446 + 16 * i], &mbr[i]);
- if (!mbr[i].nb_sectors_abs)
+ if (!mbr[i].system || !mbr[i].nb_sectors_abs) {
continue;
+ }
if (mbr[i].system == 0xF || mbr[i].system == 0x5) {
struct partition_record ext[4];
uint8_t data1[512];
int j;
- if ((ret = bdrv_read(bs, mbr[i].start_sector_abs, data1, 1)) < 0) {
+ if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
errno = -ret;
err(EXIT_FAILURE, "error while reading");
}
for (j = 0; j < 4; j++) {
read_partition(&data1[446 + 16 * j], &ext[j]);
- if (!ext[j].nb_sectors_abs)
+ if (!ext[j].system || !ext[j].nb_sectors_abs) {
continue;
+ }
if ((ext_partnum + j + 1) == partition) {
*offset = (uint64_t)ext[j].start_sector_abs << 9;
int fd = inet_listen(address_and_port, NULL, 0, SOCK_STREAM, 0, &local_err);
if (local_err != NULL) {
- error_report("%s", error_get_pretty(local_err));
- error_free(local_err);
+ error_report_err(local_err);
}
return fd;
}
int fd = unix_listen(path, NULL, 0, &local_err);
if (local_err != NULL) {
- error_report("%s", error_get_pretty(local_err));
- error_free(local_err);
+ error_report_err(local_err);
}
return fd;
}
int fd = unix_connect(path, &local_err);
if (local_err != NULL) {
- error_report("%s", error_get_pretty(local_err));
- error_free(local_err);
+ error_report_err(local_err);
}
return fd;
}
{
char *device = arg;
off_t size;
- size_t blocksize;
uint32_t nbdflags;
int fd, sock;
int ret;
pthread_t show_parts_thread;
+ Error *local_error = NULL;
sock = unix_socket_outgoing(sockpath);
if (sock < 0) {
}
ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
- &size, &blocksize);
+ &size, &local_error);
if (ret < 0) {
+ if (local_error) {
+ fprintf(stderr, "%s\n", error_get_pretty(local_error));
+ error_free(local_error);
+ }
goto out_socket;
}
goto out_socket;
}
- ret = nbd_init(fd, sock, nbdflags, size, blocksize);
+ ret = nbd_init(fd, sock, nbdflags, size);
if (ret < 0) {
goto out_fd;
}
int main(int argc, char **argv)
{
+ BlockBackend *blk;
BlockDriverState *bs;
- BlockDriver *drv;
off_t dev_offset = 0;
uint32_t nbdflags = 0;
bool disconnect = false;
char *end;
int flags = BDRV_O_RDWR;
int partition = -1;
- int ret;
+ int ret = 0;
int fd;
bool seen_cache = false;
bool seen_discard = false;
const char *fmt = NULL;
Error *local_err = NULL;
BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+ QDict *options = NULL;
/* The client thread uses SIGTERM to interrupt the server. A signal
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
* print errors and exit with the proper status code.
*/
pid = fork();
- if (pid == 0) {
+ if (pid < 0) {
+ err(EXIT_FAILURE, "Failed to fork");
+ } else if (pid == 0) {
close(stderr_fd[0]);
ret = qemu_daemon(1, 0);
snprintf(sockpath, 128, SOCKET_PATH, basename(device));
}
- qemu_init_main_loop();
+ if (qemu_init_main_loop(&local_err)) {
+ error_report_err(local_err);
+ exit(EXIT_FAILURE);
+ }
bdrv_init();
atexit(bdrv_close_all);
if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv) {
- errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
- }
- } else {
- drv = NULL;
+ options = qdict_new();
+ qdict_put(options, "driver", qstring_from_str(fmt));
}
- bs = bdrv_new("hda", &error_abort);
-
srcpath = argv[optind];
- ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
- if (ret < 0) {
- errno = -ret;
- err(EXIT_FAILURE, "Failed to bdrv_open '%s': %s", argv[optind],
- error_get_pretty(local_err));
+ blk = blk_new_open("hda", srcpath, NULL, options, flags, &local_err);
+ if (!blk) {
+ errx(EXIT_FAILURE, "Failed to blk_new_open '%s': %s", argv[optind],
+ error_get_pretty(local_err));
}
+ bs = blk_bs(blk);
if (sn_opts) {
ret = bdrv_snapshot_load_tmp(bs,
}
bs->detect_zeroes = detect_zeroes;
- fd_size = bdrv_getlength(bs);
+ fd_size = blk_getlength(blk);
+ if (fd_size < 0) {
+ errx(EXIT_FAILURE, "Failed to determine the image length: %s",
+ strerror(-fd_size));
+ }
if (partition != -1) {
- ret = find_partition(bs, partition, &dev_offset, &fd_size);
+ ret = find_partition(blk, partition, &dev_offset, &fd_size);
if (ret < 0) {
errno = -ret;
err(EXIT_FAILURE, "Could not find partition %d", partition);
}
}
- exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed);
+ exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed,
+ &local_err);
+ if (!exp) {
+ errx(EXIT_FAILURE, "%s", error_get_pretty(local_err));
+ }
if (sockpath) {
fd = unix_socket_incoming(sockpath);
}
} while (state != TERMINATED);
- bdrv_close(bs);
+ blk_unref(blk);
if (sockpath) {
unlink(sockpath);
}
- if (sn_opts) {
- qemu_opts_del(sn_opts);
- }
+ qemu_opts_del(sn_opts);
if (device) {
void *ret;