All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
@ 2009-06-17 21:22 Jean-Christophe Dubois
  2009-06-17 21:51 ` malc
  2009-06-17 21:54 ` Anthony Liguori
  0 siblings, 2 replies; 12+ messages in thread
From: Jean-Christophe Dubois @ 2009-06-17 21:22 UTC (permalink / raw)
  To: qemu-devel

Some system calls are now requiring to have their return value checked.

Without this a warning is emitted and in the case a qemu an error is
triggered as qemu is considering warnings as errors.

For example:

block/cow.c: In function ‘cow_create’:
block/cow.c:251: error: ignoring return value of ‘write’, declared with
attribute warn_unused_result
block/cow.c:253: error: ignoring return value of ‘ftruncate’, declared
with attribute warn_unused_result

This is an attempt at removing all these warnings to allow a clean
compilation with up to date compilers/distributions.

The second version fixes an error detected by Stuart Brady as well
as some coding style issues. Note however that some of the
modified files don't follow the qemu coding style (using tabs
instead of spaces).

The Third version add one ftruncate() system call error handling that
was missing from V2 (in block/vvfat.c).

The Fourth version is correctly handling EINTR error on read/write
system calls. read/write calls are replaced by qemu_read/qemu_write
functions that are handling EINTR and incomplete read/write under
the cover.

Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net>
---
 block.c           |    3 +-
 block/bochs.c     |    3 +-
 block/cow.c       |   12 +++++++++-
 block/qcow.c      |   22 +++++++++++++++-----
 block/qcow2.c     |   37 ++++++++++++++++++++++++++++-------
 block/raw-posix.c |    9 +++++--
 block/vmdk.c      |   54 +++++++++++++++++++++++++++++++++++-----------------
 block/vvfat.c     |   24 ++++++++++++++++------
 linux-user/mmap.c |    7 ++++-
 linux-user/path.c |    6 ++++-
 osdep.c           |    5 +++-
 qemu-common.h     |   31 ++++++++++++++++++++++++++++++
 slirp/misc.c      |    4 ++-
 usb-linux.c       |    3 +-
 vl.c              |   14 +++++++++---
 15 files changed, 177 insertions(+), 57 deletions(-)

diff --git a/block.c b/block.c
index aca5a6d..c78d66a 100644
--- a/block.c
+++ b/block.c
@@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
             snprintf(backing_filename, sizeof(backing_filename),
                      "%s", filename);
         else
-            realpath(filename, backing_filename);
+            if (!realpath(filename, backing_filename))
+                return -1;
 
         bdrv_qcow2 = bdrv_find_format("qcow2");
         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
diff --git a/block/bochs.c b/block/bochs.c
index bac81c4..1fbce9e 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
     // read in bitmap for current extent
     lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
 
-    read(s->fd, &bitmap_entry, 1);
+    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
+        return -1; // not allocated
 
     if (!((bitmap_entry >> (extent_offset % 8)) & 1))
     {
diff --git a/block/cow.c b/block/cow.c
index 84818f1..d8cd1df 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -248,11 +248,19 @@ static int cow_create(const char *filename, QEMUOptionParameter *options)
     }
     cow_header.sectorsize = cpu_to_be32(512);
     cow_header.size = cpu_to_be64(image_sectors * 512);
-    write(cow_fd, &cow_header, sizeof(cow_header));
+    if (qemu_write(cow_fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header))
+        goto fail;
+
     /* resize to include at least all the bitmap */
-    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
+    if (ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)))
+        goto fail;
+
     close(cow_fd);
     return 0;
+
+fail:
+    close(cow_fd);
+    return -1;
 }
 
 static void cow_flush(BlockDriverState *bs)
diff --git a/block/qcow.c b/block/qcow.c
index 55a68a6..5e50db8 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -801,17 +801,27 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options)
     }
 
     /* write all the data */
-    write(fd, &header, sizeof(header));
-    if (backing_file) {
-        write(fd, backing_file, backing_filename_len);
-    }
-    lseek(fd, header_size, SEEK_SET);
+    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
+        goto fail;
+
+    if (backing_file)
+        if (qemu_write(fd, backing_file, backing_filename_len) != backing_filename_len)
+            goto fail;
+
+    if (lseek(fd, header_size, SEEK_SET) == -1)
+        goto fail;
     tmp = 0;
     for(i = 0;i < l1_size; i++) {
-        write(fd, &tmp, sizeof(tmp));
+        if (qemu_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            goto fail;
     }
+
     close(fd);
     return 0;
+
+fail:
+    close(fd);
+    return -1;
 }
 
 static int qcow_make_empty(BlockDriverState *bs)
diff --git a/block/qcow2.c b/block/qcow2.c
index 9acbddf..fab3c7c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -742,7 +742,9 @@ static int qcow_create2(const char *filename, int64_t total_size,
         ref_clusters * s->cluster_size);
 
     /* write all the data */
-    write(fd, &header, sizeof(header));
+    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
+        goto fail;
+
     if (backing_file) {
         if (backing_format_len) {
             char zero[16];
@@ -751,29 +753,48 @@ static int qcow_create2(const char *filename, int64_t total_size,
             memset(zero, 0, sizeof(zero));
             cpu_to_be32s(&ext_bf.magic);
             cpu_to_be32s(&ext_bf.len);
-            write(fd, &ext_bf, sizeof(ext_bf));
-            write(fd, backing_format, backing_format_len);
+            if (qemu_write(fd, &ext_bf, sizeof(ext_bf)) != sizeof(ext_bf))
+                goto fail;
+
+            if (qemu_write(fd, backing_format, backing_format_len) != backing_format_len)
+                goto fail;
+
             if (d>0) {
-                write(fd, zero, d);
+                if (qemu_write(fd, zero, d) != d)
+                    goto fail;
             }
         }
-        write(fd, backing_file, backing_filename_len);
+        if (qemu_write(fd, backing_file, backing_filename_len) != backing_filename_len)
+            goto fail;
     }
     lseek(fd, s->l1_table_offset, SEEK_SET);
     tmp = 0;
     for(i = 0;i < l1_size; i++) {
-        write(fd, &tmp, sizeof(tmp));
+        if (qemu_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            goto fail;
     }
     lseek(fd, s->refcount_table_offset, SEEK_SET);
-    write(fd, s->refcount_table, s->cluster_size);
+    if (qemu_write(fd, s->refcount_table, s->cluster_size) != s->cluster_size)
+        goto fail;
 
     lseek(fd, s->refcount_block_offset, SEEK_SET);
-    write(fd, s->refcount_block, ref_clusters * s->cluster_size);
+    if (qemu_write(fd, s->refcount_block, ref_clusters * s->cluster_size) != ref_clusters * s->cluster_size)
+        goto fail;
 
     qemu_free(s->refcount_table);
+    s->refcount_table = NULL;
     qemu_free(s->refcount_block);
+    s->refcount_block = NULL;
     close(fd);
     return 0;
+
+fail:
+    qemu_free(s->refcount_table);
+    s->refcount_table = NULL;
+    qemu_free(s->refcount_block);
+    s->refcount_block = NULL;
+    close(fd);
+    return -1;
 }
 
 static int qcow_create(const char *filename, QEMUOptionParameter *options)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index fa1a394..47e0d15 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -558,7 +558,8 @@ static void aio_signal_handler(int signum)
     if (posix_aio_state) {
         char byte = 0;
 
-        write(posix_aio_state->wfd, &byte, sizeof(byte));
+        if (qemu_write(posix_aio_state->wfd, &byte, sizeof(byte)) != sizeof(byte))
+            fprintf(stderr, "failed to write to posix_aio_state\n");
     }
 
     qemu_service_io();
@@ -838,6 +839,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
     int64_t total_size = 0;
+    int ret = 0;
 
     /* Read out options */
     while (options && options->name) {
@@ -851,9 +853,10 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
               0644);
     if (fd < 0)
         return -EIO;
-    ftruncate(fd, total_size * 512);
+    if (ftruncate(fd, total_size * 512))
+        ret = -1;
     close(fd);
-    return 0;
+    return ret;
 }
 
 static void raw_flush(BlockDriverState *bs)
diff --git a/block/vmdk.c b/block/vmdk.c
index f21f02b..b53b047 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -221,23 +221,24 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file)
     /* read the header */
     if (lseek(p_fd, 0x0, SEEK_SET) == -1)
         goto fail;
-    if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE)
+    if (qemu_read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE)
         goto fail;
 
     /* write the header */
     if (lseek(snp_fd, 0x0, SEEK_SET) == -1)
         goto fail;
-    if (write(snp_fd, hdr, HEADER_SIZE) == -1)
+    if (qemu_write(snp_fd, hdr, HEADER_SIZE) == -1)
         goto fail;
 
     memset(&header, 0, sizeof(header));
     memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
 
-    ftruncate(snp_fd, header.grain_offset << 9);
+    if (ftruncate(snp_fd, header.grain_offset << 9))
+        goto fail;
     /* the descriptor offset = 0x200 */
     if (lseek(p_fd, 0x200, SEEK_SET) == -1)
         goto fail;
-    if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE)
+    if (qemu_read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE)
         goto fail;
 
     if ((p_name = strstr(p_desc,"CID")) != NULL) {
@@ -259,7 +260,7 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file)
     /* write the descriptor */
     if (lseek(snp_fd, 0x200, SEEK_SET) == -1)
         goto fail;
-    if (write(snp_fd, s_desc, strlen(s_desc)) == -1)
+    if (qemu_write(snp_fd, s_desc, strlen(s_desc)) == -1)
         goto fail;
 
     gd_offset = header.gd_offset * SECTOR_SIZE;     // offset of GD table
@@ -279,11 +280,11 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file)
     rgd_buf = qemu_malloc(gd_size);
     if (lseek(p_fd, rgd_offset, SEEK_SET) == -1)
         goto fail_rgd;
-    if (read(p_fd, rgd_buf, gd_size) != gd_size)
+    if (qemu_read(p_fd, rgd_buf, gd_size) != gd_size)
         goto fail_rgd;
     if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1)
         goto fail_rgd;
-    if (write(snp_fd, rgd_buf, gd_size) == -1)
+    if (qemu_write(snp_fd, rgd_buf, gd_size) == -1)
         goto fail_rgd;
     qemu_free(rgd_buf);
 
@@ -291,11 +292,11 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file)
     gd_buf = qemu_malloc(gd_size);
     if (lseek(p_fd, gd_offset, SEEK_SET) == -1)
         goto fail_gd;
-    if (read(p_fd, gd_buf, gd_size) != gd_size)
+    if (qemu_read(p_fd, gd_buf, gd_size) != gd_size)
         goto fail_gd;
     if (lseek(snp_fd, gd_offset, SEEK_SET) == -1)
         goto fail_gd;
-    if (write(snp_fd, gd_buf, gd_size) == -1)
+    if (qemu_write(snp_fd, gd_buf, gd_size) == -1)
         goto fail_gd;
     qemu_free(gd_buf);
 
@@ -771,22 +772,32 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
     header.check_bytes[3] = 0xa;
 
     /* write all the data */
-    write(fd, &magic, sizeof(magic));
-    write(fd, &header, sizeof(header));
+    if (qemu_write(fd, &magic, sizeof(magic)) != sizeof(magic))
+        goto fail;
 
-    ftruncate(fd, header.grain_offset << 9);
+    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
+        goto fail;
+
+    if (ftruncate(fd, header.grain_offset << 9))
+        goto fail;
 
     /* write grain directory */
-    lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
+    if (lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET) == -1)
+        goto fail;
+
     for (i = 0, tmp = header.rgd_offset + gd_size;
          i < gt_count; i++, tmp += gt_size)
-        write(fd, &tmp, sizeof(tmp));
+        if (qemu_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            goto fail;
 
     /* write backup grain directory */
-    lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
+    if (lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET) == -1)
+        goto fail;
+
     for (i = 0, tmp = header.gd_offset + gd_size;
          i < gt_count; i++, tmp += gt_size)
-        write(fd, &tmp, sizeof(tmp));
+        if (qemu_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            goto fail;
 
     /* compose the descriptor */
     real_filename = filename;
@@ -802,11 +813,18 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
              total_size / (int64_t)(63 * 16));
 
     /* write the descriptor */
-    lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
-    write(fd, desc, strlen(desc));
+    if (lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET) == -1)
+        goto fail;
+
+    if (qemu_write(fd, desc, strlen(desc)) != strlen(desc))
+        goto fail;
 
     close(fd);
     return 0;
+
+fail:
+    close(fd);
+    return -1;
 }
 
 static void vmdk_close(BlockDriverState *bs)
diff --git a/block/vvfat.c b/block/vvfat.c
index 1e37b9f..097c9f6 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2215,6 +2215,7 @@ static int commit_one_file(BDRVVVFATState* s,
     char* cluster = qemu_malloc(s->cluster_size);
     uint32_t i;
     int fd = 0;
+    int ret = 0;
 
     assert(offset < size);
     assert((offset % s->cluster_size) == 0);
@@ -2229,14 +2230,15 @@ static int commit_one_file(BDRVVVFATState* s,
 	return fd;
     }
     if (offset > 0)
-	if (lseek(fd, offset, SEEK_SET) != offset)
-	    return -3;
+        if (lseek(fd, offset, SEEK_SET) != offset) {
+            ret = -3;
+            goto fail;
+        }
 
     while (offset < size) {
 	uint32_t c1;
 	int rest_size = (size - offset > s->cluster_size ?
 		s->cluster_size : size - offset);
-	int ret;
 
 	c1 = modified_fat_get(s, c);
 
@@ -2247,19 +2249,27 @@ static int commit_one_file(BDRVVVFATState* s,
 	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
 
 	if (ret < 0)
-	    return ret;
+	    goto fail;
 
-	if (write(fd, cluster, rest_size) < 0)
-	    return -2;
+        if (qemu_write(fd, cluster, rest_size) != rest_size) {
+            ret = -2;
+            goto fail;
+        }
 
 	offset += rest_size;
 	c = c1;
     }
 
-    ftruncate(fd, size);
+    if (ftruncate(fd, size))
+        goto fail;
+
     close(fd);
 
     return commit_mappings(s, first_cluster, dir_index);
+
+fail:
+    close(fd);
+    return ret;
 }
 
 #ifdef DEBUG
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index aa22006..5a1b525 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -252,7 +252,8 @@ static int mmap_frag(abi_ulong real_start,
             mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
 
         /* read the corresponding file data */
-        pread(fd, g2h(start), end - start, offset);
+        if (pread(fd, g2h(start), end - start, offset) == -1)
+            return -1;
 
         /* put final protection */
         if (prot_new != (prot1 | PROT_WRITE))
@@ -469,7 +470,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
                                   -1, 0);
             if (retaddr == -1)
                 goto fail;
-            pread(fd, g2h(start), len, offset);
+            if (pread(fd, g2h(start), len, offset) == -1)
+                goto fail;
+                
             if (!(prot & PROT_WRITE)) {
                 ret = target_mprotect(start, len, prot);
                 if (ret != 0) {
diff --git a/linux-user/path.c b/linux-user/path.c
index 06b1f5f..fc5cd6e 100644
--- a/linux-user/path.c
+++ b/linux-user/path.c
@@ -45,8 +45,12 @@ static struct pathelem *new_entry(const char *root,
 {
     struct pathelem *new = malloc(sizeof(*new));
     new->name = strdup(name);
-    asprintf(&new->pathname, "%s/%s", root, name);
     new->num_entries = 0;
+    if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
+        free(new->name);
+        free(new);
+        new = NULL;
+    }
     return new;
 }
 
diff --git a/osdep.c b/osdep.c
index b300ba1..de0124e 100644
--- a/osdep.c
+++ b/osdep.c
@@ -160,7 +160,10 @@ static void *kqemu_vmalloc(size_t size)
         unlink(phys_ram_file);
     }
     size = (size + 4095) & ~4095;
-    ftruncate(phys_ram_fd, phys_ram_size + size);
+    if (ftruncate(phys_ram_fd, phys_ram_size + size)) {
+        fprintf(stderr, "Could not truncate phys_ram_file\n");
+        exit(1);
+    }
 #endif /* !(__OpenBSD__ || __FreeBSD__ || __DragonFly__) */
     ptr = mmap(NULL,
                size,
diff --git a/qemu-common.h b/qemu-common.h
index fdc3679..4b75018 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -136,6 +136,37 @@ char *qemu_strndup(const char *str, size_t size);
 
 void *get_mmap_addr(unsigned long size);
 
+static inline ssize_t qemu_read(int fd, void *buf, size_t count)
+{
+   int len = 0;
+
+   while (len < count) {
+       int tmp = read(fd, buf + len, count - len);
+
+       if (tmp > 0)
+           len += tmp;
+       else if (errno != EINTR)
+           return -1;
+   }
+
+   return count;
+}
+
+static inline ssize_t qemu_write(int fd, const void *buf, size_t count)
+{
+   int len = 0;
+
+   while (len < count) {
+       int tmp = write(fd, buf + len, count - len);
+
+       if (tmp > 0)
+           len += tmp;
+       else if (errno != EINTR)
+           return -1;
+   }
+
+   return count;
+}
 
 /* Error handling.  */
 
diff --git a/slirp/misc.c b/slirp/misc.c
index 1391d49..46d5a83 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -6,6 +6,7 @@
  */
 
 #include <slirp.h>
+#include <qemu-common.h>
 
 u_int curtime, time_fasttimo, last_slowtimo;
 
@@ -365,7 +366,8 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 			  snprintf(buff, sizeof(buff),
                                    "Error: execvp of %s failed: %s\n",
                                    argv[0], strerror(errno));
-			  write(2, buff, strlen(buff)+1);
+                          if (qemu_write(2, buff, strlen(buff)+1) != (strlen(buff)+1))
+                              lprint("Error: failed to write to stderr: %s\n", strerror(errno));
 		  }
 		close(0); close(1); close(2); /* XXX */
 		exit(1);
diff --git a/usb-linux.c b/usb-linux.c
index 67e4acd..d71c4b5 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1159,9 +1159,8 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f
              device_file);
     f = fopen(filename, "r");
     if (f) {
-        fgets(line, line_size, f);
+        if (fgets(line, line_size, f)) ret = 1;
         fclose(f);
-        ret = 1;
     } else {
         monitor_printf(mon, "husb: could not open %s\n", filename);
     }
diff --git a/vl.c b/vl.c
index 3242c23..5e2c314 100644
--- a/vl.c
+++ b/vl.c
@@ -3707,7 +3707,8 @@ static void qemu_event_increment(void)
     if (io_thread_fd == -1)
         return;
 
-    write(io_thread_fd, &byte, sizeof(byte));
+    if (qemu_write(io_thread_fd, &byte, sizeof(byte)) != sizeof(byte))
+        perror("Failed write");
 }
 
 static void qemu_event_read(void *opaque)
@@ -5785,7 +5786,8 @@ int main(int argc, char **argv, char **envp)
     if (pid_file && qemu_create_pidfile(pid_file) != 0) {
         if (daemonize) {
             uint8_t status = 1;
-            write(fds[1], &status, 1);
+            if (qemu_write(fds[1], &status, 1) != 1)
+                fprintf(stderr, "Could not write status to pid file \n");
         } else
             fprintf(stderr, "Could not acquire pid file\n");
         exit(1);
@@ -6216,7 +6218,9 @@ int main(int argc, char **argv, char **envp)
 	if (len != 1)
 	    exit(1);
 
-	chdir("/");
+        if (chdir("/"))
+            exit(1);
+
 	TFR(fd = open("/dev/null", O_RDWR));
 	if (fd == -1)
 	    exit(1);
@@ -6235,7 +6239,9 @@ int main(int argc, char **argv, char **envp)
             fprintf(stderr, "chroot failed\n");
             exit(1);
         }
-        chdir("/");
+
+        if (chdir("/"))
+            exit(1);
     }
 
     if (run_as) {

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 21:22 [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date Jean-Christophe Dubois
@ 2009-06-17 21:51 ` malc
  2009-06-17 22:58   ` Jean-Christophe Dubois
  2009-06-17 21:54 ` Anthony Liguori
  1 sibling, 1 reply; 12+ messages in thread
From: malc @ 2009-06-17 21:51 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 4417 bytes --]

On Wed, 17 Jun 2009, Jean-Christophe Dubois wrote:

> Some system calls are now requiring to have their return value checked.
> 
> Without this a warning is emitted and in the case a qemu an error is
> triggered as qemu is considering warnings as errors.
> 
> For example:
> 
> block/cow.c: In function ЪЪcow_createЪЪ:
> block/cow.c:251: error: ignoring return value of ЪЪwriteЪЪ, declared with
> attribute warn_unused_result
> block/cow.c:253: error: ignoring return value of ЪЪftruncateЪЪ, declared
> with attribute warn_unused_result
> 
> This is an attempt at removing all these warnings to allow a clean
> compilation with up to date compilers/distributions.
> 
> The second version fixes an error detected by Stuart Brady as well
> as some coding style issues. Note however that some of the
> modified files don't follow the qemu coding style (using tabs
> instead of spaces).
> 
> The Third version add one ftruncate() system call error handling that
> was missing from V2 (in block/vvfat.c).
> 
> The Fourth version is correctly handling EINTR error on read/write
> system calls. read/write calls are replaced by qemu_read/qemu_write
> functions that are handling EINTR and incomplete read/write under
> the cover.
> 

This patch is rather inconsistent w.r.t. lseek (perhaps some other calls too).

> 
> diff --git a/block.c b/block.c
> index aca5a6d..c78d66a 100644
> --- a/block.c
> +++ b/block.c
> @@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
>              snprintf(backing_filename, sizeof(backing_filename),
>                       "%s", filename);
>          else
> -            realpath(filename, backing_filename);
> +            if (!realpath(filename, backing_filename))
> +                return -1;
>  
>          bdrv_qcow2 = bdrv_find_format("qcow2");
>          options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
> diff --git a/block/bochs.c b/block/bochs.c
> index bac81c4..1fbce9e 100644
> --- a/block/bochs.c
> +++ b/block/bochs.c
> @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
>      // read in bitmap for current extent
>      lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);

No check here.

>  
> -    read(s->fd, &bitmap_entry, 1);
> +    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
> +        return -1; // not allocated
>  
>      if (!((bitmap_entry >> (extent_offset % 8)) & 1))
>      {
> diff --git a/block/cow.c b/block/cow.c
> index 84818f1..d8cd1df 100644
> --- a/block/cow.c
> +++ b/block/cow.c
> @@ -248,11 +248,19 @@ static int cow_create(const char *filename, QEMUOptionParameter *options)
>      }
>      cow_header.sectorsize = cpu_to_be32(512);
>      cow_header.size = cpu_to_be64(image_sectors * 512);
> -    write(cow_fd, &cow_header, sizeof(cow_header));
> +    if (qemu_write(cow_fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header))
> +        goto fail;
> +
>      /* resize to include at least all the bitmap */
> -    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
> +    if (ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)))
> +        goto fail;
> +
>      close(cow_fd);
>      return 0;
> +
> +fail:
> +    close(cow_fd);

close can fail too, btw.

> +    return -1;
>  }
>  
>  static void cow_flush(BlockDriverState *bs)
> diff --git a/block/qcow.c b/block/qcow.c
> index 55a68a6..5e50db8 100644
> --- a/block/qcow.c
> +++ b/block/qcow.c
> @@ -801,17 +801,27 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options)
>      }
>  
>      /* write all the data */
> -    write(fd, &header, sizeof(header));
> -    if (backing_file) {
> -        write(fd, backing_file, backing_filename_len);
> -    }
> -    lseek(fd, header_size, SEEK_SET);
> +    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
> +        goto fail;
> +
> +    if (backing_file)
> +        if (qemu_write(fd, backing_file, backing_filename_len) != backing_filename_len)
> +            goto fail;
> +
> +    if (lseek(fd, header_size, SEEK_SET) == -1)
> +        goto fail;

But here it is checked..

[..snip (more code with either behaviour)..]

FWIW i'm all for it, but it would have been nice to have more coherence there.

-- 
mailto:av1474@comtv.ru

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 21:22 [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date Jean-Christophe Dubois
  2009-06-17 21:51 ` malc
@ 2009-06-17 21:54 ` Anthony Liguori
  2009-06-17 22:41   ` Jean-Christophe Dubois
  1 sibling, 1 reply; 12+ messages in thread
From: Anthony Liguori @ 2009-06-17 21:54 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel

Jean-Christophe Dubois wrote:
> Some system calls are now requiring to have their return value checked.
>
> Without this a warning is emitted and in the case a qemu an error is
> triggered as qemu is considering warnings as errors.
>
> For example:
>
> block/cow.c: In function ‘cow_create’:
> block/cow.c:251: error: ignoring return value of ‘write’, declared with
> attribute warn_unused_result
> block/cow.c:253: error: ignoring return value of ‘ftruncate’, declared
> with attribute warn_unused_result
>
> This is an attempt at removing all these warnings to allow a clean
> compilation with up to date compilers/distributions.
>
> The second version fixes an error detected by Stuart Brady as well
> as some coding style issues. Note however that some of the
> modified files don't follow the qemu coding style (using tabs
> instead of spaces).
>
> The Third version add one ftruncate() system call error handling that
> was missing from V2 (in block/vvfat.c).
>
> The Fourth version is correctly handling EINTR error on read/write
> system calls. read/write calls are replaced by qemu_read/qemu_write
> functions that are handling EINTR and incomplete read/write under
> the cover.
>
> Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net>
>   

This really makes me nervous to be honest.  It's too much for one patch.

What I'd rather do, is commit Gerd's patch and also add 
-U_FORTIFY_SOURCE to the default CFLAGS.  I've confirmed this fixes the 
default build on Ubuntu.

I'd rather take this set of clean ups as a set of smaller, well 
thought-out patches.  Once that's done, we can remove -U_FORTIFY_SOURCE.

> ---
>  block.c           |    3 +-
>  block/bochs.c     |    3 +-
>  block/cow.c       |   12 +++++++++-
>  block/qcow.c      |   22 +++++++++++++++-----
>  block/qcow2.c     |   37 ++++++++++++++++++++++++++++-------
>  block/raw-posix.c |    9 +++++--
>  block/vmdk.c      |   54 +++++++++++++++++++++++++++++++++++-----------------
>  block/vvfat.c     |   24 ++++++++++++++++------
>  linux-user/mmap.c |    7 ++++-
>  linux-user/path.c |    6 ++++-
>  osdep.c           |    5 +++-
>  qemu-common.h     |   31 ++++++++++++++++++++++++++++++
>  slirp/misc.c      |    4 ++-
>  usb-linux.c       |    3 +-
>  vl.c              |   14 +++++++++---
>  15 files changed, 177 insertions(+), 57 deletions(-)
>
> diff --git a/block.c b/block.c
> index aca5a6d..c78d66a 100644
> --- a/block.c
> +++ b/block.c
> @@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
>              snprintf(backing_filename, sizeof(backing_filename),
>                       "%s", filename);
>          else
> -            realpath(filename, backing_filename);
> +            if (!realpath(filename, backing_filename))
> +                return -1;

There should be cleanup work to do, no?

>  
>          bdrv_qcow2 = bdrv_find_format("qcow2");
>          options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
> diff --git a/block/bochs.c b/block/bochs.c
> index bac81c4..1fbce9e 100644
> --- a/block/bochs.c
> +++ b/block/bochs.c
> @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
>      // read in bitmap for current extent
>      lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
>  
> -    read(s->fd, &bitmap_entry, 1);
> +    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
> +        return -1; // not allocated
>   

Why check errors on read but not lseek?  If we're going to add error 
checking to this function, we should make it robust, not just enough 
error checking to silence GCC.  We should just silence GCC with 
-U_FORTIFY_SOURCE.

The same is true for most of the remainder.  This is definitely a good 
task worth doing but I think we should do it more carefully.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 21:54 ` Anthony Liguori
@ 2009-06-17 22:41   ` Jean-Christophe Dubois
  2009-06-17 22:51     ` Anthony Liguori
  0 siblings, 1 reply; 12+ messages in thread
From: Jean-Christophe Dubois @ 2009-06-17 22:41 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Le mercredi 17 juin 2009 23:54:56 Anthony Liguori, vous avez écrit :
> Jean-Christophe Dubois wrote:
> > Some system calls are now requiring to have their return value checked.
> >
> > Without this a warning is emitted and in the case a qemu an error is
> > triggered as qemu is considering warnings as errors.
> >
> > For example:
> >
> > block/cow.c: In function ‘cow_create’:
> > block/cow.c:251: error: ignoring return value of ‘write’, declared with
> > attribute warn_unused_result
> > block/cow.c:253: error: ignoring return value of ‘ftruncate’, declared
> > with attribute warn_unused_result
> >
> > This is an attempt at removing all these warnings to allow a clean
> > compilation with up to date compilers/distributions.
> >
> > The second version fixes an error detected by Stuart Brady as well
> > as some coding style issues. Note however that some of the
> > modified files don't follow the qemu coding style (using tabs
> > instead of spaces).
> >
> > The Third version add one ftruncate() system call error handling that
> > was missing from V2 (in block/vvfat.c).
> >
> > The Fourth version is correctly handling EINTR error on read/write
> > system calls. read/write calls are replaced by qemu_read/qemu_write
> > functions that are handling EINTR and incomplete read/write under
> > the cover.
> >
> > Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net>
>
> This really makes me nervous to be honest.  It's too much for one patch.

It is what is required to fix the compilation failure.

> What I'd rather do, is commit Gerd's patch and also add
> -U_FORTIFY_SOURCE to the default CFLAGS.  I've confirmed this fixes the
> default build on Ubuntu.

It certainly does. Qemu did compile for years with less strict compilers.

> I'd rather take this set of clean ups as a set of smaller, well
> thought-out patches.  Once that's done, we can remove -U_FORTIFY_SOURCE.

Well, without -U_FORTIFY_SOURCE the all set of patch is required. Once you add 
-U_FORTIFY_SOURCE I am skeptical it will be removed any time soon. Actually I 
bet more code without error checking will be added and the problem will just 
build up.

> > ---
> >  block.c           |    3 +-
> >  block/bochs.c     |    3 +-
> >  block/cow.c       |   12 +++++++++-
> >  block/qcow.c      |   22 +++++++++++++++-----
> >  block/qcow2.c     |   37 ++++++++++++++++++++++++++++-------
> >  block/raw-posix.c |    9 +++++--
> >  block/vmdk.c      |   54
> > +++++++++++++++++++++++++++++++++++----------------- block/vvfat.c     | 
> >  24 ++++++++++++++++------
> >  linux-user/mmap.c |    7 ++++-
> >  linux-user/path.c |    6 ++++-
> >  osdep.c           |    5 +++-
> >  qemu-common.h     |   31 ++++++++++++++++++++++++++++++
> >  slirp/misc.c      |    4 ++-
> >  usb-linux.c       |    3 +-
> >  vl.c              |   14 +++++++++---
> >  15 files changed, 177 insertions(+), 57 deletions(-)
> >
> > diff --git a/block.c b/block.c
> > index aca5a6d..c78d66a 100644
> > --- a/block.c
> > +++ b/block.c
> > @@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char
> > *filename, int flags, snprintf(backing_filename,
> > sizeof(backing_filename), "%s", filename);
> >          else
> > -            realpath(filename, backing_filename);
> > +            if (!realpath(filename, backing_filename))
> > +                return -1;
>
> There should be cleanup work to do, no?
>
> >          bdrv_qcow2 = bdrv_find_format("qcow2");
> >          options = parse_option_parameters("",
> > bdrv_qcow2->create_options, NULL); diff --git a/block/bochs.c
> > b/block/bochs.c
> > index bac81c4..1fbce9e 100644
> > --- a/block/bochs.c
> > +++ b/block/bochs.c
> > @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState
> > *bs, int64_t sector_num) // read in bitmap for current extent
> >      lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
> >
> > -    read(s->fd, &bitmap_entry, 1);
> > +    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
> > +        return -1; // not allocated
>
> Why check errors on read but not lseek?  

Well, my first goal was to fix the compilation failure in a useful way. lseek() 
doesn't trigger the warning and so doesn't make the compilation fail.

Now, I would agree that lseek return code should also be checked. But can you 
guess how many lseek() (and other system calls) without error check there is 
in the qemu source code.

> If we're going to add error
> checking to this function, we should make it robust, not just enough
> error checking to silence GCC.

Why do you think my functions are not robust enough? Just curious ... If I can 
fix them, I'll do it. My goal was not to just silence GCC (I would use -
U_FORTIFY_SOURCE for this) but to actually handle the error in a meaningful 
way.

> We should just silence GCC with
> -U_FORTIFY_SOURCE.

You can do this but once done I doubt anybody will step up to actually fix the 
multiple place in the code where system calls are used without error checking. 
As there will be no more warning/error the problem will be 
forgotten/invisible.

> The same is true for most of the remainder.  This is definitely a good
> task worth doing but I think we should do it more carefully.

Once again, when all warnings are suppressed I doubt anybody will volunteer 
for this boring task. And all future code added to the project without system 
call error check will get unnoticed because you silenced GCC.

But at the end it is your call.

> Regards,
>
> Anthony Liguori

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 22:41   ` Jean-Christophe Dubois
@ 2009-06-17 22:51     ` Anthony Liguori
  2009-06-17 23:16       ` Jean-Christophe Dubois
  0 siblings, 1 reply; 12+ messages in thread
From: Anthony Liguori @ 2009-06-17 22:51 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel

Jean-Christophe Dubois wrote:
> Once again, when all warnings are suppressed I doubt anybody will volunteer 
> for this boring task. And all future code added to the project without system 
> call error check will get unnoticed because you silenced GCC.
>
> But at the end it is your call.
>   

Silencing the warnings != fixing the warnings.

To fix the warning, the errors have to be dealt with in a graceful way.  
This means either propagating the errors and releases any acquired 
resources or aborting.

It is not an improvement to just add dummy error handling in a few 
spots.  It does not result in making the code any more robust.

Regards,

Anthony Liguori

>> Regards,
>>
>> Anthony Liguori
>>     
>
>   

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 21:51 ` malc
@ 2009-06-17 22:58   ` Jean-Christophe Dubois
  2009-06-18  1:17     ` malc
  0 siblings, 1 reply; 12+ messages in thread
From: Jean-Christophe Dubois @ 2009-06-17 22:58 UTC (permalink / raw)
  To: malc; +Cc: qemu-devel

Le mercredi 17 juin 2009 23:51:12 malc, vous avez écrit :
> On Wed, 17 Jun 2009, Jean-Christophe Dubois wrote:
> > Some system calls are now requiring to have their return value checked.
> >
> > Without this a warning is emitted and in the case a qemu an error is
> > triggered as qemu is considering warnings as errors.
> >
> > For example:
> >
> > block/cow.c: In function ЪЪcow_createЪЪ:
> > block/cow.c:251: error: ignoring return value of ЪЪwriteЪЪ, declared with
> > attribute warn_unused_result
> > block/cow.c:253: error: ignoring return value of ЪЪftruncateЪЪ, declared
> > with attribute warn_unused_result
> >
> > This is an attempt at removing all these warnings to allow a clean
> > compilation with up to date compilers/distributions.
> >
> > The second version fixes an error detected by Stuart Brady as well
> > as some coding style issues. Note however that some of the
> > modified files don't follow the qemu coding style (using tabs
> > instead of spaces).
> >
> > The Third version add one ftruncate() system call error handling that
> > was missing from V2 (in block/vvfat.c).
> >
> > The Fourth version is correctly handling EINTR error on read/write
> > system calls. read/write calls are replaced by qemu_read/qemu_write
> > functions that are handling EINTR and incomplete read/write under
> > the cover.
>
> This patch is rather inconsistent w.r.t. lseek (perhaps some other calls
> too).
>
> > diff --git a/block.c b/block.c
> > index aca5a6d..c78d66a 100644
> > --- a/block.c
> > +++ b/block.c
> > @@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char
> > *filename, int flags, snprintf(backing_filename,
> > sizeof(backing_filename), "%s", filename);
> >          else
> > -            realpath(filename, backing_filename);
> > +            if (!realpath(filename, backing_filename))
> > +                return -1;
> >
> >          bdrv_qcow2 = bdrv_find_format("qcow2");
> >          options = parse_option_parameters("",
> > bdrv_qcow2->create_options, NULL); diff --git a/block/bochs.c
> > b/block/bochs.c
> > index bac81c4..1fbce9e 100644
> > --- a/block/bochs.c
> > +++ b/block/bochs.c
> > @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState
> > *bs, int64_t sector_num) // read in bitmap for current extent
> >      lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
>
> No check here.
>
> > -    read(s->fd, &bitmap_entry, 1);
> > +    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
> > +        return -1; // not allocated
> >
> >      if (!((bitmap_entry >> (extent_offset % 8)) & 1))
> >      {
> > diff --git a/block/cow.c b/block/cow.c
> > index 84818f1..d8cd1df 100644
> > --- a/block/cow.c
> > +++ b/block/cow.c
> > @@ -248,11 +248,19 @@ static int cow_create(const char *filename,
> > QEMUOptionParameter *options) }
> >      cow_header.sectorsize = cpu_to_be32(512);
> >      cow_header.size = cpu_to_be64(image_sectors * 512);
> > -    write(cow_fd, &cow_header, sizeof(cow_header));
> > +    if (qemu_write(cow_fd, &cow_header, sizeof(cow_header)) !=
> > sizeof(cow_header)) +        goto fail;
> > +
> >      /* resize to include at least all the bitmap */
> > -    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
> > +    if (ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >>
> > 3))) +        goto fail;
> > +
> >      close(cow_fd);
> >      return 0;
> > +
> > +fail:
> > +    close(cow_fd);
>
> close can fail too, btw.
>
> > +    return -1;
> >  }
> >
> >  static void cow_flush(BlockDriverState *bs)
> > diff --git a/block/qcow.c b/block/qcow.c
> > index 55a68a6..5e50db8 100644
> > --- a/block/qcow.c
> > +++ b/block/qcow.c
> > @@ -801,17 +801,27 @@ static int qcow_create(const char *filename,
> > QEMUOptionParameter *options) }
> >
> >      /* write all the data */
> > -    write(fd, &header, sizeof(header));
> > -    if (backing_file) {
> > -        write(fd, backing_file, backing_filename_len);
> > -    }
> > -    lseek(fd, header_size, SEEK_SET);
> > +    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
> > +        goto fail;
> > +
> > +    if (backing_file)
> > +        if (qemu_write(fd, backing_file, backing_filename_len) !=
> > backing_filename_len) +            goto fail;
> > +
> > +    if (lseek(fd, header_size, SEEK_SET) == -1)
> > +        goto fail;
>
> But here it is checked..
>
> [..snip (more code with either behaviour)..]
>
> FWIW i'm all for it, but it would have been nice to have more coherence
> there.

My goal was not to fix all the qemu source code at once. There are many, many 
places in qemu where no error check is done on system calls. So I fixed a few 
lseek and left some other ones alone. But believe me there are many more of 
them in the source code. In order to be "coherent" my patch would need to be a 
lot, lot bigger.

BTW, there are other places in qemu sources where for example EINTR or 
incomplete read/write are not handled correctly on read/write calls. But I am 
not going to chase after them just to be told that you prefer to silence GCC 
rather than checking for errors.

JC

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 22:51     ` Anthony Liguori
@ 2009-06-17 23:16       ` Jean-Christophe Dubois
  2009-06-18 20:16         ` Luiz Capitulino
  0 siblings, 1 reply; 12+ messages in thread
From: Jean-Christophe Dubois @ 2009-06-17 23:16 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Le jeudi 18 juin 2009 00:51:43 Anthony Liguori, vous avez écrit :
> Jean-Christophe Dubois wrote:
> > Once again, when all warnings are suppressed I doubt anybody will
> > volunteer for this boring task. And all future code added to the project
> > without system call error check will get unnoticed because you silenced
> > GCC.
> >
> > But at the end it is your call.
>
> Silencing the warnings != fixing the warnings.

Correct.

> To fix the warning, the errors have to be dealt with in a graceful way.
> This means either propagating the errors and releases any acquired
> resources or aborting.

Well, I believe my patch is trying to deal with errors in a graceful way and 
releasing acquired resources whenever possible/required (actually, it does fix 
a few fd leaks). If you find this is not the case just point me at the faulty 
file and I'll fix it.

> It is not an improvement to just add dummy error handling in a few
> spots.  It does not result in making the code any more robust.

I don't think I am doing "dummy" error handling. I have made all the error 
handling you requested and more (EINTR error, partial read/write) and tried to 
clean resources in an ordered way when I found it was required.

And whatever I have added is a lot more robust than what was before. Once 
again, please just show me where my patch is incorrect and I will fix it. 

But don't just point at lseek() and friends. There are many of these system 
calls that are not handled correctly in the qemu code and I don't think I'll 
fix them all at once. It seems you are thinking my patch is already too big.

>
> Regards,
>
> Anthony Liguori
>
> >> Regards,
> >>
> >> Anthony Liguori

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 22:58   ` Jean-Christophe Dubois
@ 2009-06-18  1:17     ` malc
  0 siblings, 0 replies; 12+ messages in thread
From: malc @ 2009-06-18  1:17 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5655 bytes --]

On Thu, 18 Jun 2009, Jean-Christophe Dubois wrote:

> Le mercredi 17 juin 2009 23:51:12 malc, vous avez ЪЪcrit :
> > On Wed, 17 Jun 2009, Jean-Christophe Dubois wrote:
> > > Some system calls are now requiring to have their return value checked.
> > >
> > > Without this a warning is emitted and in the case a qemu an error is
> > > triggered as qemu is considering warnings as errors.
> > >
> > > For example:
> > >
> > > block/cow.c: In function ЪЪcow_createЪЪ:
> > > block/cow.c:251: error: ignoring return value of ЪЪwriteЪЪ, declared with
> > > attribute warn_unused_result
> > > block/cow.c:253: error: ignoring return value of ЪЪftruncateЪЪ, declared
> > > with attribute warn_unused_result
> > >
> > > This is an attempt at removing all these warnings to allow a clean
> > > compilation with up to date compilers/distributions.
> > >
> > > The second version fixes an error detected by Stuart Brady as well
> > > as some coding style issues. Note however that some of the
> > > modified files don't follow the qemu coding style (using tabs
> > > instead of spaces).
> > >
> > > The Third version add one ftruncate() system call error handling that
> > > was missing from V2 (in block/vvfat.c).
> > >
> > > The Fourth version is correctly handling EINTR error on read/write
> > > system calls. read/write calls are replaced by qemu_read/qemu_write
> > > functions that are handling EINTR and incomplete read/write under
> > > the cover.
> >
> > This patch is rather inconsistent w.r.t. lseek (perhaps some other calls
> > too).
> >
> > > diff --git a/block.c b/block.c
> > > index aca5a6d..c78d66a 100644
> > > --- a/block.c
> > > +++ b/block.c
> > > @@ -371,7 +371,8 @@ int bdrv_open2(BlockDriverState *bs, const char
> > > *filename, int flags, snprintf(backing_filename,
> > > sizeof(backing_filename), "%s", filename);
> > >          else
> > > -            realpath(filename, backing_filename);
> > > +            if (!realpath(filename, backing_filename))
> > > +                return -1;
> > >
> > >          bdrv_qcow2 = bdrv_find_format("qcow2");
> > >          options = parse_option_parameters("",
> > > bdrv_qcow2->create_options, NULL); diff --git a/block/bochs.c
> > > b/block/bochs.c
> > > index bac81c4..1fbce9e 100644
> > > --- a/block/bochs.c
> > > +++ b/block/bochs.c
> > > @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState
> > > *bs, int64_t sector_num) // read in bitmap for current extent
> > >      lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
> >
> > No check here.
> >
> > > -    read(s->fd, &bitmap_entry, 1);
> > > +    if (qemu_read(s->fd, &bitmap_entry, 1) != 1)
> > > +        return -1; // not allocated
> > >
> > >      if (!((bitmap_entry >> (extent_offset % 8)) & 1))
> > >      {
> > > diff --git a/block/cow.c b/block/cow.c
> > > index 84818f1..d8cd1df 100644
> > > --- a/block/cow.c
> > > +++ b/block/cow.c
> > > @@ -248,11 +248,19 @@ static int cow_create(const char *filename,
> > > QEMUOptionParameter *options) }
> > >      cow_header.sectorsize = cpu_to_be32(512);
> > >      cow_header.size = cpu_to_be64(image_sectors * 512);
> > > -    write(cow_fd, &cow_header, sizeof(cow_header));
> > > +    if (qemu_write(cow_fd, &cow_header, sizeof(cow_header)) !=
> > > sizeof(cow_header)) +        goto fail;
> > > +
> > >      /* resize to include at least all the bitmap */
> > > -    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
> > > +    if (ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >>
> > > 3))) +        goto fail;
> > > +
> > >      close(cow_fd);
> > >      return 0;
> > > +
> > > +fail:
> > > +    close(cow_fd);
> >
> > close can fail too, btw.
> >
> > > +    return -1;
> > >  }
> > >
> > >  static void cow_flush(BlockDriverState *bs)
> > > diff --git a/block/qcow.c b/block/qcow.c
> > > index 55a68a6..5e50db8 100644
> > > --- a/block/qcow.c
> > > +++ b/block/qcow.c
> > > @@ -801,17 +801,27 @@ static int qcow_create(const char *filename,
> > > QEMUOptionParameter *options) }
> > >
> > >      /* write all the data */
> > > -    write(fd, &header, sizeof(header));
> > > -    if (backing_file) {
> > > -        write(fd, backing_file, backing_filename_len);
> > > -    }
> > > -    lseek(fd, header_size, SEEK_SET);
> > > +    if (qemu_write(fd, &header, sizeof(header)) != sizeof(header))
> > > +        goto fail;
> > > +
> > > +    if (backing_file)
> > > +        if (qemu_write(fd, backing_file, backing_filename_len) !=
> > > backing_filename_len) +            goto fail;
> > > +
> > > +    if (lseek(fd, header_size, SEEK_SET) == -1)
> > > +        goto fail;
> >
> > But here it is checked..
> >
> > [..snip (more code with either behaviour)..]
> >
> > FWIW i'm all for it, but it would have been nice to have more coherence
> > there.
> 
> My goal was not to fix all the qemu source code at once. There are many, many 
> places in qemu where no error check is done on system calls. So I fixed a few 
> lseek and left some other ones alone. But believe me there are many more of 
> them in the source code. In order to be "coherent" my patch would need to be a 
> lot, lot bigger.

And what was the motivation of fixing some and leaving others as is?

> BTW, there are other places in qemu sources where for example EINTR or 
> incomplete read/write are not handled correctly on read/write calls. But I am 
> not going to chase after them just to be told that you prefer to silence GCC 
> rather than checking for errors.

"You" as in...?

-- 
mailto:av1474@comtv.ru

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-17 23:16       ` Jean-Christophe Dubois
@ 2009-06-18 20:16         ` Luiz Capitulino
  2009-06-18 20:33           ` Anthony Liguori
  0 siblings, 1 reply; 12+ messages in thread
From: Luiz Capitulino @ 2009-06-18 20:16 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel

On Thu, 18 Jun 2009 01:16:37 +0200
"Jean-Christophe Dubois" <jcd@tribudubois.net> wrote:

> And whatever I have added is a lot more robust than what was before.
> Once again, please just show me where my patch is incorrect and I
> will fix it. 

 I really missed this v4, sorry for that and thanks for letting me know.

 I think the first step is to do one logical change at a time. You
could, for example do:

 1. Add qemu_read() and qemu_write()
 2. Port one subsystem per-patch for each of them

 Each lseek() or ftruncate() could also be done this way. Unrelated
fixes should be in different patches.

 We also have to define how far we're going on this 'warning fixing'
thing. read() and write() seems ok to me, now close() doesn't seem
important.

 This is my personal suggestion on the topic, it doesn't represent
upstream's view though.

 Also, I think qemu_read() and qemu_write() should abort on error,
if that's what callers are going to do.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-18 20:16         ` Luiz Capitulino
@ 2009-06-18 20:33           ` Anthony Liguori
  2009-06-18 21:05             ` Luiz Capitulino
  2009-06-18 21:10             ` Jean-Christophe Dubois
  0 siblings, 2 replies; 12+ messages in thread
From: Anthony Liguori @ 2009-06-18 20:33 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: qemu-devel, Jean-Christophe Dubois

Luiz Capitulino wrote:
> On Thu, 18 Jun 2009 01:16:37 +0200
> "Jean-Christophe Dubois" <jcd@tribudubois.net> wrote:
>
>   
>> And whatever I have added is a lot more robust than what was before.
>> Once again, please just show me where my patch is incorrect and I
>> will fix it. 
>>     
>
>  I really missed this v4, sorry for that and thanks for letting me know.
>
>  I think the first step is to do one logical change at a time. You
> could, for example do:
>
>  1. Add qemu_read() and qemu_write()
>   

We already have these in various places.  The problem is, we often want 
different semantics.  We don't always want to retry partial results 
(like for live migration).  We need a more rationalized approach to this.

>  2. Port one subsystem per-patch for each of them
>   

Yes, and for each fixup, fix the whole function, not just a handful of 
functions that gcc currently whines about.

N.B.  I will be pushing -U_FORTIFY_SOURCE so the ubuntu build breakage 
will be fixed.  We have the time to fix these warnings correctly.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-18 20:33           ` Anthony Liguori
@ 2009-06-18 21:05             ` Luiz Capitulino
  2009-06-18 21:10             ` Jean-Christophe Dubois
  1 sibling, 0 replies; 12+ messages in thread
From: Luiz Capitulino @ 2009-06-18 21:05 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Jean-Christophe Dubois

On Thu, 18 Jun 2009 15:33:03 -0500
Anthony Liguori <anthony@codemonkey.ws> wrote:

> Luiz Capitulino wrote:
> > On Thu, 18 Jun 2009 01:16:37 +0200
> > "Jean-Christophe Dubois" <jcd@tribudubois.net> wrote:
> >
> >   
> >> And whatever I have added is a lot more robust than what was
> >> before. Once again, please just show me where my patch is
> >> incorrect and I will fix it. 
> >>     
> >
> >  I really missed this v4, sorry for that and thanks for letting me
> > know.
> >
> >  I think the first step is to do one logical change at a time. You
> > could, for example do:
> >
> >  1. Add qemu_read() and qemu_write()
> >   
> 
> We already have these in various places.  The problem is, we often
> want different semantics.  We don't always want to retry partial
> results (like for live migration).  We need a more rationalized
> approach to this.

 If a reasonable number of users can agree on one general semantic,
we could have qemu_read() for it and let the others use plain read()
directly.

 But now I'm guessing, one should map all the usage to have a better
picture on how to encapsulate and share code.

 And I hope this is done before having anything merged, otherwise
this will require the same amount of work later.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date
  2009-06-18 20:33           ` Anthony Liguori
  2009-06-18 21:05             ` Luiz Capitulino
@ 2009-06-18 21:10             ` Jean-Christophe Dubois
  1 sibling, 0 replies; 12+ messages in thread
From: Jean-Christophe Dubois @ 2009-06-18 21:10 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Luiz Capitulino

Le jeudi 18 juin 2009 22:33:03 Anthony Liguori, vous avez écrit :
> Luiz Capitulino wrote:
> > On Thu, 18 Jun 2009 01:16:37 +0200
> >
> > "Jean-Christophe Dubois" <jcd@tribudubois.net> wrote:
> >> And whatever I have added is a lot more robust than what was before.
> >> Once again, please just show me where my patch is incorrect and I
> >> will fix it.
> >
> >  I really missed this v4, sorry for that and thanks for letting me know.
> >
> >  I think the first step is to do one logical change at a time. You
> > could, for example do:
> >
> >  1. Add qemu_read() and qemu_write()
>
> We already have these in various places.  The problem is, we often want
> different semantics.  We don't always want to retry partial results
> (like for live migration).  We need a more rationalized approach to this.

Anthony, I am not sure to understand what you mean here. Are you against the 
qemu_read/qemu_write approach? Are you hinting that your preference is that 
each and every read/write call handles its error case in its own local way?

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2009-06-18 21:10 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-17 21:22 [Qemu-devel] [PATCH v4] avoid compilation warning/errors on up to date Jean-Christophe Dubois
2009-06-17 21:51 ` malc
2009-06-17 22:58   ` Jean-Christophe Dubois
2009-06-18  1:17     ` malc
2009-06-17 21:54 ` Anthony Liguori
2009-06-17 22:41   ` Jean-Christophe Dubois
2009-06-17 22:51     ` Anthony Liguori
2009-06-17 23:16       ` Jean-Christophe Dubois
2009-06-18 20:16         ` Luiz Capitulino
2009-06-18 20:33           ` Anthony Liguori
2009-06-18 21:05             ` Luiz Capitulino
2009-06-18 21:10             ` Jean-Christophe Dubois

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.