d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER START
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The contents of this file are subject to the terms of the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Common Development and Distribution License (the "License").
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You may not use this file except in compliance with the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * or http://www.opensolaris.org/os/licensing.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * See the License for the specific language governing permissions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and limitations under the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * When distributing Covered Code, include this CDDL HEADER in each
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If applicable, add the following below this CDDL HEADER, with the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * fields enclosed by brackets "[]" replaced with your own identifying
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * information: Portions Copyright [yyyy] [name of copyright owner]
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER END
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Use is subject to license terms.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This RCM module adds support to the RCM framework for AGGR links
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <stdio.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <stdlib.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <string.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <errno.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <alloca.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/types.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/aggr.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <synch.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <assert.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <strings.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include "rcm_module.h"
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <libintl.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <libdllink.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <libdlaggr.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Definitions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#ifndef lint
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define _(x) gettext(x)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#else
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define _(x) x
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#endif
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Some generic well-knowns and defaults used in this module */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define RCM_LINK_PREFIX "SUNW_datalink" /* RCM datalink name prefix */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define RCM_LINK_RESOURCE_MAX (13 + LINKID_STR_WIDTH)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* AGGR link representation */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct dl_aggr {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct dl_aggr *da_next; /* next AGGR on the system */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct dl_aggr *da_prev; /* prev AGGR on the system */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t da_stale; /* AGGR link is stale? */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t da_aggrid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t da_lastport;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} dl_aggr_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* AGGR Cache state flags */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef enum {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_NODE_STALE = 0x01, /* stale cached data */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_NODE_NEW = 0x02, /* new cached nodes */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_NODE_OFFLINED = 0x04, /* node offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_AGGR_PORT_OFFLINED = 0x08, /* aggr port offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_AGGR_CONSUMER_OFFLINED = 0x10 /* consumers offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} cache_node_state_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Network Cache lookup options */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define CACHE_NO_REFRESH 0x1 /* cache refresh not needed */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define CACHE_REFRESH 0x2 /* refresh cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Cache element. It is used to keep a list of links on the system and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * their associated aggregations.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct link_cache {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct link_cache *vc_next; /* next cached resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct link_cache *vc_prev; /* prev cached resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *vc_resource; /* resource name */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t vc_linkid; /* linkid */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *vc_aggr; /* AGGR on this link */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_node_state_t vc_state; /* cache state flags */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} link_cache_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Global cache for network AGGRs
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t cache_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t cache_tail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic mutex_t cache_lock;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic dl_aggr_t aggr_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic dl_aggr_t aggr_tail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic mutex_t aggr_list_lock;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int events_registered = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeystatic dladm_handle_t dld_handle = NULL;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * RCM module interface prototypes
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_register(rcm_handle_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_unregister(rcm_handle_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_get_info(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, char **, nvlist_t *, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_suspend(rcm_handle_t *, char *, id_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz timespec_t *, uint_t, char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_resume(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_undo_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_remove(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_notify_event(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, nvlist_t *, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_configure_all(rcm_handle_t *, datalink_id_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Module private routines */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int cache_update(rcm_handle_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void cache_remove(link_cache_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void cache_insert(link_cache_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void node_free(link_cache_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void aggr_list_remove(dl_aggr_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void aggr_list_insert(dl_aggr_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void aggr_list_free();
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t *cache_lookup(rcm_handle_t *, char *, char);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_consumer_offline(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, uint_t, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_consumer_online(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, uint_t, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_offline_port(link_cache_t *, cache_node_state_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_online_port(link_cache_t *, boolean_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic char *aggr_usage(link_cache_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void aggr_log_err(datalink_id_t, char **, char *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_consumer_notify(rcm_handle_t *, datalink_id_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, uint_t, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Module-Private data */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct rcm_mod_ops aggr_ops =
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_MOD_OPS_VERSION,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_register,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_unregister,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_get_info,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_suspend,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_resume,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_offline,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_undo_offline,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_remove,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz NULL,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz NULL,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_notify_event
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_init() - Update registrations, and return the ops structure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstruct rcm_mod_ops *
d62bc4badc1c1f1549c961cfb8b420e650e1272byzrcm_mod_init(void)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems dladm_status_t status;
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems char errmsg[DLADM_STRSIZE];
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: mod_init\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_head.vc_next = &cache_tail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_head.vc_prev = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_tail.vc_prev = &cache_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_tail.vc_next = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_init(&cache_lock, 0, NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_head.da_next = &aggr_tail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_head.da_prev = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_tail.da_prev = &aggr_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_tail.da_next = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_init(&aggr_list_lock, NULL, NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems if ((status = dladm_open(&dld_handle)) != DLADM_STATUS_OK) {
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems rcm_log_message(RCM_WARNING,
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems "AGGR: mod_init failed: cannot open datalink handle: %s\n",
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems dladm_status2str(status, errmsg));
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems return (NULL);
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems }
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Return the ops vectors */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (&aggr_ops);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_info() - Return a string describing this module.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzconst char *
d62bc4badc1c1f1549c961cfb8b420e650e1272byzrcm_mod_info(void)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: mod_info\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
648495d6a097a39eaebc7e56d25f2463ff3bba65vikram return ("AGGR module version 1.1");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_fini() - Destroy the network AGGR cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
d62bc4badc1c1f1549c961cfb8b420e650e1272byzrcm_mod_fini(void)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: mod_fini\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Note that aggr_unregister() does not seem to be called anywhere,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * therefore we free the cache nodes here. In theory we should call
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_register_interest() for each node before we free it, the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * framework does not provide the rcm_handle to allow us to do so.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (node != &cache_tail) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_remove(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node_free(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_destroy(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_list_free();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_destroy(&aggr_list_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey dladm_close(dld_handle);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_list_insert - Insert an aggr in the global aggr list
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_list_insert(dl_aggr_t *aggr)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&aggr_list_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* insert at the head for best performance */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_next = aggr_head.da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_prev = &aggr_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_next->da_prev = aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_prev->da_next = aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_list_remove - Remove an aggr from the global aggr list
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_list_remove(dl_aggr_t *aggr)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&aggr_list_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_next->da_prev = aggr->da_prev;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_prev->da_next = aggr->da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_next = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_prev = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_list_free()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&aggr_list_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = aggr_head.da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (aggr != &aggr_tail) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_list_remove(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = aggr_head.da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&aggr_list_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_register() - Make sure the cache is properly sync'ed, and its
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * registrations are in order.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_register(rcm_handle_t *hd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: register\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (cache_update(hd) < 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Need to register interest in all new resources
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * getting attached, so we get attach event notifications
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!events_registered) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_register_event(hd, RCM_RESOURCE_LINK_NEW, 0, NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_RESOURCE_LINK_NEW);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "AGGR: registered %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_RESOURCE_LINK_NEW);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz events_registered++;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_unregister() - Walk the cache, unregistering all the networks.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_unregister(rcm_handle_t *hd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: unregister\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Walk the cache, unregistering everything */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (node != &cache_tail) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_unregister_interest(hd, node->vc_resource, 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* unregister failed for whatever reason */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_remove(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node_free(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_list_free();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Unregister interest in all new resources
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (events_registered) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_unregister_event(hd, RCM_RESOURCE_LINK_NEW, 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_RESOURCE_LINK_NEW);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "AGGR: unregistered %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_RESOURCE_LINK_NEW);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz events_registered--;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_offline() - Offline AGGRs on a specific link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **errorp, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: offline(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Lock the cache and lookup the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_lookup(hd, rsrc, CACHE_REFRESH);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* should not happen because the resource is registered. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(DATALINK_INVALID_LINKID, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "offline, unrecognized resource");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this given link is the only port in the aggregation, inform
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * VLANs and IP interfaces on associated AGGRs to be offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node->vc_aggr->da_lastport == node->vc_linkid) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_consumer_offline(hd, node, errorp, flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz depend_info) == RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: consumers agreed on offline\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "consumers offline failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if it's a query */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (flags & RCM_QUERY) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: offline query succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_offline_port(node, CACHE_NODE_OFFLINED) != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp, "offline port failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: Offline succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_undo_offline() - Undo offline of a previously offlined link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_undo_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **errorp, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t up;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: online(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(DATALINK_INVALID_LINKID, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "undo offline, unrecognized resource");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = ENOENT;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if no attempt should be made to online the link here */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!(node->vc_state & CACHE_NODE_OFFLINED)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp, "resource not offlined");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = ENOTSUP;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_online_port(node, &up) != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp, "online failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform VLANs and IP interfaces on associated AGGRs to be online
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!up)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_consumer_online(hd, node, errorp, flags, depend_info) ==
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "AGGR: Consumers agree on online");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: Consumers online failed (%s)\n"), rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state &= ~CACHE_NODE_OFFLINED;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: online succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_offline_port(link_cache_t *node, cache_node_state_t state)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errmsg[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_aggr_port_attr_db_t port;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_offline_port %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = node->vc_aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to remove the given port from the AGGR or delete the AGGR
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr->da_lastport == node->vc_linkid) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: delete aggregation %u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_delete(dld_handle, aggr->da_aggrid,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: remove port (%s) from aggregation %u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz port.lp_linkid = node->vc_linkid;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_remove(dld_handle, aggr->da_aggrid, 1,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey &port, DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR offline port failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid, dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: AGGR offline port succeeded (%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state |= (CACHE_AGGR_PORT_OFFLINED | state);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_online_port(link_cache_t *node, boolean_t *up)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errmsg[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_aggr_port_attr_db_t port;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_online_port %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *up = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!(node->vc_state & CACHE_AGGR_PORT_OFFLINED))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Either add the port into the AGGR or recreate specific AGGR
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * depending on whether this link is the only port in the aggregation.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = node->vc_aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr->da_lastport == node->vc_linkid) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: delete aggregation %u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_up(dld_handle, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *up = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: add port (%s) to aggregation %u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz port.lp_linkid = node->vc_linkid;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_add(dld_handle, aggr->da_aggrid, 1, &port,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR online failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid, dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *up = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state &= ~CACHE_AGGR_PORT_OFFLINED;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_get_info() - Gather usage information for this resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_get_info(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **usagep, char **errorp, nvlist_t *props, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: get_info(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_lookup(hd, rsrc, CACHE_REFRESH);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_INFO,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: get_info(%s) unrecognized resource\n"), rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = ENOENT;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * *usagep will be freed by the caller.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *usagep = aggr_usage(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (*usagep == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* most likely malloc failure */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: get_info(%s) malloc failure\n"), rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = ENOMEM;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Set client/role properties */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) nvlist_add_string(props, RCM_CLIENT_NAME, "AGGR");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: get_info(%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc, *usagep);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_suspend() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_suspend(rcm_handle_t *hd, char *rsrc, id_t id, timespec_t *interval,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint_t flags, char **errorp, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: suspend(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_resume() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_resume(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **errorp, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: resume(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_remove() - remove a resource from cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_remove(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **errorp, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *exported;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int rv = RCM_SUCCESS;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: remove(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_INFO,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: remove(%s) unrecognized resource\n"), rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = ENOENT;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* remove the cached entry for the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_remove(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this link is not the only port in the associated aggregation,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the CACHE_AGGR_CONSUMER_OFFLINED flags won't be set.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node->vc_state & CACHE_AGGR_CONSUMER_OFFLINED) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = node->vc_aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz exported = alloca(RCM_LINK_RESOURCE_MAX);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(exported, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rv = rcm_notify_remove(hd, exported, flags, depend_info);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rv != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to notify remove dependent %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz exported);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node_free(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_notify_event - Project private implementation to receive new resource
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * events. It intercepts all new resource events. If the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * new resource is a network resource, pass up a notify
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * for it too. The new resource need not be cached, since
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * it is done at register again.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **errorp, nvlist_t *nvl, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz nvpair_t *nvp = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t linkid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint64_t id64;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t up;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int rv = RCM_SUCCESS;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: notify_event(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strcmp(rsrc, RCM_RESOURCE_LINK_NEW) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(DATALINK_INVALID_LINKID, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "unrecognized event");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errno = EINVAL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Update cache to reflect latest AGGRs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (cache_update(hd) < 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(DATALINK_INVALID_LINKID, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "private Cache update failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Process the nvlist for the event */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: process_nvlist\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strcmp(nvpair_name(nvp), RCM_NV_LINKID) != 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (nvpair_value_uint64(nvp, &id64) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(DATALINK_INVALID_LINKID, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "cannot get linkid");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz linkid = (datalink_id_t)id64;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_configure_all(hd, linkid, &up) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(linkid, errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "failed configuring AGGR links");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rv = RCM_FAILURE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Notify all VLAN and IP AGGR consumers */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (up && aggr_consumer_notify(hd, linkid, errorp, flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz depend_info) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(linkid, errorp, "consumer notify failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rv = RCM_FAILURE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: notify_event: link configuration complete\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_usage - Determine the usage of a link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The returned buffer is owned by caller, and the caller
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * must free it up when done.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic char *
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_usage(link_cache_t *node)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *buf;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz const char *fmt;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errmsg[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char name[MAXLINKNAMELEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz size_t bufsz;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: usage(%s)\n", node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node->vc_state & CACHE_NODE_OFFLINED)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz fmt = _("%s offlined");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz else
d62bc4badc1c1f1549c961cfb8b420e650e1272byz fmt = _("%s is part of AGGR ");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle, node->vc_linkid, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey NULL, NULL, name, sizeof (name))) != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: usage(%s) get port name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* space for resources and message */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz bufsz = MAXLINKNAMELEN + strlen(fmt) + strlen(name) + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((buf = malloc(bufsz)) == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: usage(%s) malloc failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, strerror(errno));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(buf, bufsz, fmt, name);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node->vc_state & CACHE_NODE_OFFLINED) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Nothing else to do */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: usage (%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey node->vc_aggr->da_aggrid, NULL, NULL, NULL, name,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey sizeof (name))) != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: usage(%s) get aggr %u name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, node->vc_aggr->da_aggrid,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) free(buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) strlcat(buf, name, bufsz);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: usage (%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource, buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Cache management routines, all cache management functions should be
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * be called with cache_lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_lookup() - Get a cache node for a resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Call with cache lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This ensures that the cache is consistent with the system state and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * returns a pointer to the cache element corresponding to the resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t *
d62bc4badc1c1f1549c961cfb8b420e650e1272byzcache_lookup(rcm_handle_t *hd, char *rsrc, char options)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: cache lookup(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (options & CACHE_REFRESH) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* drop lock since update locks cache again */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) cache_update(hd);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (; node != &cache_tail; node = node->vc_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strcmp(rsrc, node->vc_resource) == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: cache lookup succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * node_free - Free a node from the cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byznode_free(link_cache_t *node)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_insert - Insert a resource node in cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzcache_insert(link_cache_t *node)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* insert at the head for best performance */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_next = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_prev = &cache_head;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_next->vc_prev = node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_prev->vc_next = node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_remove() - Remove a resource node from cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Call with the cache_lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzcache_remove(link_cache_t *node)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_next->vc_prev = node->vc_prev;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_prev->vc_next = node->vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_next = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_prev = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_port_update(rcm_handle_t *hd, dl_aggr_t *aggr, datalink_id_t portid)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *rsrc;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret = -1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_port_update aggr:%u port:%u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid, portid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc = malloc(RCM_LINK_RESOURCE_MAX);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rsrc == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: resource malloc error(%s)\n"), strerror(errno));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, portid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: %s already registered (aggrid:%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state &= ~CACHE_NODE_STALE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(node->vc_linkid == portid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Update vc_aggr directly as only one aggregation can be
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * created on one port.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_aggr = aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: %s is a new resource (aggrid:%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = calloc(1, sizeof (link_cache_t));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: calloc: %s\n"), strerror(errno));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource = rsrc;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_aggr = aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_linkid = portid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state |= CACHE_NODE_NEW;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_insert(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct aggr_update_arg_s {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_handle_t *hd;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int retval;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} aggr_update_arg_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_update() - Update physical interface properties
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyaggr_update(dladm_handle_t handle, datalink_id_t aggrid, void *arg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_update_arg_t *aggr_update_argp = arg;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_handle_t *hd = aggr_update_argp->hd;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_aggr_grp_attr_t aggr_attr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errmsg[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t exist = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint32_t i;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret = -1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_update(%u)\n", aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&aggr_list_lock));
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_info(handle, aggrid, &aggr_attr,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: cannot get aggr information for %u error(%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggrid, dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DLADM_WALK_CONTINUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to find the aggr from the aggr list.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (aggr = aggr_head.da_next; aggr != &aggr_tail; aggr = aggr->da_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr->da_aggrid == aggr_attr.lg_linkid)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz exist = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((aggr = calloc(1, sizeof (dl_aggr_t))) == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("AGGR: malloc: %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz strerror(errno));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Update aggregation information. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_attr.lg_nports == 1)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_lastport = aggr_attr.lg_ports[0].lp_linkid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz else
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_lastport = DATALINK_INVALID_LINKID;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid = aggr_attr.lg_linkid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (i = 0; i < aggr_attr.lg_nports; i++) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t portid = (aggr_attr.lg_ports[i]).lp_linkid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_port_update(hd, aggr, portid) != 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!exist)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_list_insert(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_stale = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE3,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_update: succeeded(%u)\n", aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!exist && ret != 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr_attr.lg_ports);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_update_argp->retval = ret;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret == 0 ? DLADM_WALK_CONTINUE : DLADM_WALK_TERMINATE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_update_all() - Determine all AGGR links in the system
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_update_all(rcm_handle_t *hd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_update_arg_t arg = {NULL, 0};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_update_all\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(MUTEX_HELD(&cache_lock));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz arg.hd = hd;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey (void) dladm_walk_datalink_id(aggr_update, dld_handle, &arg,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (arg.retval);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_update() - Update cache with latest interface info
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzcache_update(rcm_handle_t *hd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node, *next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: cache_update\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&aggr_list_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* first we walk the entire aggr list, marking each entry stale */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (aggr = aggr_head.da_next; aggr != &aggr_tail; aggr = aggr->da_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_stale = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* then we walk the entire cache, marking each entry stale */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node = cache_head.vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (; node != &cache_tail; node = node->vc_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state |= CACHE_NODE_STALE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = aggr_update_all(hd);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Even aggr_update_all() fails, continue to delete all the stale
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * resources. First, unregister links that are not offlined and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * still in cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (node = cache_head.vc_next; node != &cache_tail; node = next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz next = node->vc_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (node->vc_state & CACHE_NODE_STALE) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) rcm_unregister_interest(hd, node->vc_resource,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: unregistered %s\n", node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cache_remove(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node_free(node);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!(node->vc_state & CACHE_NODE_NEW))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_register_interest(hd, node->vc_resource, 0,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz NULL) != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = -1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "AGGR: registered %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state &= ~CACHE_NODE_NEW;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = aggr_head.da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (aggr != &aggr_tail) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *next = aggr->da_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* delete stale AGGRs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr->da_stale) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_list_remove(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&aggr_list_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_log_err() - RCM error log wrapper
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_log_err(datalink_id_t linkid, char **errorp, char *errmsg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char link[MAXLINKNAMELEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errstr[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int len;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz const char *errfmt;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *error;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link[0] = '\0';
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (linkid != DATALINK_INVALID_LINKID) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char rsrc[RCM_LINK_RESOURCE_MAX];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("AGGR: %s(%s)\n"), errmsg, rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle, linkid, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey NULL, NULL, link, sizeof (link))) != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: cannot get link name of (%s) %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc, dladm_status2str(status, errstr));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("AGGR: %s\n"), errmsg);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errfmt = strlen(link) > 0 ? _("AGGR: %s(%s)") : _("AGGR: %s");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz len = strlen(errfmt) + strlen(errmsg) + MAXLINKNAMELEN + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((error = malloc(len)) != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strlen(link) > 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) sprintf(error, errfmt, errmsg, link);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz else
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) sprintf(error, errfmt, errmsg);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (errorp != NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *errorp = error;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_offline()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Offline AGGR consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_offline(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint_t flags, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char rsrc[RCM_LINK_RESOURCE_MAX];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_offline %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, node->vc_aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform associated VLANs and IP interfaces to be offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = rcm_request_offline(hd, rsrc, flags, depend_info);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (ret != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: rcm_request_offline failed (%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state |= CACHE_AGGR_CONSUMER_OFFLINED;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_offline done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_online()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * online AGGR consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_online(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint_t flags, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char rsrc[RCM_LINK_RESOURCE_MAX];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_online %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!(node->vc_state & CACHE_AGGR_CONSUMER_OFFLINED)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: no consumers offlined (%s)\n", node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (RCM_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, node->vc_aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = rcm_notify_online(hd, rsrc, flags, depend_info);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (ret != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: rcm_notify_online failed (%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz node->vc_state &= ~CACHE_AGGR_CONSUMER_OFFLINED;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_online done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Send RCM_RESOURCE_LINK_NEW events to other modules about new aggregations.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Return 0 on success, -1 on failure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_notify_new_aggr(rcm_handle_t *hd, char *rsrc)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_aggr_t *aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz nvlist_t *nvl = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint64_t id;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t is_only_port;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int ret = -1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_notify_new_aggr (%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the interface in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_notify_new_aggr() unrecognized resource (%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (nvlist_alloc(&nvl, 0, 0) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to allocate nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr = node->vc_aggr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz is_only_port = (aggr->da_lastport == node->vc_linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (is_only_port) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_notify_new_aggr add (%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz id = aggr->da_aggrid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (nvlist_add_uint64(nvl, RCM_NV_LINKID, id) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to construct nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this link is not the only port in the aggregation, the aggregation
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * is not new. No need to inform other consumers in that case.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (is_only_port && rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0, nvl, NULL) != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to notify %s event for %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_RESOURCE_LINK_NEW, node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ret = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(nvl);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_notify() - Notify consumers of AGGRs coming back online.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_notify(rcm_handle_t *hd, datalink_id_t linkid, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint_t flags, rcm_info_t **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char rsrc[RCM_LINK_RESOURCE_MAX];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz RCM_LINK_PREFIX, linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_consumer_notify(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform IP and VLAN consumers to be online.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_notify_new_aggr(hd, rsrc) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH)) != NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) aggr_offline_port(node, CACHE_NODE_STALE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_notify_new_aggr failed(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (-1);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_notify succeeded\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct aggr_configure_arg {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t portid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int retval;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t up;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} aggr_configure_arg_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyaggr_configure(dladm_handle_t handle, datalink_id_t aggrid, void *arg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_configure_arg_t *aggr_configure_argp = arg;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t portid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_aggr_grp_attr_t aggr_attr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_aggr_port_attr_db_t port_attr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_status_t status;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint32_t flags;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char errmsg[DLADM_STRSIZE];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int i;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_datalink_id2info(handle, aggrid, &flags, NULL, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey NULL, 0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DLADM_WALK_CONTINUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_info(handle, aggrid, &aggr_attr, DLADM_OPT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DLADM_WALK_CONTINUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz portid = aggr_configure_argp->portid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (i = 0; i < aggr_attr.lg_nports; i++)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_attr.lg_ports[i].lp_linkid == portid)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (i == aggr_attr.lg_nports) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The aggregation doesn't contain this port.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr_attr.lg_ports);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DLADM_WALK_CONTINUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this aggregation already exists, add this port to this
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggregation, otherwise, bring up this aggregation.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (flags & DLADM_OPT_ACTIVE) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE3,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_configure dladm_aggr_add port %u (%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz portid, aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz port_attr.lp_linkid = portid;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_add(handle, aggrid, 1, &port_attr,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE3,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_configure dladm_aggr_up (%u)\n", aggrid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_up(handle, aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (status != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Print a warning message and continue to UP other AGGRs.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_WARNING,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR online failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggrid, dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_configure_argp->retval = -1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else if (!(flags & DLADM_OPT_ACTIVE)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_configure_argp->up = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(aggr_attr.lg_ports);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DLADM_WALK_TERMINATE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_configure_all() - Configure AGGRs over a physical link after it attaches
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_configure_all(rcm_handle_t *hd, datalink_id_t linkid, boolean_t *up)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char rsrc[RCM_LINK_RESOURCE_MAX];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz link_cache_t *node;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_configure_arg_t arg = {DATALINK_INVALID_LINKID, 0, B_FALSE};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *up = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the AGGRs in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, sizeof (rsrc), "%s/%u", RCM_LINK_PREFIX, linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_configure_all(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if the link is new or was previously offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_lock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) != NULL) &&
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (!(node->vc_state & CACHE_NODE_OFFLINED))) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: Skipping configured link(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) mutex_unlock(&cache_lock);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz arg.portid = linkid;
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey (void) dladm_walk_datalink_id(aggr_configure, dld_handle, &arg,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, DLADM_OPT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (arg.retval == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *up = arg.up;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_configure_all succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (arg.retval);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}