On 11/14/2012 03:38 PM, Simo Sorce wrote:
On Wed, 2012-11-14 at 15:18 +0100, Jan Cholasta wrote:

Just one more nitpick: SSS_DB_CHECK_PTS and sss_db_version_check are
used only in sysdb.c, so there is no reason to have them defined
publicly in util.h+util.c. Move them both to sysdb.c please (you
might
also want to rename them to better fit in sysdb.c).


Yes please, rename them to be sysdb_* functions and move them in sysdb
where they belong.
The util/ shouldn't have component specific functions.

Simo.


moved all code to sysdb, new patch attached.

O.


--
Ondrej Kos
Associate Software Engineer
Identity Management
Red Hat Czech

phone: +420-532-294-558
cell:  +420-736-417-909
ext:   82-62558
loc:   1013 Brno 1 office
irc:   okos @ #brno
From 115e4e83fc5459e684892fe0f94fa53bb61da890 Mon Sep 17 00:00:00 2001
From: Ondrej Kos <o...@redhat.com>
Date: Thu, 8 Nov 2012 14:34:36 +0100
Subject: [PATCH] Display more information on DB version crash

https://fedorahosted.org/sssd/ticket/1589

Added check for determining, whether database version is higher or
lower than expected. To distinguish it from other errors it uses
following retun values (further used for appropriate error message):
EMEDIUMTYPE for lower version than expected
EUCLEAN for higher version than expected

When SSSD or one of it's tools fails on DB version mismatch, new error
message is showed suggesting how to proceed.
---
 src/db/sysdb.c                          | 60 +++++++++++++++++++++++++++++++--
 src/db/sysdb.h                          | 11 ++++++
 src/monitor/monitor.c                   |  1 +
 src/responder/common/responder_common.c |  1 +
 src/tools/sss_cache.c                   |  1 +
 src/tools/sss_seed.c                    |  1 +
 src/tools/tools_util.c                  |  1 +
 7 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 9685163b3f00cc2a45617072efa353589de111ce..b6d250ba7a02dcd96e8665b1770d39e9d0b4d32a 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1037,7 +1037,7 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
             if (!allow_upgrade) {
                 DEBUG(0, ("Wrong DB version (got %s expected %s)\n",
                           version, SYSDB_VERSION));
-                ret = EINVAL;
+                ret = sysdb_version_check(SYSDB_VERSION, version);
                 goto done;
             }
 
@@ -1136,7 +1136,7 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
 
         DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
                  version?version:"not found", SYSDB_VERSION, domain->name));
-        ret = EINVAL;
+        ret = sysdb_version_check(SYSDB_VERSION, version);
         goto done;
     }
 
@@ -1356,6 +1356,62 @@ int compare_ldb_dn_comp_num(const void *m1, const void *m2)
     return ldb_dn_get_comp_num(msg2->dn) - ldb_dn_get_comp_num(msg1->dn);
 }
 
+/* Compare versions of sysdb, returns ERRNO accordingly */
+errno_t
+sysdb_version_check(const char *expected,
+                    const char *received)
+{
+    int ret;
+    unsigned int exp_major, exp_minor, recv_major, recv_minor;
+
+    ret = sscanf(expected, "%u.%u", &exp_major, &exp_minor);
+    if (ret != SYSDB_CHECK_PTS) {
+        return EINVAL;
+    }
+    ret = sscanf(received, "%u.%u", &recv_major, &recv_minor);
+    if (ret != SYSDB_CHECK_PTS) {
+        return EINVAL;
+    }
+
+    if (recv_major > exp_major) {
+        return EUCLEAN;
+    } else if (recv_major < exp_major) {
+        return EMEDIUMTYPE;
+    }
+
+    if (recv_minor > exp_minor) {
+        return EUCLEAN;
+    } else if (recv_minor < exp_minor) {
+        return EMEDIUMTYPE;
+    }
+
+    return EOK;
+}
+
+/* Print out database version mismatch error message
+ * according to expected one and environment */
+void
+sysdb_version_mismatch(errno_t equ_type,
+                        bool in_tool)
+{
+    ERROR("DB version mismatch!\n");
+    switch (equ_type) {
+        case EUCLEAN:
+            ERROR("Lower version of database is expected.\n");
+            break;
+        case EMEDIUMTYPE:
+            ERROR("Higher version of database is expected. %s\n",
+                    in_tool ? "You could try running SSSD, which should "
+                    "handle the upgrade itself." : "");
+            break;
+        default:
+            break;
+    }
+    ERROR("Removing cached files in /var/run/sss/db/ should fix the issue, "
+            "but be aware, that deleting cache files also removes all of your "
+            "cached credentials.\n");
+}
+
 int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname,
                              const char *newname)
 {
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 39e0f9f5245c67f3798055823e98c2db0fbdebba..3d07687d81a9c81065e31c038ab7e25c25ad216d 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -214,6 +214,8 @@
 #define SYSDB_MOD_DEL LDB_FLAG_MOD_DELETE
 #define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE
 
+#define SYSDB_CHECK_PTS 2
+
 struct confdb_ctx;
 struct sysdb_ctx;
 
@@ -348,6 +350,15 @@ struct sss_domain_info *sysdb_ctx_get_domain(struct sysdb_ctx *sysdb);
 
 int compare_ldb_dn_comp_num(const void *m1, const void *m2);
 
+errno_t sysdb_version_check(const char *expected, const char *received);
+
+void sysdb_version_mismatch(errno_t equ_type, bool in_tool);
+
+#define SYSDB_MIS_CHECK(ret, in_tool) \
+    if (ret == EMEDIUMTYPE || ret == EUCLEAN) { \
+        sysdb_version_mismatch(ret, in_tool); \
+    }
+
 /* functions to start and finish transactions */
 int sysdb_transaction_start(struct sysdb_ctx *sysdb);
 int sysdb_transaction_commit(struct sysdb_ctx *sysdb);
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 956efb13ceb29a9361e60526e934883e0ecb5a16..bf45a65a5b22c3470d5263961a5ec597747dac2b 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2113,6 +2113,7 @@ int monitor_process_init(struct mt_ctx *ctx,
     }
     ret = sysdb_init(tmp_ctx, ctx->cdb, NULL, true, &db_list);
     if (ret != EOK) {
+        SYSDB_MIS_CHECK(ret, false);
         return ret;
     }
     talloc_zfree(tmp_ctx);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index d9f73fe2698cd7eacfb1a589c159e5cb037dab64..e33c9854df6a24e84340566ee6e22c6a69c14486 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -839,6 +839,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
 
     ret = sysdb_init(rctx, cdb, NULL, false, &rctx->db_list);
     if (ret != EOK) {
+        SYSDB_MIS_CHECK(ret, false);
         DEBUG(0, ("fatal error initializing resp_ctx\n"));
         return ret;
     }
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index 06b0099dc642812752949aa6cb8781ac1349ad90..4fa406916a527d6856ab91e78d16e7af4a5d89e7 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -339,6 +339,7 @@ errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain)
         ret = sysdb_init_domain_and_sysdb(ctx, ctx->confdb, domain, DB_PATH,
                                           &ctx->domains, &db_ctx);
         if (ret != EOK) {
+            SYSDB_MIS_CHECK(ret, true);
             DEBUG(1, ("Could not initialize connection to the sysdb\n"));
             goto fail;
         }
diff --git a/src/tools/sss_seed.c b/src/tools/sss_seed.c
index cd1b263863e44411e7aac8772c3922178ad9dca4..8e64a30b1531b27b4a12d5c73b07ed03c2f8d2d4 100644
--- a/src/tools/sss_seed.c
+++ b/src/tools/sss_seed.c
@@ -631,6 +631,7 @@ static int seed_init_db(TALLOC_CTX *mem_ctx,
     ret = sysdb_init_domain_and_sysdb(tmp_ctx, confdb, domain_name,
                                       DB_PATH, &domain, &sysdb);
     if (ret != EOK) {
+        SYSDB_MIS_CHECK(ret, true);
         DEBUG(SSSDBG_CRIT_FAILURE,
               ("Could not initialize connection to domain '%s' in sysdb.%s\n",
                domain_name, ret == ENOENT ? " Domain not found." : ""));
diff --git a/src/tools/tools_util.c b/src/tools/tools_util.c
index 99b79f171d82cde5f1c58988949422981e4d5ee3..bda83eb331b7d45564d6b11449f0d0d2a3f46fb0 100644
--- a/src/tools/tools_util.c
+++ b/src/tools/tools_util.c
@@ -57,6 +57,7 @@ static int setup_db(struct tools_ctx *ctx)
     ret = sysdb_init_domain_and_sysdb(ctx, ctx->confdb, "local", DB_PATH,
                                       &ctx->local, &ctx->sysdb);
     if (ret != EOK) {
+        SYSDB_MIS_CHECK(ret, true);
         DEBUG(1, ("Could not initialize connection to the sysdb\n"));
         return ret;
     }
-- 
1.7.11.7

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to