[sheepdog] Unreliable error code handling in sheep/plainstore.c

Xu Yifeng skypexu at gmail.com
Wed Mar 4 09:21:46 CET 2015


I found some unreliable error handling in plainstore.c, reason is 
combination of
sd_err() and err_to_sderr(), because it is not guaranteed that sd_err() 
does not
muck errno, it is possible passing an mucked errno to err_to_sderr(), 
see following
code in plain_store.c, line 758:
    if (unlikely(size != len)) {
                 sd_err("failed to write object %"PRIx64", path=%s, 
offset=%"
                        PRId32", size=%"PRId32", result=%zd, %m", oid, path,
                        iocb->offset, iocb->length, size);
                 ret = err_to_sderr(path, oid, errno);
                 goto out;
         }

it is possible that sd_err() may muck the errno, causing an irrelevant 
errno to be passed to
err_to_sderr!

The easiest way to fix this problem is preserve errno in log_write(), or
let err_to_sderr preserve errno and reorder the code.

diff --git a/lib/logger.c b/lib/logger.c
index da0ebac..20d2ca1 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -482,13 +482,16 @@ static void rotate_log(void)
  void log_write(int prio, const char *func, int line, const char *fmt, ...)
  {
         va_list ap;
+       int err_save;

         if (prio > sd_log_level)
                 return;

+       err_save = errno;
         va_start(ap, fmt);
         dolog(prio, func, line, fmt, ap);
         va_end(ap);
+       errno = err_save;
  }





More information about the sheepdog mailing list