4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <arpa/inet.h>
28 #include <libdllink.h>
29 #include <libdlstat.h>
32 #include <netinet/in.h>
34 #include <sys/socket.h>
36 #include <sys/types.h>
39 #include "conditions.h"
47 * ncp.c - handles NCP actions.
50 char active_ncp
[NWAM_MAX_NAME_LEN
];
51 nwam_ncp_handle_t active_ncph
= NULL
;
52 int64_t current_ncu_priority_group
= INVALID_PRIORITY_GROUP
;
54 * active_ncp_mutex protects active_ncp, active_ncph and
55 * current_ncu_priority_group.
57 pthread_mutex_t active_ncp_mutex
= PTHREAD_MUTEX_INITIALIZER
;
60 * The variable ncu_wait_time specifies how long to wait to obtain a
61 * DHCP lease before giving up on that NCU and moving on to the next/lower
64 uint64_t ncu_wait_time
= NCU_WAIT_TIME_DEFAULT
;
67 * Specifies if this is the first time the NCP has been enabled. True
68 * on startup so that we can differentiate between when we start up
69 * with a given NCP versus when we are asked to reenable it.
71 boolean_t initial_ncp_enable
= B_TRUE
;
74 * nwamd_ncp_handle_enable_event() should be called in the event handling
75 * loop in response to an _ENABLE event, triggered as a result of an
76 * nwam_ncp_enable() call from a libnwam consumer. To enable the new NCP,
77 * we first call nwamd_fini_ncus() on the old NCP. This results in enqueueing
78 * of a set of _FINI events for each NCU. These events are handled and in
79 * order to tear down config, (online*, uninitialized) state change events
80 * are created and consumed directly by the fini event handler (these events
81 * are not enqueued as this would result in state events for the old NCP
82 * appearing after the new NCP has been enabled. After the _FINI events are
83 * enqueued, we enqueue an NCP _OBJECT_STATE event for the new NCP. Since
84 * it is enqueued after the _FINI events, we are guaranteed no events for the
85 * old NCP will appear after the new NCP is activated.
88 nwamd_ncp_handle_enable_event(nwamd_event_t event
)
90 char *new_ncp
= event
->event_object
;
91 nwam_ncp_handle_t new_ncph
;
94 if (new_ncp
[0] == '\0')
97 (void) pthread_mutex_lock(&active_ncp_mutex
);
98 if (strcmp(active_ncp
, new_ncp
) == 0 && !initial_ncp_enable
) {
99 nlog(LOG_DEBUG
, "nwamd_ncp_handle_enable_event: "
100 "%s is already active", new_ncp
);
101 (void) pthread_mutex_unlock(&active_ncp_mutex
);
104 (void) pthread_mutex_unlock(&active_ncp_mutex
);
106 nlog(LOG_DEBUG
, "nwamd_ncp_handle_enable_event: activating NCP %s",
110 * To activate new NCP, run nwamd_fini_ncus(), reset the active
111 * priority-group, set the active_ncp property and refresh the
112 * daemon. The refresh action will trigger a re-read of the NCUs
113 * for the activated NCP.
118 if ((err
= nwam_ncp_read(new_ncp
, 0, &new_ncph
))
119 == NWAM_ENTITY_NOT_FOUND
) {
120 err
= nwam_ncp_create(new_ncp
, 0, &new_ncph
);
123 if (err
== NWAM_SUCCESS
) {
124 nwam_ncp_free(new_ncph
);
125 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCP
, new_ncp
,
126 NWAM_STATE_ONLINE
, NWAM_AUX_STATE_ACTIVE
);
127 } else if (initial_ncp_enable
) {
129 * We weren't able to enable the NCP when nwamd starts up,
130 * retry in a few seconds.
132 nwamd_event_t retry_event
= nwamd_event_init_object_action
133 (NWAM_OBJECT_TYPE_NCP
, new_ncp
, NULL
, NWAM_ACTION_ENABLE
);
134 if (retry_event
== NULL
) {
135 nlog(LOG_ERR
, "nwamd_ncp_handle_enable_event: "
136 "could not create retry event to enable %s NCP",
141 nlog(LOG_ERR
, "nwamd_ncp_handle_enable_event: "
142 "failed to enable %s NCP, retrying in %d seconds",
143 new_ncp
, NWAMD_READONLY_RETRY_INTERVAL
);
144 nwamd_event_enqueue_timed(retry_event
,
145 NWAMD_READONLY_RETRY_INTERVAL
);
147 nlog(LOG_ERR
, "nwamd_ncp_handle_enable_event: error %s",
154 nwamd_ncp_handle_action_event(nwamd_event_t event
)
156 switch (event
->event_msg
->nwe_data
.nwe_object_action
.nwe_action
) {
157 case NWAM_ACTION_ENABLE
:
158 nwamd_ncp_handle_enable_event(event
);
160 case NWAM_ACTION_ADD
:
161 case NWAM_ACTION_DESTROY
:
165 nlog(LOG_INFO
, "nwam_ncp_handle_action_event: "
166 "unexpected action");
167 nwamd_event_do_not_send(event
);
173 * The only state events we create are (online, active) events which are
174 * generated as part of an NCP enable action (see above).
177 nwamd_ncp_handle_state_event(nwamd_event_t event
)
179 char *new_ncp
= event
->event_object
;
180 nwam_ncp_handle_t new_ncph
, old_ncph
;
183 /* The NCP to be activated should always exist. */
184 if ((err
= nwam_ncp_read(new_ncp
, 0, &new_ncph
)) != NWAM_SUCCESS
) {
185 nlog(LOG_ERR
, "nwamd_ncp_handle_state_event: "
186 "cannot read NCP %s: : %s", new_ncp
, nwam_strerror(err
));
187 nwamd_event_do_not_send(event
);
192 * To activate new NCP, reset the active priority-group, set the
193 * active_ncp property and refresh the daemon. The refresh action will
194 * trigger a re-read of the NCUs for the activated NCP.
196 (void) pthread_mutex_lock(&active_ncp_mutex
);
197 old_ncph
= active_ncph
;
198 active_ncph
= new_ncph
;
199 nwam_ncp_free(old_ncph
);
200 current_ncu_priority_group
= INVALID_PRIORITY_GROUP
;
201 (void) strlcpy(active_ncp
, event
->event_object
,
202 sizeof (active_ncp
));
203 (void) pthread_mutex_unlock(&active_ncp_mutex
);
204 (void) nwamd_set_string_property(OUR_FMRI
, OUR_PG
,
205 OUR_ACTIVE_NCP_PROP_NAME
, new_ncp
);
206 (void) smf_refresh_instance(OUR_FMRI
);
207 initial_ncp_enable
= B_FALSE
;
211 nwamd_ncp_action(const char *ncp
, nwam_action_t action
)
213 nwamd_event_t event
= nwamd_event_init_object_action
214 (NWAM_OBJECT_TYPE_NCP
, ncp
, NULL
, action
);
217 nwamd_event_enqueue(event
);
222 * Below this point are routines handling NCU prioritization
223 * policy for the active NCP.
226 struct priority_group_cbarg
{
227 uint64_t minpriority
;
228 uint64_t currpriority
;
232 /* Callback used to find next pg in NCP that is >= start_pg */
234 find_next_priority_group_cb(nwamd_object_t object
, void *data
)
236 struct priority_group_cbarg
*cbarg
= data
;
238 nwamd_ncu_t
*ncu
= object
->nwamd_object_data
;
240 if (ncu
->ncu_link
.nwamd_link_activation_mode
!=
241 NWAM_ACTIVATION_MODE_PRIORITIZED
)
244 priority
= ncu
->ncu_link
.nwamd_link_priority_group
;
246 if (priority
>= cbarg
->minpriority
&& priority
< cbarg
->currpriority
) {
247 cbarg
->found
= B_TRUE
;
248 cbarg
->currpriority
= priority
;
253 /* Set current_pg to next pg in NCP that is >= start_pg */
255 nwamd_ncp_find_next_priority_group(int64_t minpriority
,
256 int64_t *nextpriorityp
)
258 struct priority_group_cbarg cbarg
;
260 cbarg
.minpriority
= minpriority
;
261 cbarg
.currpriority
= MAXINT
;
262 cbarg
.found
= B_FALSE
;
264 (void) nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU
,
265 find_next_priority_group_cb
, &cbarg
);
268 nlog(LOG_DEBUG
, "nwamd_ncp_find_next_priority_group: "
269 "next priority group >= %lld is %lld",
270 minpriority
, cbarg
.currpriority
);
271 *nextpriorityp
= cbarg
.currpriority
;
274 nlog(LOG_DEBUG
, "nwamd_ncp_find_next_priority_group: "
275 "no priority groups >= %lld exist", minpriority
);
281 * Struct for walking NCUs in the selected priority group. We count
282 * how many of the exclusive, all and shared NCUs are online, and
283 * if activate_or_deactivate is true, we either activate or deactivate
284 * (depending on the value of activate) offline/online NCUs.
286 struct nwamd_ncu_check_walk_arg
{
287 boolean_t manual
; /* enable manual NCUs only */
288 int64_t priority_group
; /* interested priority-group for this walk */
289 uint64_t exclusive_ncus
;
290 uint64_t exclusive_online_ncus
;
291 uint64_t shared_ncus
;
292 uint64_t shared_online_ncus
;
294 uint64_t all_online_ncus
;
295 boolean_t activate_or_deactivate
;
300 * This function serves a number of purposes:
301 * - it supports activation/deactivation of manual NCUs in the current NCP
302 * (when wa->manual is true, wa->activate determines if we activate or
303 * deactivate the current NCU)
304 * - it supports checking/activation of a particular priority group in
305 * the active NCP. This works as follows:
307 * Count up numbers of exclusive, shared and all NCUs, and how many of each
308 * are online. If an NCU is waiting for IP address to be assigned, it is
309 * also considered online. If activate_or_deactivate is true, we also
310 * either activate (if activate is true) or deactivate prioritized NCUs
311 * that are offline or online.
314 nwamd_ncu_check_or_activate(nwamd_object_t object
, void *data
)
316 struct nwamd_ncu_check_walk_arg
*wa
= data
;
318 uint64_t priority_group
, priority_mode
;
319 nwamd_object_t if_obj
;
320 nwam_state_t state
, if_state
;
321 nwam_aux_state_t aux_state
, if_aux_state
;
324 state
= object
->nwamd_object_state
;
325 aux_state
= object
->nwamd_object_aux_state
;
326 name
= object
->nwamd_object_name
;
327 ncu
= object
->nwamd_object_data
;
329 /* skip NCUs in UNINITIALIZED state */
330 if (state
== NWAM_STATE_UNINITIALIZED
) {
331 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
332 "skipping uninitialized ncu %s", name
);
335 if (!wa
->manual
&& wa
->priority_group
== INVALID_PRIORITY_GROUP
)
338 if (ncu
->ncu_type
!= NWAM_NCU_TYPE_LINK
) {
339 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
340 "skipping interface NCU %s", name
);
343 if (!wa
->manual
&& ncu
->ncu_link
.nwamd_link_activation_mode
!=
344 NWAM_ACTIVATION_MODE_PRIORITIZED
) {
345 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
346 "skipping non-prioritized NCU %s", name
);
349 if (wa
->manual
&& ncu
->ncu_link
.nwamd_link_activation_mode
!=
350 NWAM_ACTIVATION_MODE_MANUAL
) {
351 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
352 "skipping non-manual NCU %s", name
);
356 priority_group
= ncu
->ncu_link
.nwamd_link_priority_group
;
357 priority_mode
= ncu
->ncu_link
.nwamd_link_priority_mode
;
358 /* Only work with NCUs in the requested priority-group */
359 if (!wa
->manual
&& priority_group
!= wa
->priority_group
) {
360 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
361 "skipping NCU %s in different priority-group", name
);
364 /* Get the state of the corresponding interface NCU */
365 if ((if_obj
= nwamd_ncu_object_find(NWAM_NCU_TYPE_INTERFACE
,
366 ncu
->ncu_name
)) == NULL
) {
367 nlog(LOG_ERR
, "nwamd_ncu_check_or_activate: "
368 "interface NCU of %s not found, skipping", name
);
371 if_state
= if_obj
->nwamd_object_state
;
372 if_aux_state
= if_obj
->nwamd_object_aux_state
;
373 nwamd_object_release(if_obj
);
375 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: %s ncu %s",
376 wa
->activate_or_deactivate
?
377 (wa
->activate
? "activating" : "deactivating") :
381 if (wa
->activate_or_deactivate
&& wa
->activate
) {
382 if (state
== NWAM_STATE_OFFLINE
&& ncu
->ncu_enabled
) {
383 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
384 "moving NCU %s to offline* from offline",
386 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
387 name
, NWAM_STATE_OFFLINE_TO_ONLINE
,
388 NWAM_AUX_STATE_INITIALIZED
);
390 if (state
!= NWAM_STATE_DISABLED
&&
392 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
393 "moving NCU %s to online* (disabling)",
395 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
396 name
, NWAM_STATE_ONLINE_TO_OFFLINE
,
397 NWAM_AUX_STATE_MANUAL_DISABLE
);
402 switch (priority_mode
) {
403 case NWAM_PRIORITY_MODE_EXCLUSIVE
:
404 wa
->exclusive_ncus
++;
405 if (state
== NWAM_STATE_ONLINE
&&
406 (if_state
== NWAM_STATE_ONLINE
||
407 if_aux_state
== NWAM_AUX_STATE_IF_WAITING_FOR_ADDR
))
408 wa
->exclusive_online_ncus
++;
411 * For exclusive NCUs, we activate offline NCUs as long
412 * as no other exclusive NCUs are active.
414 if (wa
->activate_or_deactivate
&& wa
->activate
) {
415 if (state
== NWAM_STATE_OFFLINE
&&
416 wa
->exclusive_online_ncus
== 0) {
417 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
418 "moving NCU %s to offline* from offline",
420 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
421 name
, NWAM_STATE_OFFLINE_TO_ONLINE
,
422 NWAM_AUX_STATE_INITIALIZED
);
425 if (wa
->activate_or_deactivate
&& !wa
->activate
) {
426 if (aux_state
!= NWAM_AUX_STATE_CONDITIONS_NOT_MET
) {
427 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
428 "deactivating NCU %s", name
);
429 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
430 name
, NWAM_STATE_ONLINE_TO_OFFLINE
,
431 NWAM_AUX_STATE_CONDITIONS_NOT_MET
);
435 * If we are activating or checking the priority group and
436 * too many exclusive NCUs are online, take this NCU down.
438 if ((wa
->activate_or_deactivate
&& wa
->activate
) ||
439 !wa
->activate_or_deactivate
) {
440 if (state
== NWAM_STATE_ONLINE
&&
441 if_state
== NWAM_STATE_ONLINE
&&
442 wa
->exclusive_online_ncus
> 1) {
443 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
444 "moving NCU %s to online* since another "
445 "NCU is already active",
447 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
448 name
, NWAM_STATE_ONLINE_TO_OFFLINE
,
449 NWAM_AUX_STATE_CONDITIONS_NOT_MET
);
453 case NWAM_PRIORITY_MODE_SHARED
:
455 if (state
== NWAM_STATE_ONLINE
&&
456 (if_state
== NWAM_STATE_ONLINE
||
457 if_aux_state
== NWAM_AUX_STATE_IF_WAITING_FOR_ADDR
))
458 wa
->shared_online_ncus
++;
460 if (wa
->activate_or_deactivate
&& wa
->activate
) {
461 if (state
== NWAM_STATE_OFFLINE
) {
462 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
463 "activating NCU %s", name
);
464 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
465 name
, NWAM_STATE_OFFLINE_TO_ONLINE
,
466 NWAM_AUX_STATE_INITIALIZED
);
469 if (wa
->activate_or_deactivate
&& !wa
->activate
) {
470 if (aux_state
!= NWAM_AUX_STATE_CONDITIONS_NOT_MET
) {
471 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
472 "deactivating NCU %s", name
);
473 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
474 name
, NWAM_STATE_ONLINE_TO_OFFLINE
,
475 NWAM_AUX_STATE_CONDITIONS_NOT_MET
);
479 case NWAM_PRIORITY_MODE_ALL
:
481 if (state
== NWAM_STATE_ONLINE
&&
482 (if_state
== NWAM_STATE_ONLINE
||
483 if_aux_state
== NWAM_AUX_STATE_IF_WAITING_FOR_ADDR
))
484 wa
->all_online_ncus
++;
487 * For "all" NCUs, activate/deactivate all offline/online
490 if (wa
->activate_or_deactivate
&& wa
->activate
) {
491 if (state
== NWAM_STATE_OFFLINE
) {
492 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
493 "activating NCU %s", name
);
494 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
495 name
, NWAM_STATE_OFFLINE_TO_ONLINE
,
496 NWAM_AUX_STATE_INITIALIZED
);
499 if (wa
->activate_or_deactivate
&& !wa
->activate
) {
500 if (aux_state
!= NWAM_AUX_STATE_CONDITIONS_NOT_MET
) {
501 nlog(LOG_DEBUG
, "nwamd_ncu_check_or_activate: "
502 "deactivating NCU %s", name
);
503 nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU
,
504 name
, NWAM_STATE_ONLINE_TO_OFFLINE
,
505 NWAM_AUX_STATE_CONDITIONS_NOT_MET
);
511 nlog(LOG_ERR
, "nwamd_ncu_check_or_activate: "
512 "invalid priority-mode");
520 nwamd_ncp_activate_priority_group(int64_t priority
)
522 struct nwamd_ncu_check_walk_arg wa
;
523 nwamd_event_t check_event
, priority_event
;
525 if (priority
== INVALID_PRIORITY_GROUP
)
528 (void) pthread_mutex_lock(&active_ncp_mutex
);
529 if (priority
== current_ncu_priority_group
) {
530 (void) pthread_mutex_unlock(&active_ncp_mutex
);
533 (void) pthread_mutex_unlock(&active_ncp_mutex
);
535 nlog(LOG_DEBUG
, "nwamd_ncp_activate_priority_group: "
536 "activating priority group %lld", priority
);
539 wa
.priority_group
= priority
;
540 wa
.exclusive_ncus
= 0;
541 wa
.exclusive_online_ncus
= 0;
543 wa
.shared_online_ncus
= 0;
545 wa
.all_online_ncus
= 0;
546 wa
.activate_or_deactivate
= B_TRUE
;
547 wa
.activate
= B_TRUE
;
549 if (nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU
,
550 nwamd_ncu_check_or_activate
, &wa
) != 0) {
551 nlog(LOG_ERR
, "nwamd_ncp_activate_priority_group: "
552 "nwamd_walk_objects() failed");
557 * Enqueue event to update current_ncu_priority_group and send to
558 * any event listeners.
560 priority_event
= nwamd_event_init_priority_group_change(priority
);
561 if (priority_event
== NULL
)
563 nwamd_event_enqueue(priority_event
);
566 * Now we've activated a new priority group, enqueue an event
567 * to check up on the state of this priority group.
569 check_event
= nwamd_event_init_ncu_check();
570 if (check_event
== NULL
)
572 nwamd_event_enqueue_timed(check_event
, ncu_wait_time
);
576 nwamd_ncp_deactivate_priority_group(int64_t priority
)
578 struct nwamd_ncu_check_walk_arg wa
;
580 if (priority
== INVALID_PRIORITY_GROUP
)
583 nlog(LOG_DEBUG
, "nwamd_ncp_deactivate_priority_group: "
584 "deactivating priority group %lld", priority
);
587 wa
.priority_group
= priority
;
588 wa
.exclusive_ncus
= 0;
589 wa
.exclusive_online_ncus
= 0;
591 wa
.shared_online_ncus
= 0;
593 wa
.all_online_ncus
= 0;
594 wa
.activate_or_deactivate
= B_TRUE
;
595 wa
.activate
= B_FALSE
;
597 if (nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU
,
598 nwamd_ncu_check_or_activate
, &wa
) != 0) {
599 nlog(LOG_ERR
, "nwamd_ncp_deactivate_priority_group: "
600 "nwamd_walk_objects() failed");
606 * This function deactivates all priority groups at level 'priority' and lower
607 * (which is, numerically, all priorities >= priority).
610 nwamd_ncp_deactivate_priority_group_all(int64_t priority
)
612 if (priority
== INVALID_PRIORITY_GROUP
)
615 nlog(LOG_DEBUG
, "nwamd_ncp_deactivate_priority_group_all: "
616 "deactivating priority group less than or equal to %lld", priority
);
619 nwamd_ncp_deactivate_priority_group(priority
);
620 } while (nwamd_ncp_find_next_priority_group(priority
+ 1, &priority
));
624 * Returns 'true' if it found the highest priority group no higher then what
625 * is passed that should be activated and sets *priority to that.
628 nwamd_ncp_check_priority_group(int64_t *priority
)
630 struct nwamd_ncu_check_walk_arg wa
;
631 boolean_t conditions_met
= B_FALSE
;
633 nlog(LOG_DEBUG
, "nwamd_ncp_check_priority_group: "
634 "checking priority group %lld", *priority
);
636 if (*priority
== INVALID_PRIORITY_GROUP
) {
637 if (!nwamd_ncp_find_next_priority_group(0, priority
))
641 while (!conditions_met
) {
642 (void) memset(&wa
, 0, sizeof (wa
));
644 wa
.priority_group
= *priority
;
645 wa
.activate_or_deactivate
= B_FALSE
;
647 if (nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU
,
648 nwamd_ncu_check_or_activate
, &wa
) != 0) {
649 nlog(LOG_ERR
, "nwamd_ncp_check_priority_group: "
650 "nwamd_walk_objects() failed");
655 * Are activation conditons satisifed? In other words:
656 * - exactly one of the exclusive NCUs is online
657 * - 1 or more shared NCUs are online
658 * - all of the all NCUs are online.
659 * If any of these is untrue, conditions are not satisfied.
661 conditions_met
= B_TRUE
;
662 if (wa
.exclusive_ncus
> 0 && wa
.exclusive_online_ncus
!= 1)
663 conditions_met
= B_FALSE
;
664 if (wa
.shared_ncus
> 0 && wa
.shared_online_ncus
== 0)
665 conditions_met
= B_FALSE
;
666 if (wa
.all_ncus
> 0 && wa
.all_ncus
!= wa
.all_online_ncus
)
667 conditions_met
= B_FALSE
;
668 if (wa
.exclusive_online_ncus
== 0 &&
669 wa
.shared_online_ncus
== 0 && wa
.all_online_ncus
== 0)
670 conditions_met
= B_FALSE
;
672 if (conditions_met
) {
676 * If there is a next pg, activate it. If not, do
677 * nothing - we're stuck here unless an event occurs
678 * for our or a higher pg.
680 if (!nwamd_ncp_find_next_priority_group
681 (wa
.priority_group
+ 1, priority
)) {
682 nlog(LOG_DEBUG
, "ran out of prio groups");
691 nwamd_ncp_activate_manual_ncus(void)
693 struct nwamd_ncu_check_walk_arg wa
;
695 nlog(LOG_DEBUG
, "nwamd_ncp_activate_manual_ncus: activating NCUs");
698 wa
.activate_or_deactivate
= B_TRUE
;
699 wa
.activate
= B_TRUE
;
701 if (nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU
,
702 nwamd_ncu_check_or_activate
, &wa
) != 0) {
703 nlog(LOG_ERR
, "nwamd_ncp_activate_manual_ncus: "
704 "nwamd_walk_objects() failed");
710 nwamd_create_ncu_check_event(uint64_t when
)
712 nwamd_event_t check_event
= nwamd_event_init_ncu_check();
713 if (check_event
!= NULL
)
714 nwamd_event_enqueue_timed(check_event
, when
);