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
|