Commit 03ff3ca3 authored by aliguori's avatar aliguori

Use common objects for qemu-img and qemu-nbd

Right now, we sprinkle #if defined(QEMU_IMG) && defined(QEMU_NBD) all over the
code.  It's ugly and causes us to have to build multiple object files for
linking against qemu and the tools.

This patch introduces a new file, qemu-tool.c which contains enough for
qemu-img, qemu-nbd, and QEMU to all share the same objects.

This also required getting qemu-nbd to be a bit more Windows friendly.  I also
changed the Windows block-raw to use normal IO instead of overlapping IO since
we don't actually do AIO yet on Windows.  I changed the various #if 0's to
 #if WIN32_AIO to make it easier for someone to eventually fix AIO on Windows.

After this patch, there are no longer any #ifdef's related to qemu-img and
qemu-nbd.
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5226 c046a42c-6fe2-441c-8c8c-71466251a162
parent d9cf1578
......@@ -28,6 +28,10 @@ ifdef CONFIG_SOLARIS
LIBS+=-lsocket -lnsl -lresolv
endif
ifdef CONFIG_WIN32
LIBS+=-lwinmm -lws2_32 -liphlpapi
endif
all: $(TOOLS) $(DOCS) recurse-all
SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
......@@ -46,9 +50,17 @@ recurse-all: $(SUBDIR_RULES)
BLOCK_OBJS=cutils.o qemu-malloc.o
BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
BLOCK_OBJS+=block-qcow2.o block-parallels.o
ifndef CONFIG_WIN32
BLOCK_OBJS+=block-nbd.o
BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
BLOCK_OBJS+=nbd.o block.o
ifdef CONFIG_WIN32
BLOCK_OBJS += block-raw-win32.o
else
BLOCK_OBJS += block-raw-posix.o
endif
ifdef CONFIG_AIO
BLOCK_OBJS += compatfd.o
endif
######################################################################
......@@ -59,11 +71,6 @@ endif
OBJS=$(BLOCK_OBJS)
OBJS+=readline.o console.o
OBJS+=block.o
ifndef CONFIG_WIN32
OBJS+=nbd.o
endif
OBJS+=irq.o
OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
......@@ -173,33 +180,15 @@ libqemu_user.a: $(USER_OBJS)
rm -f $@
$(AR) rcs $@ $(USER_OBJS)
QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
ifdef CONFIG_WIN32
QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
else
QEMU_IMG_BLOCK_OBJS += nbd.o qemu-img-block-raw-posix.o
endif
ifdef CONFIG_AIO
QEMU_IMG_BLOCK_OBJS += compatfd.o
endif
######################################################################
qemu-img$(EXESUF): qemu-img.o qemu-img-block.o $(QEMU_IMG_BLOCK_OBJS)
qemu-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
qemu-img-%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_IMG -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
qemu-nbd-%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_NBD -c -o $@ $<
qemu-nbd$(EXESUF): qemu-nbd.o qemu-nbd-nbd.o qemu-img-block.o \
osdep.o qemu-nbd-block-raw-posix.o compatfd.o $(BLOCK_OBJS)
qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
# dyngen host tool
......
......@@ -22,11 +22,8 @@
* THE SOFTWARE.
*/
#include "qemu-common.h"
#if !defined(QEMU_IMG) && !defined(QEMU_NBD)
#include "qemu-timer.h"
#include "exec-all.h"
#include "qemu-char.h"
#endif
#include "block_int.h"
#include "compatfd.h"
#include <assert.h>
......@@ -70,7 +67,7 @@
//#define DEBUG_FLOPPY
//#define DEBUG_BLOCK
#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
#if defined(DEBUG_BLOCK)
#define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \
{ fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
#else
......@@ -99,7 +96,7 @@ typedef struct BDRVRawState {
int fd_got_error;
int fd_media_changed;
#endif
#if defined(O_DIRECT) && !defined(QEMU_IMG)
#if defined(O_DIRECT)
uint8_t* aligned_buf;
#endif
} BDRVRawState;
......@@ -137,7 +134,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
return ret;
}
s->fd = fd;
#if defined(O_DIRECT) && !defined(QEMU_IMG)
#if defined(O_DIRECT)
s->aligned_buf = NULL;
if (flags & BDRV_O_DIRECT) {
s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE);
......@@ -272,7 +269,7 @@ label__raw_write__success:
}
#if defined(O_DIRECT) && !defined(QEMU_IMG)
#if defined(O_DIRECT)
/*
* offset and count are in bytes and possibly not aligned. For files opened
* with O_DIRECT, necessary alignments are ensured before calling
......@@ -525,9 +522,7 @@ void qemu_aio_init(void)
fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
#if !defined(QEMU_IMG) && !defined(QEMU_NBD)
qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
#endif
#if defined(__GLIBC__) && defined(__linux__)
{
......@@ -556,10 +551,8 @@ void qemu_aio_wait(void)
{
int ret;
#if !defined(QEMU_IMG) && !defined(QEMU_NBD)
if (qemu_bh_poll())
return;
#endif
if (!first_aio)
return;
......@@ -605,14 +598,12 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
return acb;
}
#if !defined(QEMU_IMG) && !defined(QEMU_NBD)
static void raw_aio_em_cb(void* opaque)
{
RawAIOCB *acb = opaque;
acb->common.cb(acb->common.opaque, acb->ret);
qemu_aio_release(acb);
}
#endif
static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors,
......@@ -624,7 +615,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
* If O_DIRECT is used and the buffer is not aligned fall back
* to synchronous IO.
*/
#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
#if defined(O_DIRECT)
BDRVRawState *s = bs->opaque;
if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
......@@ -657,7 +648,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
* If O_DIRECT is used and the buffer is not aligned fall back
* to synchronous IO.
*/
#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
#if defined(O_DIRECT)
BDRVRawState *s = bs->opaque;
if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
......@@ -719,9 +710,7 @@ void qemu_aio_flush(void)
void qemu_aio_wait(void)
{
#if !defined(QEMU_IMG) && !defined(QEMU_NBD)
qemu_bh_poll();
#endif
}
#endif /* CONFIG_AIO */
......@@ -732,7 +721,7 @@ static void raw_close(BlockDriverState *bs)
if (s->fd >= 0) {
close(s->fd);
s->fd = -1;
#if defined(O_DIRECT) && !defined(QEMU_IMG)
#if defined(O_DIRECT)
if (s->aligned_buf != NULL)
qemu_free(s->aligned_buf);
#endif
......@@ -1002,7 +991,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
return 0;
}
#if defined(__linux__) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
#if defined(__linux__)
/* Note: we do not have a reliable method to detect if the floppy is
present. The current method is to try to open the floppy at every
......@@ -1052,14 +1041,6 @@ static int fd_open(BlockDriverState *bs)
s->fd_got_error = 0;
return 0;
}
#else
static int fd_open(BlockDriverState *bs)
{
return 0;
}
#endif
#if defined(__linux__)
static int raw_is_inserted(BlockDriverState *bs)
{
......
......@@ -22,14 +22,13 @@
* THE SOFTWARE.
*/
#include "qemu-common.h"
#ifndef QEMU_IMG
#include "qemu-timer.h"
#include "exec-all.h"
#endif
#include "block_int.h"
#include <assert.h>
#include <winioctl.h>
//#define WIN32_AIO
#define FTYPE_FILE 0
#define FTYPE_CD 1
#define FTYPE_HARDDISK 2
......@@ -100,10 +99,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
} else {
create_flags = OPEN_EXISTING;
}
#ifdef QEMU_IMG
overlapped = FILE_ATTRIBUTE_NORMAL;
#else
#ifdef WIN32_AIO
overlapped = FILE_FLAG_OVERLAPPED;
#else
overlapped = FILE_ATTRIBUTE_NORMAL;
#endif
if (flags & BDRV_O_DIRECT)
overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
......@@ -133,10 +132,12 @@ static int raw_pread(BlockDriverState *bs, int64_t offset,
ov.OffsetHigh = offset >> 32;
ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
if (!ret) {
#ifdef WIN32_AIO
ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
if (!ret)
return -EIO;
else
#endif
return ret_count;
}
return ret_count;
......@@ -155,17 +156,18 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
ov.OffsetHigh = offset >> 32;
ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
if (!ret) {
#ifdef WIN32_AIO
ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
if (!ret)
return -EIO;
else
#endif
return ret_count;
}
return ret_count;
}
#if 0
#ifndef QEMU_IMG
#ifdef WIN32_AIO
static void raw_aio_cb(void *opaque)
{
RawAIOCB *acb = opaque;
......@@ -181,7 +183,6 @@ static void raw_aio_cb(void *opaque)
acb->common.cb(acb->common.opaque, 0);
}
}
#endif
static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors,
......@@ -204,9 +205,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
acb->ov.OffsetHigh = offset >> 32;
acb->ov.hEvent = acb->hEvent;
acb->count = nb_sectors * 512;
#ifndef QEMU_IMG
qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
#endif
return acb;
}
......@@ -226,9 +225,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
qemu_aio_release(acb);
return NULL;
}
#ifdef QEMU_IMG
qemu_aio_release(acb);
#endif
return (BlockDriverAIOCB *)acb;
}
......@@ -248,15 +245,12 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
qemu_aio_release(acb);
return NULL;
}
#ifdef QEMU_IMG
qemu_aio_release(acb);
#endif
return (BlockDriverAIOCB *)acb;
}
static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
{
#ifndef QEMU_IMG
RawAIOCB *acb = (RawAIOCB *)blockacb;
BlockDriverState *bs = acb->common.bs;
BDRVRawState *s = bs->opaque;
......@@ -265,9 +259,8 @@ static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
/* XXX: if more than one async I/O it is not correct */
CancelIo(s->hfile);
qemu_aio_release(acb);
#endif
}
#endif /* #if 0 */
#endif /* #if WIN32_AIO */
static void raw_flush(BlockDriverState *bs)
{
......@@ -356,9 +349,7 @@ void qemu_aio_flush(void)
void qemu_aio_wait(void)
{
#ifndef QEMU_IMG
qemu_bh_poll();
#endif
}
BlockDriver bdrv_raw = {
......@@ -372,7 +363,7 @@ BlockDriver bdrv_raw = {
raw_create,
raw_flush,
#if 0
#ifdef WIN32_AIO
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
......@@ -458,10 +449,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
}
create_flags = OPEN_EXISTING;
#ifdef QEMU_IMG
overlapped = FILE_ATTRIBUTE_NORMAL;
#else
#ifdef WIN32_AIO
overlapped = FILE_FLAG_OVERLAPPED;
#else
overlapped = FILE_ATTRIBUTE_NORMAL;
#endif
if (flags & BDRV_O_DIRECT)
overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
......@@ -524,7 +515,7 @@ BlockDriver bdrv_host_device = {
NULL,
raw_flush,
#if 0
#ifdef WIN32_AIO
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
......
......@@ -22,9 +22,7 @@
* THE SOFTWARE.
*/
#include "qemu-common.h"
#ifndef QEMU_IMG
#include "console.h"
#endif
#include "block_int.h"
#ifdef _BSD
......@@ -922,7 +920,6 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
}
#ifndef QEMU_IMG
void bdrv_info(void)
{
BlockDriverState *bs;
......@@ -980,7 +977,6 @@ void bdrv_info_stats (void)
bs->rd_ops, bs->wr_ops);
}
}
#endif
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size)
......@@ -1203,31 +1199,6 @@ void bdrv_aio_cancel(BlockDriverAIOCB *acb)
/**************************************************************/
/* async block device emulation */
#ifdef QEMU_IMG
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
int ret;
ret = bdrv_read(bs, sector_num, buf, nb_sectors);
cb(opaque, ret);
return NULL;
}
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
int64_t sector_num, const uint8_t *buf, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
int ret;
ret = bdrv_write(bs, sector_num, buf, nb_sectors);
cb(opaque, ret);
return NULL;
}
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
{
}
#else
static void bdrv_aio_bh_cb(void *opaque)
{
BlockDriverAIOCBSync *acb = opaque;
......@@ -1273,7 +1244,6 @@ static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
qemu_bh_cancel(acb->bh);
qemu_aio_release(acb);
}
#endif /* !QEMU_IMG */
/**************************************************************/
/* sync block device emulation */
......@@ -1337,9 +1307,7 @@ void bdrv_init(void)
bdrv_register(&bdrv_vvfat);
bdrv_register(&bdrv_qcow2);
bdrv_register(&bdrv_parallels);
#ifndef _WIN32
bdrv_register(&bdrv_nbd);
#endif
qemu_aio_init();
}
......
......@@ -47,10 +47,8 @@ typedef struct QEMUSnapshotInfo {
bdrv_file_open()) */
#define BDRV_O_DIRECT 0x0020
#ifndef QEMU_IMG
void bdrv_info(void);
void bdrv_info_stats(void);
#endif
void bdrv_init(void);
BlockDriver *bdrv_find_format(const char *format_name);
......
......@@ -21,28 +21,27 @@
#include <errno.h>
#include <string.h>
#ifndef _WIN32
#include <sys/ioctl.h>
#endif
#ifdef __sun__
#include <sys/ioccom.h>
#endif
#include <ctype.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#if defined(QEMU_NBD)
extern int verbose;
#else
static int verbose = 0;
#endif
#include "qemu_socket.h"
//#define DEBUG_NBD
#ifdef DEBUG_NBD
#define TRACE(msg, ...) do { \
if (verbose) LOG(msg, ## __VA_ARGS__); \
LOG(msg, ## __VA_ARGS__); \
} while(0)
#else
#define TRACE(msg, ...) \
do { } while (0)
#endif
#define LOG(msg, ...) do { \
fprintf(stderr, "%s:%s():L%d: " msg "\n", \
......@@ -77,11 +76,14 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
ssize_t len;
if (do_read) {
len = read(fd, buffer + offset, size - offset);
len = recv(fd, buffer + offset, size - offset, 0);
} else {
len = write(fd, buffer + offset, size - offset);
len = send(fd, buffer + offset, size - offset, 0);
}
if (len == -1)
errno = socket_error();
/* recoverable error */
if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
continue;
......@@ -108,7 +110,6 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
int s;
struct in_addr in;
struct sockaddr_in addr;
int serrno;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s == -1) {
......@@ -136,9 +137,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
return s;
error:
serrno = errno;
close(s);
errno = serrno;
closesocket(s);
return -1;
}
......@@ -147,7 +146,6 @@ int tcp_socket_incoming(const char *address, uint16_t port)
int s;
struct in_addr in;
struct sockaddr_in addr;
int serrno;
int opt;
s = socket(PF_INET, SOCK_STREAM, 0);
......@@ -185,17 +183,15 @@ int tcp_socket_incoming(const char *address, uint16_t port)
return s;
error:
serrno = errno;
close(s);
errno = serrno;
closesocket(s);
return -1;
}
#ifndef _WIN32
int unix_socket_incoming(const char *path)
{
int s;
struct sockaddr_un addr;
int serrno;
s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1) {
......@@ -216,9 +212,7 @@ int unix_socket_incoming(const char *path)
return s;
error:
serrno = errno;
close(s);
errno = serrno;
closesocket(s);
return -1;
}
......@@ -226,7 +220,6 @@ int unix_socket_outgoing(const char *path)
{
int s;
struct sockaddr_un addr;
int serrno;
s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1) {
......@@ -243,12 +236,23 @@ int unix_socket_outgoing(const char *path)
return s;
error:
serrno = errno;
close(s);
errno = serrno;
closesocket(s);
return -1;
}
#else
int unix_socket_incoming(const char *path)
{
errno = ENOTSUP;
return -1;
}
int unix_socket_outgoing(const char *path)
{
errno = ENOTSUP;
return -1;
}
#endif
/* Basic flow
......@@ -337,6 +341,7 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
return 0;
}
#ifndef _WIN32
int nbd_init(int fd, int csock, off_t size, size_t blocksize)
{
TRACE("Setting block size to %lu", (unsigned long)blocksize);
......@@ -410,6 +415,25 @@ int nbd_client(int fd, int csock)
errno = serrno;
return ret;
}
#else
int nbd_init(int fd, int csock, off_t size, size_t blocksize)
{
errno = ENOTSUP;
return -1;
}
int nbd_disconnect(int fd)
{
errno = ENOTSUP;
return -1;
}
int nbd_client(int fd, int csock)
{
errno = ENOTSUP;
return -1;
}
#endif
int nbd_send_request(int csock, struct nbd_request *request)
{
......
......@@ -45,6 +45,8 @@
#include <malloc.h>
#endif
#include "qemu_socket.h"
#if defined(_WIN32)
void *qemu_memalign(size_t alignment, size_t size)
{
......@@ -283,3 +285,28 @@ int qemu_gettimeofday(qemu_timeval *tp)
return 0;
}
#endif /* _WIN32 */
#ifdef _WIN32
void socket_set_nonblock(int fd)
{
unsigned long opt = 1;
ioctlsocket(fd, FIONBIO, &opt);