Allow to share a disk image via nbd, by Laurent Vivier.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4837 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2008-07-03 12:45:02 +00:00
parent 2f7264888a
commit 3b05a8e91b
2 changed files with 78 additions and 22 deletions

View File

@ -55,6 +55,7 @@ static void usage(const char *name)
" -n, --nocache disable host cache\n"
" -c, --connect=DEV connect FILE to the local NBD device DEV\n"
" -d, --disconnect disconnect the specified device\n"
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
" -v, --verbose display extra debugging information\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n"
@ -182,14 +183,13 @@ int main(int argc, char **argv)
bool disconnect = false;
const char *bindto = "0.0.0.0";
int port = 1024;
int sock, csock;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
off_t fd_size;
char *device = NULL;
char *socket = NULL;
char sockpath[128];
const char *sopt = "hVbo:p:rsnP:c:dvk:";
const char *sopt = "hVbo:p:rsnP:c:dvk:e:";
struct option lopt[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
@ -203,6 +203,7 @@ int main(int argc, char **argv)
{ "disconnect", 0, 0, 'd' },
{ "snapshot", 0, 0, 's' },
{ "nocache", 0, 0, 'n' },
{ "shared", 1, 0, 'e' },
{ "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
@ -212,9 +213,15 @@ int main(int argc, char **argv)
char *end;
int flags = 0;
int partition = -1;
int fd;
int ret;
int shared = 1;
uint8_t *data;
fd_set fds;
int *sharing_fds;
int fd;
int i;
int nb_fds = 0;
int max_fd;
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
switch (ch) {
@ -267,6 +274,15 @@ int main(int argc, char **argv)
case 'c':
device = optarg;
break;
case 'e':
shared = strtol(optarg, &end, 0);
if (*end) {
errx(EINVAL, "Invalid shared device number '%s'", optarg);
}
if (shared < 1) {
errx(EINVAL, "Shared device number must be greater than 0\n");
}
break;
case 'v':
verbose = 1;
break;
@ -320,8 +336,10 @@ int main(int argc, char **argv)
errx(errno, "Could not find partition %d", partition);
if (device) {
pid_t pid;
if (!verbose)
pid_t pid;
int sock;
if (!verbose)
daemon(0, 0); /* detach client and server */
if (socket == NULL) {
@ -384,33 +402,69 @@ int main(int argc, char **argv)
/* children */
}
sharing_fds = qemu_malloc((shared + 1) * sizeof(int));
if (sharing_fds == NULL)
errx(ENOMEM, "Cannot allocate sharing fds");
if (socket) {
sock = unix_socket_incoming(socket);
sharing_fds[0] = unix_socket_incoming(socket);
} else {
sock = tcp_socket_incoming(bindto, port);
sharing_fds[0] = tcp_socket_incoming(bindto, port);
}
if (sock == -1)
return 1;
csock = accept(sock,
(struct sockaddr *)&addr,
&addr_len);
if (csock == -1)
return 1;
/* new fd_size is calculated by find_partition */
if (nbd_negotiate(bs, csock, fd_size) == -1)
if (sharing_fds[0] == -1)
return 1;
max_fd = sharing_fds[0];
nb_fds++;
data = qemu_memalign(512, NBD_BUFFER_SIZE);
while (nbd_trip(bs, csock, fd_size, dev_offset, &offset, readonly,
data, NBD_BUFFER_SIZE) == 0);
if (data == NULL)
errx(ENOMEM, "Cannot allocate data buffer");
do {
FD_ZERO(&fds);
for (i = 0; i < nb_fds; i++)
FD_SET(sharing_fds[i], &fds);
ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
if (ret == -1)
break;
if (FD_ISSET(sharing_fds[0], &fds))
ret--;
for (i = 1; i < nb_fds && ret; i++) {
if (FD_ISSET(sharing_fds[i], &fds)) {
if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset,
&offset, readonly, data, NBD_BUFFER_SIZE) != 0) {
close(sharing_fds[i]);
nb_fds--;
sharing_fds[i] = sharing_fds[nb_fds];
i--;
}
ret--;
}
}
/* new connection ? */
if (FD_ISSET(sharing_fds[0], &fds)) {
if (nb_fds < shared + 1) {
sharing_fds[nb_fds] = accept(sharing_fds[0],
(struct sockaddr *)&addr,
&addr_len);
if (sharing_fds[nb_fds] != -1 &&
nbd_negotiate(bs, sharing_fds[nb_fds], fd_size) != -1) {
if (sharing_fds[nb_fds] > max_fd)
max_fd = sharing_fds[nb_fds];
nb_fds++;
}
}
}
} while (nb_fds > 1);
qemu_free(data);
close(csock);
close(sock);
close(sharing_fds[0]);
bdrv_close(bs);
qemu_free(sharing_fds);
if (socket)
unlink(socket);

View File

@ -34,6 +34,8 @@ Export Qemu disk image using NBD protocol.
connect FILE to NBD device DEV
@item -d, --disconnect
disconnect the specified device
@item -e, --shared=NUM
device can be shared by NUM clients (default '1')
@item -v, --verbose
display extra debugging information
@item -h, --help