From: Paolo Bonzini <pbonzini@redhat.com>
To: Chunyan Liu <cyliu@suse.com>
Cc: stefanha@gmail.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH][resend] Add -f option to qemu-nbd
Date: Wed, 18 Jan 2012 11:51:31 +0100 [thread overview]
Message-ID: <4F16A433.8000405@redhat.com> (raw)
In-Reply-To: <1326876486-13995-1-git-send-email-cyliu@suse.com>
On 01/18/2012 09:48 AM, Chunyan Liu wrote:
> Stefan, could you help commit it if it's OK? Thanks.
> Same as in thread:
> http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg01083.html
> but rebase it to latest code.
>
> Add -f option to qemu-nbd to find a free nbd device for user and connect
> disk image to that device.
Hi Chunyan,
I'm now the NBD maintainer so I can take care of the patch. There are
still a couple of nits.
The main problem is that the device name is never printed, which
requires some imagination on part of the user. :)
This pretty much requires that you set "verbose = 1" together with -f.
This disables daemonization, unfortunately, but there isn't really any
better way to do so. I'm inclined towards removing daemonization
altogether from 1.1; other opinions are welcome.
Anyhow, please set "verbose = 1" and change the help text for -c/-v from
" -c, --connect=DEV connect FILE to the local NBD device DEV\n"
" -v, --verbose display extra debugging information\n"
to
" -c, --connect=DEV connect FILE to the local NBD device DEV\n"
" and run in the background\n"
" -v, --verbose with -c, display extra information and\n"
" do not run in the background\n"
Since a respin is required, there are a couple of other comments inline.
> syntax: qemu-nbd -f disk.img
> ---
> qemu-nbd.c | 76 ++++++++++++++++++++++++++++++++++++++++++-----------------
> 1 files changed, 54 insertions(+), 22 deletions(-)
>
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index eb61c33..f4c1437 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -33,7 +33,7 @@
> #include<libgen.h>
> #include<pthread.h>
>
> -#define SOCKET_PATH "/var/lock/qemu-nbd-%s"
> +#define SOCKET_PATH "/var/lock/qemu-nbd-%d"
>
> static NBDExport *exp;
> static int verbose;
> @@ -55,12 +55,13 @@ static void usage(const char *name)
> " -o, --offset=OFFSET offset into the image\n"
> " -b, --bind=IFACE interface to bind to (default `0.0.0.0')\n"
> " -k, --socket=PATH path to the unix socket\n"
> -" (default '"SOCKET_PATH"')\n"
> +" (default /var/lock/qemu-nbd-PID)\n"
> " -r, --read-only export read-only\n"
> " -P, --partition=NUM only expose partition NUM\n"
> " -s, --snapshot use snapshot file\n"
> " -n, --nocache disable host cache\n"
> " -c, --connect=DEV connect FILE to the local NBD device DEV\n"
> +" -f, --find find a free NBD device and connect FILE to it\n"
> " -d, --disconnect disconnect the specified device\n"
> " -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
> " -t, --persistent don't exit on the last connection\n"
> @@ -69,7 +70,7 @@ static void usage(const char *name)
> " -V, --version output version information and exit\n"
> "\n"
> "Report bugs to<anthony@codemonkey.ws>\n"
> - , name, NBD_DEFAULT_PORT, "DEVICE");
> + , name, NBD_DEFAULT_PORT);
> }
>
> static void version(const char *name)
> @@ -194,7 +195,8 @@ static void *show_parts(void *arg)
>
> static void *nbd_client_thread(void *arg)
> {
> - int fd = *(int *)arg;
> + int fd = -1;
> + int find = *(int *)arg;
> off_t size;
> size_t blocksize;
> uint32_t nbdflags;
> @@ -213,9 +215,42 @@ static void *nbd_client_thread(void *arg)
> goto out;
> }
>
> - ret = nbd_init(fd, sock, nbdflags, size, blocksize);
> - if (ret == -1) {
> - goto out;
> + if (!find) {
> + fd = open(device, O_RDWR);
> + if (fd == -1) {
> + fprintf(stderr, "Failed to open %s\n", device);
> + goto out;
> + }
> +
> + ret = nbd_init(fd, sock, nbdflags, size, blocksize);
> + if (ret == -1) {
> + goto out;
> + }
> + } else {
> + int i = 0;
> + int max_nbd = 16;
> + device = g_malloc(64);
> +
> + for (i = 0; i< max_nbd; i++) {
> + snprintf(device, 64, "/dev/nbd%d", i);
> + fd = open(device, O_RDWR);
> + if (fd == -1) {
> + continue;
> + }
> +
> + if (nbd_init(fd, sock, nbdflags, size, blocksize) == -1) {
> + close(fd);
> + continue;
> + }
> +
> + break;
> + }
> +
> + if (i>= max_nbd) {
> + fprintf(stderr, "Fail to find a free nbd device\n");
> + g_free(device);
> + goto out;
Just use errx(EXIT_FAILURE, "Could not find a free NBD device.") here.
> + }
> }
>
> /* update partition table */
> @@ -275,7 +310,7 @@ int main(int argc, char **argv)
> const char *bindto = "0.0.0.0";
> int port = NBD_DEFAULT_PORT;
> off_t fd_size;
> - const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
> + const char *sopt = "hVb:o:p:rsnP:c:dvk:e:tf";
> struct option lopt[] = {
> { "help", 0, NULL, 'h' },
> { "version", 0, NULL, 'V' },
> @@ -292,6 +327,7 @@ int main(int argc, char **argv)
> { "shared", 1, NULL, 'e' },
> { "persistent", 0, NULL, 't' },
> { "verbose", 0, NULL, 'v' },
> + { "find", 0, NULL, 'f'},
> { NULL, 0, NULL, 0 }
> };
> int ch;
> @@ -303,6 +339,7 @@ int main(int argc, char **argv)
> int ret;
> int fd;
> int persistent = 0;
> + int find = 0;
> pthread_t client_thread;
>
> /* The client thread uses SIGTERM to interrupt the server. A signal
> @@ -380,6 +417,9 @@ int main(int argc, char **argv)
> case 'v':
> verbose = 1;
> break;
> + case 'f':
> + find = 1;
> + break;
> case 'V':
> version(argv[0]);
> exit(0);
> @@ -414,7 +454,7 @@ int main(int argc, char **argv)
> return 0;
> }
Please give an error here if "device && find" ("The -f option is
incompatible with -c").
> - if (device&& !verbose) {
> + if ((device || find)&& !verbose) {
> int stderr_fd[2];
> pid_t pid;
> int ret;
> @@ -466,18 +506,10 @@ int main(int argc, char **argv)
> }
> }
>
> - if (device) {
> - /* Open before spawning new threads. In the future, we may
> - * drop privileges after opening.
> - */
> - fd = open(device, O_RDWR);
> - if (fd == -1) {
> - err(EXIT_FAILURE, "Failed to open %s", device);
> - }
> -
> + if (device || find) {
> if (sockpath == NULL) {
> sockpath = g_malloc(128);
> - snprintf(sockpath, 128, SOCKET_PATH, basename(device));
> + snprintf(sockpath, 128, SOCKET_PATH, getpid());
> }
> }
>
> @@ -510,10 +542,10 @@ int main(int argc, char **argv)
> return 1;
> }
>
> - if (device) {
> + if (device || find) {
> int ret;
>
> - ret = pthread_create(&client_thread, NULL, nbd_client_thread,&fd);
> + ret = pthread_create(&client_thread, NULL, nbd_client_thread,&find);
Just pass NULL here and test "device != NULL" in the nbd_client_thread.
> if (ret != 0) {
> errx(EXIT_FAILURE, "Failed to create client thread: %s",
> strerror(ret));
> @@ -536,7 +568,7 @@ int main(int argc, char **argv)
> unlink(sockpath);
> }
>
> - if (device) {
> + if (device || find) {
> void *ret;
> pthread_join(client_thread,&ret);
> exit(ret != NULL);
Thanks,
Paolo
next prev parent reply other threads:[~2012-01-18 10:51 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-18 8:48 [Qemu-devel] [PATCH][resend] Add -f option to qemu-nbd Chunyan Liu
2012-01-18 10:51 ` Paolo Bonzini [this message]
2012-01-19 8:52 ` Chunyan Liu
2012-01-19 9:03 ` Paolo Bonzini
2012-01-18 10:56 ` Michael Tokarev
2012-01-18 11:26 ` Paolo Bonzini
2012-01-19 9:16 ` Chunyan Liu
2012-01-19 9:34 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F16A433.8000405@redhat.com \
--to=pbonzini@redhat.com \
--cc=cyliu@suse.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).