summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2013-06-18 12:28:36 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-06-21 10:00:28 +0200
commite5f455afbc2d149527bfd08f4e89903a3a8da17a (patch)
tree4dfbd9044175db000ff6bbcb4ae8f39ebaa23f46 /src
parentb509de2164be8fa9a8d52d70883f4ec70b4bddf8 (diff)
downloadsssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.tar.gz
sssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.tar.xz
sssd-e5f455afbc2d149527bfd08f4e89903a3a8da17a.zip
failover: return error when SRV lookup returned only duplicates
https://fedorahosted.org/sssd/ticket/1947 Otherwise we risk that the meta server is removed from the server list, but without a chance to return, because there may be no fo_server with srv_data = meta. Also if state->meta->next is NULL (it is still orphaned because we try to errornously expand it without invoking collapse first), state->out will be NULL and SSSD will crash. New error code: ERR_SRV_DUPLICATES
Diffstat (limited to 'src')
-rw-r--r--src/providers/fail_over.c23
-rw-r--r--src/util/util_errors.c1
-rw-r--r--src/util/util_errors.h1
3 files changed, 23 insertions, 2 deletions
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index c4dd1ea0..c5db7024 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -1288,21 +1288,40 @@ resolve_srv_done(struct tevent_req *subreq)
backup_servers, num_backup_servers,
state->meta->srv_data,
state->meta->user_data,
- false, NULL);
+ false, &last_server);
if (ret != EOK) {
goto done;
}
}
+ if (last_server == state->meta) {
+ /* SRV lookup returned only those servers
+ * that are already present. */
+ DEBUG(SSSDBG_TRACE_FUNC, ("SRV lookup did not return "
+ "any new server.\n"));
+ ret = ERR_SRV_DUPLICATES;
+ goto done;
+ }
+
+ /* At least one new server was inserted.
+ * We will return the first new server. */
+ if (state->meta->next == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("BUG: state->meta->next is NULL\n"));
+ ret = ERR_INTERNAL;
+ goto done;
+ }
+
state->out = state->meta->next;
+ /* And remove meta server from the server list. It will be
+ * inserted again during srv collapse. */
DLIST_REMOVE(state->service->server_list, state->meta);
if (state->service->last_tried_server == state->meta) {
state->service->last_tried_server = state->out;
}
set_srv_data_status(state->meta->srv_data, SRV_RESOLVED);
-
ret = EOK;
break;
case ERR_SRV_NOT_FOUND:
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 22a3045a..015c5aca 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -44,6 +44,7 @@ struct err_string error_to_str[] = {
{ "Host Access Denied" }, /* ERR_ACCESS_DENIED */
{ "SRV record not found" }, /* ERR_SRV_NOT_FOUND */
{ "SRV lookup error" }, /* ERR_SRV_LOOKUP_ERROR */
+ { "SRV lookup did not return any new server "}, /* ERR_SRV_DUPLICATES */
{ "Dynamic DNS update failed" }, /* ERR_DYNDNS_FAILED */
{ "Dynamic DNS update timed out" }, /* ERR_DYNDNS_TIMEOUT */
{ "Dynamic DNS update not possible while offline" }, /* ERR_DYNDNS_OFFLINE */
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 65d37aed..ca447282 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -66,6 +66,7 @@ enum sssd_errors {
ERR_ACCESS_DENIED,
ERR_SRV_NOT_FOUND,
ERR_SRV_LOOKUP_ERROR,
+ ERR_SRV_DUPLICATES,
ERR_DYNDNS_FAILED,
ERR_DYNDNS_TIMEOUT,
ERR_DYNDNS_OFFLINE,
l kwa">else if (phydev->interface == PHY_INTERFACE_MODE_MII) { /* 100BASE-TX mode */ phydev->advertising = SUPPORTED_100baseT_Full; phydev->supported = phydev->advertising; val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK; phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val); } return 0; } int aquantia_startup(struct phy_device *phydev) { u32 reg, speed; int i = 0; phydev->duplex = DUPLEX_FULL; /* if the AN is still in progress, wait till timeout. */ phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1); reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1); if (!(reg & MDIO_AN_STAT1_COMPLETE)) { printf("%s Waiting for PHY auto negotiation to complete", phydev->dev->name); do { udelay(1000); reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1); if ((i++ % 500) == 0) printf("."); } while (!(reg & MDIO_AN_STAT1_COMPLETE) && i < (4 * PHY_ANEG_TIMEOUT)); if (i > PHY_ANEG_TIMEOUT) printf(" TIMEOUT !\n"); } /* Read twice because link state is latched and a * read moves the current state into the register */ phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1); reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1); if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) phydev->link = 0; else phydev->link = 1; speed = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR); if (speed & AQUNTIA_SPEED_MSB_MASK) { if (speed & AQUNTIA_SPEED_LSB_MASK) phydev->speed = SPEED_10000; else phydev->speed = SPEED_1000; } else { if (speed & AQUNTIA_SPEED_LSB_MASK) phydev->speed = SPEED_100; else phydev->speed = SPEED_10; } return 0; } struct phy_driver aq1202_driver = { .name = "Aquantia AQ1202", .uid = 0x3a1b445, .mask = 0xfffffff0, .features = PHY_10G_FEATURES, .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS| MDIO_MMD_PHYXS | MDIO_MMD_AN | MDIO_MMD_VEND1), .config = &aquantia_config, .startup = &aquantia_startup, .shutdown = &gen10g_shutdown, }; struct phy_driver aq2104_driver = { .name = "Aquantia AQ2104", .uid = 0x3a1b460, .mask = 0xfffffff0, .features = PHY_10G_FEATURES, .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS| MDIO_MMD_PHYXS | MDIO_MMD_AN | MDIO_MMD_VEND1), .config = &aquantia_config, .startup = &aquantia_startup, .shutdown = &gen10g_shutdown, }; struct phy_driver aqr105_driver = { .name = "Aquantia AQR105", .uid = 0x3a1b4a2, .mask = 0xfffffff0, .features = PHY_10G_FEATURES, .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS| MDIO_MMD_PHYXS | MDIO_MMD_AN | MDIO_MMD_VEND1), .config = &aquantia_config, .startup = &aquantia_startup, .shutdown = &gen10g_shutdown, }; struct phy_driver aqr405_driver = { .name = "Aquantia AQR405", .uid = 0x3a1b4b2, .mask = 0xfffffff0, .features = PHY_10G_FEATURES, .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS| MDIO_MMD_PHYXS | MDIO_MMD_AN | MDIO_MMD_VEND1), .config = &aquantia_config, .startup = &aquantia_startup, .shutdown = &gen10g_shutdown, }; int phy_aquantia_init(void) { phy_register(&aq1202_driver); phy_register(&aq2104_driver); phy_register(&aqr105_driver); phy_register(&aqr405_driver); return 0; }