[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH][resend] Add -f option to qemu-nbd
From: |
Chunyan Liu |
Subject: |
Re: [Qemu-devel] [PATCH][resend] Add -f option to qemu-nbd |
Date: |
Thu, 19 Jan 2012 16:52:34 +0800 |
Thanks, Paolo!
2012/1/18 Paolo Bonzini <address@hidden>:
> 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.
Currently, to print the connected device name, we can also change code a little
as following: ("-v" can still indicate working on background or not. )
@@ -256,10 +256,9 @@ static void *nbd_client_thread(void *arg)
/* update partition table */
pthread_create(&show_parts_thread, NULL, show_parts, NULL);
- if (verbose) {
- fprintf(stderr, "NBD device %s is now connected to %s\n",
+ fprintf(stderr, "NBD device %s is now connected to %s\n",
device, srcpath);
- } else {
+ if (!verbose) {
/* Close stderr so that the qemu-nbd process exits. */
dup2(STDOUT_FILENO, STDERR_FILENO);
}
>
> 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<address@hidden>\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.
Using errx() will skip kill(getpid(), SIGTERM) and exit directly;
I'm not sure if that will cause problem?
>
>> + }
>> }
>>
>> /* 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
>