Print this page
7369 SMF is fast and loose with exclude dependencies


1412 /* ARGSUSED */
1413 static int
1414 exclude_all_satisfied(graph_vertex_t *groupv, boolean_t satbility)
1415 {
1416         graph_edge_t *edge, *e2;
1417         graph_vertex_t *v, *v2;
1418 
1419         for (edge = uu_list_first(groupv->gv_dependencies);
1420             edge != NULL;
1421             edge = uu_list_next(groupv->gv_dependencies, edge)) {
1422                 v = edge->ge_vertex;
1423 
1424                 switch (v->gv_type) {
1425                 case GVT_INST:
1426                         if ((v->gv_flags & GV_CONFIGURED) == 0)
1427                                 continue;
1428 
1429                         switch (v->gv_state) {
1430                         case RESTARTER_STATE_ONLINE:
1431                         case RESTARTER_STATE_DEGRADED:
1432                                 LOG_EXCLUDE(groupv, v);
1433                                 return (v->gv_flags & GV_ENABLED ? -1 : 0);
1434 
1435                         case RESTARTER_STATE_OFFLINE:
1436                         case RESTARTER_STATE_UNINIT:
1437                                 LOG_EXCLUDE(groupv, v);
1438                                 return (0);
1439 
1440                         case RESTARTER_STATE_DISABLED:






1441                         case RESTARTER_STATE_MAINT:
1442                                 continue;
1443 
1444                         default:
1445 #ifndef NDEBUG
1446                                 uu_warn("%s:%d: Unexpected vertex state %d.\n",
1447                                     __FILE__, __LINE__, v->gv_state);
1448 #endif
1449                                 abort();
1450                         }
1451                         /* NOTREACHED */
1452 
1453                 case GVT_SVC:
1454                         break;
1455 
1456                 case GVT_FILE:
1457                         if (!file_ready(v))
1458                                 continue;
1459                         LOG_EXCLUDE(groupv, v);
1460                         return (-1);
1461 
1462                 case GVT_GROUP:
1463                 default:
1464 #ifndef NDEBUG
1465                         uu_warn("%s:%d: Unexpected vertex type %d.\n", __FILE__,
1466                             __LINE__, v->gv_type);
1467 #endif
1468                         abort();
1469                 }
1470 
1471                 /* v represents a service */
1472                 if (uu_list_numnodes(v->gv_dependencies) == 0)
1473                         continue;
1474 
1475                 for (e2 = uu_list_first(v->gv_dependencies);
1476                     e2 != NULL;
1477                     e2 = uu_list_next(v->gv_dependencies, e2)) {
1478                         v2 = e2->ge_vertex;
1479                         assert(v2->gv_type == GVT_INST);
1480 
1481                         if ((v2->gv_flags & GV_CONFIGURED) == 0)
1482                                 continue;
1483 
1484                         switch (v2->gv_state) {
1485                         case RESTARTER_STATE_ONLINE:
1486                         case RESTARTER_STATE_DEGRADED:
1487                                 LOG_EXCLUDE(groupv, v2);
1488                                 return (v2->gv_flags & GV_ENABLED ? -1 : 0);
1489 
1490                         case RESTARTER_STATE_OFFLINE:
1491                         case RESTARTER_STATE_UNINIT:
1492                                 LOG_EXCLUDE(groupv, v2);
1493                                 return (0);
1494 
1495                         case RESTARTER_STATE_DISABLED:
1496                         case RESTARTER_STATE_MAINT:
1497                                 continue;
1498 
1499                         default:
1500 #ifndef NDEBUG
1501                                 uu_warn("%s:%d: Unexpected vertex type %d.\n",
1502                                     __FILE__, __LINE__, v2->gv_type);
1503 #endif
1504                                 abort();
1505                         }
1506                 }
1507         }
1508 
1509         return (1);
1510 }
1511 
1512 /*
1513  * int instance_satisfied()
1514  *   Determine if all the dependencies are satisfied for the supplied instance
1515  *   vertex. Return 1 if they are, 0 if they aren't, and -1 if they won't be
1516  *   without administrator intervention.
1517  */
1518 static int
1519 instance_satisfied(graph_vertex_t *v, boolean_t satbility)
1520 {




1521         assert(v->gv_type == GVT_INST);
1522         assert(!inst_running(v));
1523 

































1524         return (require_all_satisfied(v, satbility));
1525 }
1526 
1527 /*
1528  * Decide whether v can satisfy a dependency.  v can either be a child of
1529  * a group vertex, or of an instance vertex.
1530  */
1531 static int
1532 dependency_satisfied(graph_vertex_t *v, boolean_t satbility)
1533 {
1534         switch (v->gv_type) {
1535         case GVT_INST:
1536                 if ((v->gv_flags & GV_CONFIGURED) == 0) {
1537                         if (v->gv_flags & GV_DEATHROW) {
1538                                 /*
1539                                  * A dependency on an instance with GV_DEATHROW
1540                                  * flag is always considered as satisfied.
1541                                  */
1542                                 return (1);
1543                         }


4522  */
4523 void
4524 offline_subtree_leaves(graph_vertex_t *v, void *arg)
4525 {
4526         assert(MUTEX_HELD(&dgraph_lock));
4527 
4528         /* If v isn't an instance, recurse on its dependencies. */
4529         if (v->gv_type != GVT_INST) {
4530                 graph_walk_dependencies(v, offline_subtree_leaves, arg);
4531                 return;
4532         }
4533 
4534         /*
4535          * If v is not in the subtree, so should all of its dependencies,
4536          * so do nothing.
4537          */
4538         if ((v->gv_flags & GV_TOOFFLINE) == 0)
4539                 return;
4540 
4541         /* If v isn't a leaf because it's already down, recurse. */
4542         if (!up_state(v->gv_state)) {
4543                 graph_walk_dependencies(v, offline_subtree_leaves, arg);
4544                 return;
4545         }
4546 
4547         /* if v is a leaf, offline it or disable it if it's the last one */
4548         if (insubtree_dependents_down(v) == B_TRUE) {
4549                 if (v->gv_flags & GV_TODISABLE)
4550                         vertex_send_event(v,
4551                             RESTARTER_EVENT_TYPE_ADMIN_DISABLE);
4552                 else
4553                         offline_vertex(v);
4554         }
4555 }
4556 
4557 void
4558 graph_offline_subtree_leaves(graph_vertex_t *v, void *h)
4559 {
4560         graph_walk_dependencies(v, offline_subtree_leaves, (void *)h);
4561 }
4562 




1412 /* ARGSUSED */
1413 static int
1414 exclude_all_satisfied(graph_vertex_t *groupv, boolean_t satbility)
1415 {
1416         graph_edge_t *edge, *e2;
1417         graph_vertex_t *v, *v2;
1418 
1419         for (edge = uu_list_first(groupv->gv_dependencies);
1420             edge != NULL;
1421             edge = uu_list_next(groupv->gv_dependencies, edge)) {
1422                 v = edge->ge_vertex;
1423 
1424                 switch (v->gv_type) {
1425                 case GVT_INST:
1426                         if ((v->gv_flags & GV_CONFIGURED) == 0)
1427                                 continue;
1428 
1429                         switch (v->gv_state) {
1430                         case RESTARTER_STATE_ONLINE:
1431                         case RESTARTER_STATE_DEGRADED:



1432                         case RESTARTER_STATE_OFFLINE:

1433                                 LOG_EXCLUDE(groupv, v);
1434                                 return (v->gv_flags & GV_TODISABLE ? 0 : -1);
1435 
1436                         case RESTARTER_STATE_DISABLED:
1437                         case RESTARTER_STATE_UNINIT:
1438                                 if (v->gv_flags & GV_ENABLED) {
1439                                         LOG_EXCLUDE(groupv, v);
1440                                         return (-1);
1441                                 }
1442                                 /* FALLTHROUGH */
1443                         case RESTARTER_STATE_MAINT:
1444                                 continue;
1445 
1446                         default:
1447 #ifndef NDEBUG
1448                                 uu_warn("%s:%d: Unexpected vertex state %d.\n",
1449                                     __FILE__, __LINE__, v->gv_state);
1450 #endif
1451                                 abort();
1452                         }
1453                         /* NOTREACHED */
1454 
1455                 case GVT_SVC:
1456                         return (exclude_all_satisfied(v, satbility));
1457 
1458                 case GVT_FILE:
1459                         if (!file_ready(v))
1460                                 continue;
1461                         LOG_EXCLUDE(groupv, v);
1462                         return (-1);
1463 
1464                 case GVT_GROUP:
1465                 default:
1466 #ifndef NDEBUG
1467                         uu_warn("%s:%d: Unexpected vertex type %d.\n", __FILE__,
1468                             __LINE__, v->gv_type);
1469 #endif
1470                         abort();
1471                 }





































1472         }
1473 
1474         return (1);
1475 }
1476 
1477 /*
1478  * int instance_satisfied()
1479  *   Determine if all the dependencies are satisfied for the supplied instance
1480  *   vertex. Return 1 if they are, 0 if they aren't, and -1 if they won't be
1481  *   without administrator intervention.
1482  */
1483 static int
1484 instance_satisfied(graph_vertex_t *v, boolean_t satbility)
1485 {
1486         graph_edge_t *e;
1487         boolean_t any_unsatisfied;
1488         boolean_t any_unsatisfiable;
1489 
1490         assert(v->gv_type == GVT_INST);
1491         assert(!inst_running(v));
1492 
1493         any_unsatisfied = B_FALSE;
1494         any_unsatisfiable = B_FALSE;
1495 
1496         /*
1497          * Walk the dependents of the given vertex looking for any exclude_all
1498          * dependency groups with running instances.  If they are all going to
1499          * be disabled consider the dependency unsatisfied, not unsatisfaible.
1500          */
1501         for (e = uu_list_first(v->gv_dependents); e != NULL;
1502             e = uu_list_next(v->gv_dependents, e)) {
1503                 graph_edge_t *e2;
1504 
1505                 if (e->ge_vertex->gv_type != GVT_GROUP ||
1506                     e->ge_vertex->gv_depgroup != DEPGRP_EXCLUDE_ALL)
1507                         continue;
1508 
1509                 for (e2 = uu_list_first(e->ge_vertex->gv_dependents);
1510                     e2 != NULL;
1511                     e2 = uu_list_next(e->ge_vertex->gv_dependents, e2)) {
1512 
1513                         if (!inst_running(e2->ge_vertex))
1514                                 continue;
1515 
1516                         if (e2->ge_vertex->gv_flags & GV_TODISABLE)
1517                                 any_unsatisfied = B_TRUE;
1518                         else
1519                                 any_unsatisfiable = B_TRUE;
1520                 }
1521         }
1522 
1523         if (any_unsatisfied || any_unsatisfiable)
1524                 return (any_unsatisfiable ? -1 : 0);
1525 
1526         return (require_all_satisfied(v, satbility));
1527 }
1528 
1529 /*
1530  * Decide whether v can satisfy a dependency.  v can either be a child of
1531  * a group vertex, or of an instance vertex.
1532  */
1533 static int
1534 dependency_satisfied(graph_vertex_t *v, boolean_t satbility)
1535 {
1536         switch (v->gv_type) {
1537         case GVT_INST:
1538                 if ((v->gv_flags & GV_CONFIGURED) == 0) {
1539                         if (v->gv_flags & GV_DEATHROW) {
1540                                 /*
1541                                  * A dependency on an instance with GV_DEATHROW
1542                                  * flag is always considered as satisfied.
1543                                  */
1544                                 return (1);
1545                         }


4524  */
4525 void
4526 offline_subtree_leaves(graph_vertex_t *v, void *arg)
4527 {
4528         assert(MUTEX_HELD(&dgraph_lock));
4529 
4530         /* If v isn't an instance, recurse on its dependencies. */
4531         if (v->gv_type != GVT_INST) {
4532                 graph_walk_dependencies(v, offline_subtree_leaves, arg);
4533                 return;
4534         }
4535 
4536         /*
4537          * If v is not in the subtree, so should all of its dependencies,
4538          * so do nothing.
4539          */
4540         if ((v->gv_flags & GV_TOOFFLINE) == 0)
4541                 return;
4542 
4543         /* If v isn't a leaf because it's already down, recurse. */
4544         if (!inst_running(v) && (v->gv_flags & GV_TODISABLE) == 0) {
4545                 graph_walk_dependencies(v, offline_subtree_leaves, arg);
4546                 return;
4547         }
4548 
4549         /* if v is a leaf, offline it or disable it if it's the last one */
4550         if (insubtree_dependents_down(v) == B_TRUE) {
4551                 if (v->gv_flags & GV_TODISABLE)
4552                         vertex_send_event(v,
4553                             RESTARTER_EVENT_TYPE_ADMIN_DISABLE);
4554                 else
4555                         offline_vertex(v);
4556         }
4557 }
4558 
4559 void
4560 graph_offline_subtree_leaves(graph_vertex_t *v, void *h)
4561 {
4562         graph_walk_dependencies(v, offline_subtree_leaves, (void *)h);
4563 }
4564