qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v4 2/3] Extract code to nbd_setup function to be use


From: Chunyan Liu
Subject: [Qemu-devel] [PATCH v4 2/3] Extract code to nbd_setup function to be used for many purposes
Date: Fri, 2 Dec 2011 23:27:55 +0800

According to Stefan's suggestion, will loop over /dev/nbd%d to do "qemu-nbd -f
disk.img", if fails, try next device. To make "qemu-nbd -c" and "qemu-nbd -f"
share codes as more as possible, extract the shared codes to a function
nbd_setup(). Current qemu-nbd functions work well still. 

Signed-off-by: Chunyan Liu <address@hidden>
---
 qemu-nbd.c |  300 ++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 159 insertions(+), 141 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 291cba2..83ae30f 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -42,6 +42,18 @@ static int verbose;
 static char *device;
 static char *srcpath;
 static char *sockpath;
+static int is_sockpath_option;
+static int sigterm_fd[2];
+static off_t dev_offset;
+static uint32_t nbdflags;
+static bool disconnect;
+static const char *bindto = "0.0.0.0";
+static int port = NBD_DEFAULT_PORT;
+static int li;
+static int flags = BDRV_O_RDWR;
+static int partition = -1;
+static int shared = 1;
+static int persistent;
 
 static void usage(const char *name)
 {
@@ -171,9 +183,7 @@ static int find_partition(BlockDriverState *bs, int 
partition,
 static void termsig_handler(int signum)
 {
     static int sigterm_reported;
-    if (!sigterm_reported) {
-        sigterm_reported = (write(sigterm_wfd, "", 1) == 1);
-    }
+    sigterm_reported = (write(sigterm_wfd, "", 1) == 1);
 }
 
 static void *show_parts(void *arg)
@@ -244,18 +254,152 @@ out:
     return (void *) EXIT_FAILURE;
 }
 
-int main(int argc, char **argv)
+static int nbd_setup(void)
 {
     BlockDriverState *bs;
-    off_t dev_offset = 0;
     off_t offset = 0;
-    uint32_t nbdflags = 0;
-    bool disconnect = false;
-    const char *bindto = "0.0.0.0";
-    int port = NBD_DEFAULT_PORT;
     struct sockaddr_in addr;
     socklen_t addr_len = sizeof(addr);
     off_t fd_size;
+    uint8_t *data;
+    fd_set fds;
+    int *sharing_fds;
+    int fd;
+    int i;
+    int nb_fds = 0;
+    int max_fd;
+    pthread_t client_thread;
+    int ret;
+
+    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 (sockpath == NULL) {
+            sockpath = g_malloc(128);
+            snprintf(sockpath, 128, SOCKET_PATH, basename(device));
+        }
+    }
+
+    bs = bdrv_new("hda");
+    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
+        errno = -ret;
+        err(EXIT_FAILURE, "Failed to bdrv_open '%s'", srcpath);
+    }
+
+    fd_size = bs->total_sectors * 512;
+
+    if (partition != -1 &&
+        find_partition(bs, partition, &dev_offset, &fd_size)) {
+        err(EXIT_FAILURE, "Could not find partition %d", partition);
+    }
+
+    sharing_fds = g_malloc((shared + 1) * sizeof(int));
+
+    if (sockpath) {
+        sharing_fds[0] = unix_socket_incoming(sockpath);
+    } else {
+        sharing_fds[0] = tcp_socket_incoming(bindto, port);
+    }
+
+    if (sharing_fds[0] == -1)
+        return 1;
+
+    if (device) {
+        int ret;
+
+        ret = pthread_create(&client_thread, NULL, nbd_client_thread, &fd);
+        if (ret != 0) {
+            errx(EXIT_FAILURE, "Failed to create client thread: %s",
+                 strerror(ret));
+        }
+    } else {
+        /* Shut up GCC warnings.  */
+        memset(&client_thread, 0, sizeof(client_thread));
+    }
+
+    max_fd = sharing_fds[0];
+    nb_fds++;
+
+    data = qemu_blockalign(bs, NBD_BUFFER_SIZE);
+    if (data == NULL) {
+        errx(EXIT_FAILURE, "Cannot allocate data buffer");
+    }
+
+    do {
+        FD_ZERO(&fds);
+        FD_SET(sigterm_fd[0], &fds);
+        for (i = 0; i < nb_fds; i++)
+            FD_SET(sharing_fds[i], &fds);
+
+        do {
+            ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
+        } while (ret == -1 && errno == EINTR);
+        if (ret == -1 || FD_ISSET(sigterm_fd[0], &fds)) {
+            int sigbuf[1];
+            read(sigterm_fd[0], sigbuf, 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, nbdflags, 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(sharing_fds[nb_fds], fd_size, nbdflags) != 
-1) {
+                        if (sharing_fds[nb_fds] > max_fd)
+                            max_fd = sharing_fds[nb_fds];
+                        nb_fds++;
+                }
+            }
+        }
+    } while (persistent || nb_fds > 1);
+    qemu_vfree(data);
+
+    close(sharing_fds[0]);
+    g_free(sharing_fds);
+    if (sockpath) {
+        unlink(sockpath);
+    }
+    if (bs) {
+        bdrv_delete(bs);
+    }
+    if (!is_sockpath_option) {
+        sockpath = NULL;
+    }
+
+    if (device) {
+        void *ret;
+        pthread_join(client_thread, &ret);
+        return (ret != NULL) ? EXIT_FAILURE : EXIT_SUCCESS;
+    } else {
+        return EXIT_SUCCESS;
+    }
+}
+
+int main(int argc, char **argv)
+{
     const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
     struct option lopt[] = {
         { "help", 0, NULL, 'h' },
@@ -277,27 +421,14 @@ int main(int argc, char **argv)
     };
     int ch;
     int opt_ind = 0;
-    int li;
     char *end;
-    int flags = BDRV_O_RDWR;
-    int partition = -1;
-    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;
-    int persistent = 0;
-    pthread_t client_thread;
+    int ret = 0;
 
     /* The client thread uses SIGTERM to interrupt the server.  A signal
      * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
      */
     struct sigaction sa_sigterm;
-    int sigterm_fd[2];
+
     if (qemu_pipe(sigterm_fd) == -1) {
         err(EXIT_FAILURE, "Error setting up communication pipe");
     }
@@ -352,6 +483,7 @@ int main(int argc, char **argv)
             sockpath = optarg;
             if (sockpath[0] != '/')
                 errx(EXIT_FAILURE, "socket path must be absolute\n");
+            is_sockpath_option = 1;
             break;
         case 'd':
             disconnect = true;
@@ -395,6 +527,7 @@ int main(int argc, char **argv)
     }
 
     if (disconnect) {
+        int fd;
         fd = open(argv[optind], O_RDWR);
         if (fd == -1)
             err(EXIT_FAILURE, "Cannot open %s", argv[optind]);
@@ -411,7 +544,6 @@ int main(int argc, char **argv)
     if (device && !verbose) {
         int stderr_fd[2];
         pid_t pid;
-        int ret;
 
         if (qemu_pipe(stderr_fd) == -1) {
             err(EXIT_FAILURE, "Error setting up communication pipe");
@@ -460,125 +592,11 @@ 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 (sockpath == NULL) {
-            sockpath = g_malloc(128);
-            snprintf(sockpath, 128, SOCKET_PATH, basename(device));
-        }
-    }
-
     bdrv_init();
     atexit(bdrv_close_all);
-
-    bs = bdrv_new("hda");
     srcpath = argv[optind];
-    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
-        errno = -ret;
-        err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
-    }
-
-    fd_size = bs->total_sectors * 512;
-
-    if (partition != -1 &&
-        find_partition(bs, partition, &dev_offset, &fd_size)) {
-        err(EXIT_FAILURE, "Could not find partition %d", partition);
-    }
-
-    sharing_fds = g_malloc((shared + 1) * sizeof(int));
-
-    if (sockpath) {
-        sharing_fds[0] = unix_socket_incoming(sockpath);
-    } else {
-        sharing_fds[0] = tcp_socket_incoming(bindto, port);
-    }
-
-    if (sharing_fds[0] == -1)
-        return 1;
-
-    if (device) {
-        int ret;
-
-        ret = pthread_create(&client_thread, NULL, nbd_client_thread, &fd);
-        if (ret != 0) {
-            errx(EXIT_FAILURE, "Failed to create client thread: %s",
-                 strerror(ret));
-        }
-    } else {
-        /* Shut up GCC warnings.  */
-        memset(&client_thread, 0, sizeof(client_thread));
-    }
-
-    max_fd = sharing_fds[0];
-    nb_fds++;
-
-    data = qemu_blockalign(bs, NBD_BUFFER_SIZE);
-    if (data == NULL) {
-        errx(EXIT_FAILURE, "Cannot allocate data buffer");
-    }
-
-    do {
-        FD_ZERO(&fds);
-        FD_SET(sigterm_fd[0], &fds);
-        for (i = 0; i < nb_fds; i++)
-            FD_SET(sharing_fds[i], &fds);
-
-        do {
-            ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
-        } while (ret == -1 && errno == EINTR);
-        if (ret == -1 || FD_ISSET(sigterm_fd[0], &fds)) {
-            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, nbdflags, 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(sharing_fds[nb_fds], fd_size, nbdflags) != 
-1) {
-                        if (sharing_fds[nb_fds] > max_fd)
-                            max_fd = sharing_fds[nb_fds];
-                        nb_fds++;
-                }
-            }
-        }
-    } while (persistent || nb_fds > 1);
-    qemu_vfree(data);
 
-    close(sharing_fds[0]);
-    g_free(sharing_fds);
-    if (sockpath) {
-        unlink(sockpath);
-    }
+    ret = nbd_setup();
 
-    if (device) {
-        void *ret;
-        pthread_join(client_thread, &ret);
-        exit(ret != NULL);
-    } else {
-        exit(EXIT_SUCCESS);
-    }
+    exit(ret);
 }
-- 
1.7.3.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]