1*1cfa752fSRamaswamy Tummala /* 2*1cfa752fSRamaswamy Tummala * CDDL HEADER START 3*1cfa752fSRamaswamy Tummala * 4*1cfa752fSRamaswamy Tummala * The contents of this file are subject to the terms of the 5*1cfa752fSRamaswamy Tummala * Common Development and Distribution License (the "License"). 6*1cfa752fSRamaswamy Tummala * You may not use this file except in compliance with the License. 7*1cfa752fSRamaswamy Tummala * 8*1cfa752fSRamaswamy Tummala * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1cfa752fSRamaswamy Tummala * or http://www.opensolaris.org/os/licensing. 10*1cfa752fSRamaswamy Tummala * See the License for the specific language governing permissions 11*1cfa752fSRamaswamy Tummala * and limitations under the License. 12*1cfa752fSRamaswamy Tummala * 13*1cfa752fSRamaswamy Tummala * When distributing Covered Code, include this CDDL HEADER in each 14*1cfa752fSRamaswamy Tummala * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1cfa752fSRamaswamy Tummala * If applicable, add the following below this CDDL HEADER, with the 16*1cfa752fSRamaswamy Tummala * fields enclosed by brackets "[]" replaced with your own identifying 17*1cfa752fSRamaswamy Tummala * information: Portions Copyright [yyyy] [name of copyright owner] 18*1cfa752fSRamaswamy Tummala * 19*1cfa752fSRamaswamy Tummala * CDDL HEADER END 20*1cfa752fSRamaswamy Tummala */ 21*1cfa752fSRamaswamy Tummala /* 22*1cfa752fSRamaswamy Tummala * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23*1cfa752fSRamaswamy Tummala */ 24*1cfa752fSRamaswamy Tummala 25*1cfa752fSRamaswamy Tummala /* 26*1cfa752fSRamaswamy Tummala * This RCM module adds support to the RCM framework for IBPART links 27*1cfa752fSRamaswamy Tummala */ 28*1cfa752fSRamaswamy Tummala 29*1cfa752fSRamaswamy Tummala #include <stdio.h> 30*1cfa752fSRamaswamy Tummala #include <stdlib.h> 31*1cfa752fSRamaswamy Tummala #include <string.h> 32*1cfa752fSRamaswamy Tummala #include <errno.h> 33*1cfa752fSRamaswamy Tummala #include <sys/types.h> 34*1cfa752fSRamaswamy Tummala #include <synch.h> 35*1cfa752fSRamaswamy Tummala #include <assert.h> 36*1cfa752fSRamaswamy Tummala #include <strings.h> 37*1cfa752fSRamaswamy Tummala #include "rcm_module.h" 38*1cfa752fSRamaswamy Tummala #include <libintl.h> 39*1cfa752fSRamaswamy Tummala #include <libdllink.h> 40*1cfa752fSRamaswamy Tummala #include <libdlib.h> 41*1cfa752fSRamaswamy Tummala #include <libdlpi.h> 42*1cfa752fSRamaswamy Tummala 43*1cfa752fSRamaswamy Tummala /* 44*1cfa752fSRamaswamy Tummala * Definitions 45*1cfa752fSRamaswamy Tummala */ 46*1cfa752fSRamaswamy Tummala #ifndef lint 47*1cfa752fSRamaswamy Tummala #define _(x) gettext(x) 48*1cfa752fSRamaswamy Tummala #else 49*1cfa752fSRamaswamy Tummala #define _(x) x 50*1cfa752fSRamaswamy Tummala #endif 51*1cfa752fSRamaswamy Tummala 52*1cfa752fSRamaswamy Tummala /* Some generic well-knowns and defaults used in this module */ 53*1cfa752fSRamaswamy Tummala #define RCM_LINK_PREFIX "SUNW_datalink" /* RCM datalink name prefix */ 54*1cfa752fSRamaswamy Tummala #define RCM_LINK_RESOURCE_MAX (13 + LINKID_STR_WIDTH) 55*1cfa752fSRamaswamy Tummala 56*1cfa752fSRamaswamy Tummala /* IBPART link flags */ 57*1cfa752fSRamaswamy Tummala typedef enum { 58*1cfa752fSRamaswamy Tummala IBPART_OFFLINED = 0x1, 59*1cfa752fSRamaswamy Tummala IBPART_CONSUMER_OFFLINED = 0x2, 60*1cfa752fSRamaswamy Tummala IBPART_STALE = 0x4 61*1cfa752fSRamaswamy Tummala } ibpart_flag_t; 62*1cfa752fSRamaswamy Tummala 63*1cfa752fSRamaswamy Tummala /* link representation */ 64*1cfa752fSRamaswamy Tummala typedef struct dl_ibpart { 65*1cfa752fSRamaswamy Tummala struct dl_ibpart *dlib_next; /* next IBPART on this link */ 66*1cfa752fSRamaswamy Tummala struct dl_ibpart *dlib_prev; /* prev IBPART on this link */ 67*1cfa752fSRamaswamy Tummala datalink_id_t dlib_ibpart_id; 68*1cfa752fSRamaswamy Tummala ibpart_flag_t dlib_flags; /* IBPART link flags */ 69*1cfa752fSRamaswamy Tummala } dl_ibpart_t; 70*1cfa752fSRamaswamy Tummala 71*1cfa752fSRamaswamy Tummala /* IBPART Cache state flags */ 72*1cfa752fSRamaswamy Tummala typedef enum { 73*1cfa752fSRamaswamy Tummala CACHE_NODE_STALE = 0x1, /* stale cached data */ 74*1cfa752fSRamaswamy Tummala CACHE_NODE_NEW = 0x2, /* new cached nodes */ 75*1cfa752fSRamaswamy Tummala CACHE_NODE_OFFLINED = 0x4 /* nodes offlined */ 76*1cfa752fSRamaswamy Tummala } cache_node_state_t; 77*1cfa752fSRamaswamy Tummala 78*1cfa752fSRamaswamy Tummala /* Network Cache lookup options */ 79*1cfa752fSRamaswamy Tummala #define CACHE_NO_REFRESH 0x1 /* cache refresh not needed */ 80*1cfa752fSRamaswamy Tummala #define CACHE_REFRESH 0x2 /* refresh cache */ 81*1cfa752fSRamaswamy Tummala 82*1cfa752fSRamaswamy Tummala /* Cache element */ 83*1cfa752fSRamaswamy Tummala typedef struct link_cache { 84*1cfa752fSRamaswamy Tummala struct link_cache *pc_next; /* next cached resource */ 85*1cfa752fSRamaswamy Tummala struct link_cache *pc_prev; /* prev cached resource */ 86*1cfa752fSRamaswamy Tummala char *pc_resource; /* resource name */ 87*1cfa752fSRamaswamy Tummala datalink_id_t pc_linkid; /* linkid */ 88*1cfa752fSRamaswamy Tummala dl_ibpart_t *pc_ibpart; /* IBPART list on this link */ 89*1cfa752fSRamaswamy Tummala cache_node_state_t pc_state; /* cache state flags */ 90*1cfa752fSRamaswamy Tummala } link_cache_t; 91*1cfa752fSRamaswamy Tummala 92*1cfa752fSRamaswamy Tummala /* 93*1cfa752fSRamaswamy Tummala * Global cache for network IBPARTs 94*1cfa752fSRamaswamy Tummala */ 95*1cfa752fSRamaswamy Tummala static link_cache_t cache_head; 96*1cfa752fSRamaswamy Tummala static link_cache_t cache_tail; 97*1cfa752fSRamaswamy Tummala static mutex_t cache_lock; 98*1cfa752fSRamaswamy Tummala static int events_registered = 0; 99*1cfa752fSRamaswamy Tummala 100*1cfa752fSRamaswamy Tummala static dladm_handle_t dld_handle = NULL; 101*1cfa752fSRamaswamy Tummala 102*1cfa752fSRamaswamy Tummala /* 103*1cfa752fSRamaswamy Tummala * RCM module interface prototypes 104*1cfa752fSRamaswamy Tummala */ 105*1cfa752fSRamaswamy Tummala static int ibpart_register(rcm_handle_t *); 106*1cfa752fSRamaswamy Tummala static int ibpart_unregister(rcm_handle_t *); 107*1cfa752fSRamaswamy Tummala static int ibpart_get_info(rcm_handle_t *, char *, id_t, uint_t, 108*1cfa752fSRamaswamy Tummala char **, char **, nvlist_t *, rcm_info_t **); 109*1cfa752fSRamaswamy Tummala static int ibpart_suspend(rcm_handle_t *, char *, id_t, 110*1cfa752fSRamaswamy Tummala timespec_t *, uint_t, char **, rcm_info_t **); 111*1cfa752fSRamaswamy Tummala static int ibpart_resume(rcm_handle_t *, char *, id_t, uint_t, 112*1cfa752fSRamaswamy Tummala char **, rcm_info_t **); 113*1cfa752fSRamaswamy Tummala static int ibpart_offline(rcm_handle_t *, char *, id_t, uint_t, 114*1cfa752fSRamaswamy Tummala char **, rcm_info_t **); 115*1cfa752fSRamaswamy Tummala static int ibpart_undo_offline(rcm_handle_t *, char *, id_t, 116*1cfa752fSRamaswamy Tummala uint_t, char **, rcm_info_t **); 117*1cfa752fSRamaswamy Tummala static int ibpart_remove(rcm_handle_t *, char *, id_t, uint_t, 118*1cfa752fSRamaswamy Tummala char **, rcm_info_t **); 119*1cfa752fSRamaswamy Tummala static int ibpart_notify_event(rcm_handle_t *, char *, id_t, 120*1cfa752fSRamaswamy Tummala uint_t, char **, nvlist_t *, rcm_info_t **); 121*1cfa752fSRamaswamy Tummala static int ibpart_configure(rcm_handle_t *, datalink_id_t); 122*1cfa752fSRamaswamy Tummala 123*1cfa752fSRamaswamy Tummala /* Module private routines */ 124*1cfa752fSRamaswamy Tummala static void cache_free(); 125*1cfa752fSRamaswamy Tummala static int cache_update(rcm_handle_t *); 126*1cfa752fSRamaswamy Tummala static void cache_remove(link_cache_t *); 127*1cfa752fSRamaswamy Tummala static void node_free(link_cache_t *); 128*1cfa752fSRamaswamy Tummala static void cache_insert(link_cache_t *); 129*1cfa752fSRamaswamy Tummala static link_cache_t *cache_lookup(rcm_handle_t *, char *, char); 130*1cfa752fSRamaswamy Tummala static int ibpart_consumer_offline(rcm_handle_t *, link_cache_t *, 131*1cfa752fSRamaswamy Tummala char **, uint_t, rcm_info_t **); 132*1cfa752fSRamaswamy Tummala static void ibpart_consumer_online(rcm_handle_t *, link_cache_t *, 133*1cfa752fSRamaswamy Tummala char **, uint_t, rcm_info_t **); 134*1cfa752fSRamaswamy Tummala static int ibpart_offline_ibpart(link_cache_t *, uint32_t, 135*1cfa752fSRamaswamy Tummala cache_node_state_t); 136*1cfa752fSRamaswamy Tummala static void ibpart_online_ibpart(link_cache_t *); 137*1cfa752fSRamaswamy Tummala static char *ibpart_usage(link_cache_t *); 138*1cfa752fSRamaswamy Tummala static void ibpart_log_err(datalink_id_t, char **, char *); 139*1cfa752fSRamaswamy Tummala static int ibpart_consumer_notify(rcm_handle_t *, datalink_id_t, 140*1cfa752fSRamaswamy Tummala char **, uint_t, rcm_info_t **); 141*1cfa752fSRamaswamy Tummala 142*1cfa752fSRamaswamy Tummala /* Module-Private data */ 143*1cfa752fSRamaswamy Tummala static struct rcm_mod_ops ibpart_ops = 144*1cfa752fSRamaswamy Tummala { 145*1cfa752fSRamaswamy Tummala RCM_MOD_OPS_VERSION, 146*1cfa752fSRamaswamy Tummala ibpart_register, 147*1cfa752fSRamaswamy Tummala ibpart_unregister, 148*1cfa752fSRamaswamy Tummala ibpart_get_info, 149*1cfa752fSRamaswamy Tummala ibpart_suspend, 150*1cfa752fSRamaswamy Tummala ibpart_resume, 151*1cfa752fSRamaswamy Tummala ibpart_offline, 152*1cfa752fSRamaswamy Tummala ibpart_undo_offline, 153*1cfa752fSRamaswamy Tummala ibpart_remove, 154*1cfa752fSRamaswamy Tummala NULL, 155*1cfa752fSRamaswamy Tummala NULL, 156*1cfa752fSRamaswamy Tummala ibpart_notify_event 157*1cfa752fSRamaswamy Tummala }; 158*1cfa752fSRamaswamy Tummala 159*1cfa752fSRamaswamy Tummala /* 160*1cfa752fSRamaswamy Tummala * rcm_mod_init() - Update registrations, and return the ops structure. 161*1cfa752fSRamaswamy Tummala */ 162*1cfa752fSRamaswamy Tummala struct rcm_mod_ops * 163*1cfa752fSRamaswamy Tummala rcm_mod_init(void) 164*1cfa752fSRamaswamy Tummala { 165*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 166*1cfa752fSRamaswamy Tummala dladm_status_t status; 167*1cfa752fSRamaswamy Tummala 168*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: mod_init\n"); 169*1cfa752fSRamaswamy Tummala 170*1cfa752fSRamaswamy Tummala cache_head.pc_next = &cache_tail; 171*1cfa752fSRamaswamy Tummala cache_head.pc_prev = NULL; 172*1cfa752fSRamaswamy Tummala cache_tail.pc_prev = &cache_head; 173*1cfa752fSRamaswamy Tummala cache_tail.pc_next = NULL; 174*1cfa752fSRamaswamy Tummala (void) mutex_init(&cache_lock, 0, NULL); 175*1cfa752fSRamaswamy Tummala 176*1cfa752fSRamaswamy Tummala if ((status = dladm_open(&dld_handle)) != DLADM_STATUS_OK) { 177*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 178*1cfa752fSRamaswamy Tummala "IBPART: mod_init failed: cannot open datalink " 179*1cfa752fSRamaswamy Tummala "handle: %s\n", dladm_status2str(status, errmsg)); 180*1cfa752fSRamaswamy Tummala return (NULL); 181*1cfa752fSRamaswamy Tummala } 182*1cfa752fSRamaswamy Tummala 183*1cfa752fSRamaswamy Tummala /* Return the ops vectors */ 184*1cfa752fSRamaswamy Tummala return (&ibpart_ops); 185*1cfa752fSRamaswamy Tummala } 186*1cfa752fSRamaswamy Tummala 187*1cfa752fSRamaswamy Tummala /* 188*1cfa752fSRamaswamy Tummala * rcm_mod_info() - Return a string describing this module. 189*1cfa752fSRamaswamy Tummala */ 190*1cfa752fSRamaswamy Tummala const char * 191*1cfa752fSRamaswamy Tummala rcm_mod_info(void) 192*1cfa752fSRamaswamy Tummala { 193*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: mod_info\n"); 194*1cfa752fSRamaswamy Tummala 195*1cfa752fSRamaswamy Tummala return ("IBPART module"); 196*1cfa752fSRamaswamy Tummala } 197*1cfa752fSRamaswamy Tummala 198*1cfa752fSRamaswamy Tummala /* 199*1cfa752fSRamaswamy Tummala * rcm_mod_fini() - Destroy the network IBPART cache. 200*1cfa752fSRamaswamy Tummala */ 201*1cfa752fSRamaswamy Tummala int 202*1cfa752fSRamaswamy Tummala rcm_mod_fini(void) 203*1cfa752fSRamaswamy Tummala { 204*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: mod_fini\n"); 205*1cfa752fSRamaswamy Tummala 206*1cfa752fSRamaswamy Tummala /* 207*1cfa752fSRamaswamy Tummala * Note that ibpart_unregister() does not seem to be called anywhere, 208*1cfa752fSRamaswamy Tummala * therefore we free the cache nodes here. In theory we should call 209*1cfa752fSRamaswamy Tummala * rcm_register_interest() for each node before we free it, the 210*1cfa752fSRamaswamy Tummala * framework does not provide the rcm_handle to allow us to do so. 211*1cfa752fSRamaswamy Tummala */ 212*1cfa752fSRamaswamy Tummala cache_free(); 213*1cfa752fSRamaswamy Tummala (void) mutex_destroy(&cache_lock); 214*1cfa752fSRamaswamy Tummala 215*1cfa752fSRamaswamy Tummala dladm_close(dld_handle); 216*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 217*1cfa752fSRamaswamy Tummala } 218*1cfa752fSRamaswamy Tummala 219*1cfa752fSRamaswamy Tummala /* 220*1cfa752fSRamaswamy Tummala * ibpart_register() - Make sure the cache is properly sync'ed, and its 221*1cfa752fSRamaswamy Tummala * registrations are in order. 222*1cfa752fSRamaswamy Tummala */ 223*1cfa752fSRamaswamy Tummala static int 224*1cfa752fSRamaswamy Tummala ibpart_register(rcm_handle_t *hd) 225*1cfa752fSRamaswamy Tummala { 226*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: register\n"); 227*1cfa752fSRamaswamy Tummala 228*1cfa752fSRamaswamy Tummala if (cache_update(hd) < 0) 229*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 230*1cfa752fSRamaswamy Tummala 231*1cfa752fSRamaswamy Tummala /* 232*1cfa752fSRamaswamy Tummala * Need to register interest in all new resources 233*1cfa752fSRamaswamy Tummala * getting attached, so we get attach event notifications 234*1cfa752fSRamaswamy Tummala */ 235*1cfa752fSRamaswamy Tummala if (!events_registered) { 236*1cfa752fSRamaswamy Tummala if (rcm_register_event(hd, RCM_RESOURCE_LINK_NEW, 0, NULL) 237*1cfa752fSRamaswamy Tummala != RCM_SUCCESS) { 238*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 239*1cfa752fSRamaswamy Tummala _("IBPART: failed to register %s\n"), 240*1cfa752fSRamaswamy Tummala RCM_RESOURCE_LINK_NEW); 241*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 242*1cfa752fSRamaswamy Tummala } else { 243*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART: registered %s\n", 244*1cfa752fSRamaswamy Tummala RCM_RESOURCE_LINK_NEW); 245*1cfa752fSRamaswamy Tummala events_registered++; 246*1cfa752fSRamaswamy Tummala } 247*1cfa752fSRamaswamy Tummala } 248*1cfa752fSRamaswamy Tummala 249*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 250*1cfa752fSRamaswamy Tummala } 251*1cfa752fSRamaswamy Tummala 252*1cfa752fSRamaswamy Tummala /* 253*1cfa752fSRamaswamy Tummala * ibpart_unregister() - Walk the cache, unregistering all the networks. 254*1cfa752fSRamaswamy Tummala */ 255*1cfa752fSRamaswamy Tummala static int 256*1cfa752fSRamaswamy Tummala ibpart_unregister(rcm_handle_t *hd) 257*1cfa752fSRamaswamy Tummala { 258*1cfa752fSRamaswamy Tummala link_cache_t *node; 259*1cfa752fSRamaswamy Tummala 260*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: unregister\n"); 261*1cfa752fSRamaswamy Tummala 262*1cfa752fSRamaswamy Tummala /* Walk the cache, unregistering everything */ 263*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 264*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 265*1cfa752fSRamaswamy Tummala while (node != &cache_tail) { 266*1cfa752fSRamaswamy Tummala if (rcm_unregister_interest(hd, node->pc_resource, 0) 267*1cfa752fSRamaswamy Tummala != RCM_SUCCESS) { 268*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 269*1cfa752fSRamaswamy Tummala _("IBPART: failed to unregister %s\n"), 270*1cfa752fSRamaswamy Tummala node->pc_resource); 271*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 272*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 273*1cfa752fSRamaswamy Tummala } 274*1cfa752fSRamaswamy Tummala cache_remove(node); 275*1cfa752fSRamaswamy Tummala node_free(node); 276*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 277*1cfa752fSRamaswamy Tummala } 278*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 279*1cfa752fSRamaswamy Tummala 280*1cfa752fSRamaswamy Tummala /* 281*1cfa752fSRamaswamy Tummala * Unregister interest in all new resources 282*1cfa752fSRamaswamy Tummala */ 283*1cfa752fSRamaswamy Tummala if (events_registered) { 284*1cfa752fSRamaswamy Tummala if (rcm_unregister_event(hd, RCM_RESOURCE_LINK_NEW, 0) 285*1cfa752fSRamaswamy Tummala != RCM_SUCCESS) { 286*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 287*1cfa752fSRamaswamy Tummala _("IBPART: failed to unregister %s\n"), 288*1cfa752fSRamaswamy Tummala RCM_RESOURCE_LINK_NEW); 289*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 290*1cfa752fSRamaswamy Tummala } else { 291*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART: unregistered %s\n", 292*1cfa752fSRamaswamy Tummala RCM_RESOURCE_LINK_NEW); 293*1cfa752fSRamaswamy Tummala events_registered--; 294*1cfa752fSRamaswamy Tummala } 295*1cfa752fSRamaswamy Tummala } 296*1cfa752fSRamaswamy Tummala 297*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 298*1cfa752fSRamaswamy Tummala } 299*1cfa752fSRamaswamy Tummala 300*1cfa752fSRamaswamy Tummala /* 301*1cfa752fSRamaswamy Tummala * ibpart_offline() - Offline IBPARTs on a specific node. 302*1cfa752fSRamaswamy Tummala */ 303*1cfa752fSRamaswamy Tummala static int 304*1cfa752fSRamaswamy Tummala ibpart_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 305*1cfa752fSRamaswamy Tummala char **errorp, rcm_info_t **info) 306*1cfa752fSRamaswamy Tummala { 307*1cfa752fSRamaswamy Tummala link_cache_t *node; 308*1cfa752fSRamaswamy Tummala 309*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: offline(%s)\n", rsrc); 310*1cfa752fSRamaswamy Tummala 311*1cfa752fSRamaswamy Tummala /* Lock the cache and lookup the resource */ 312*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 313*1cfa752fSRamaswamy Tummala node = cache_lookup(hd, rsrc, CACHE_REFRESH); 314*1cfa752fSRamaswamy Tummala if (node == NULL) { 315*1cfa752fSRamaswamy Tummala /* should not happen because the resource is registered. */ 316*1cfa752fSRamaswamy Tummala ibpart_log_err(node->pc_linkid, errorp, 317*1cfa752fSRamaswamy Tummala "unrecognized resource"); 318*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 319*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 320*1cfa752fSRamaswamy Tummala } 321*1cfa752fSRamaswamy Tummala 322*1cfa752fSRamaswamy Tummala /* 323*1cfa752fSRamaswamy Tummala * Inform consumers (IP interfaces) of associated IBPARTs to be offlined 324*1cfa752fSRamaswamy Tummala */ 325*1cfa752fSRamaswamy Tummala if (ibpart_consumer_offline(hd, node, errorp, flags, info) == 326*1cfa752fSRamaswamy Tummala RCM_SUCCESS) { 327*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, 328*1cfa752fSRamaswamy Tummala "IBPART: consumers agreed on offline\n"); 329*1cfa752fSRamaswamy Tummala } else { 330*1cfa752fSRamaswamy Tummala ibpart_log_err(node->pc_linkid, errorp, 331*1cfa752fSRamaswamy Tummala "consumers failed to offline"); 332*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 333*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 334*1cfa752fSRamaswamy Tummala } 335*1cfa752fSRamaswamy Tummala 336*1cfa752fSRamaswamy Tummala /* Check if it's a query */ 337*1cfa752fSRamaswamy Tummala if (flags & RCM_QUERY) { 338*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 339*1cfa752fSRamaswamy Tummala "IBPART: offline query succeeded(%s)\n", rsrc); 340*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 341*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 342*1cfa752fSRamaswamy Tummala } 343*1cfa752fSRamaswamy Tummala 344*1cfa752fSRamaswamy Tummala if (ibpart_offline_ibpart(node, IBPART_OFFLINED, CACHE_NODE_OFFLINED) != 345*1cfa752fSRamaswamy Tummala RCM_SUCCESS) { 346*1cfa752fSRamaswamy Tummala ibpart_online_ibpart(node); 347*1cfa752fSRamaswamy Tummala ibpart_log_err(node->pc_linkid, errorp, "offline failed"); 348*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 349*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 350*1cfa752fSRamaswamy Tummala } 351*1cfa752fSRamaswamy Tummala 352*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: Offline succeeded(%s)\n", rsrc); 353*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 354*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 355*1cfa752fSRamaswamy Tummala } 356*1cfa752fSRamaswamy Tummala 357*1cfa752fSRamaswamy Tummala /* 358*1cfa752fSRamaswamy Tummala * ibpart_undo_offline() - Undo offline of a previously offlined node. 359*1cfa752fSRamaswamy Tummala */ 360*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 361*1cfa752fSRamaswamy Tummala static int 362*1cfa752fSRamaswamy Tummala ibpart_undo_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 363*1cfa752fSRamaswamy Tummala char **errorp, rcm_info_t **info) 364*1cfa752fSRamaswamy Tummala { 365*1cfa752fSRamaswamy Tummala link_cache_t *node; 366*1cfa752fSRamaswamy Tummala 367*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: online(%s)\n", rsrc); 368*1cfa752fSRamaswamy Tummala 369*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 370*1cfa752fSRamaswamy Tummala node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH); 371*1cfa752fSRamaswamy Tummala if (node == NULL) { 372*1cfa752fSRamaswamy Tummala ibpart_log_err(DATALINK_INVALID_LINKID, errorp, "no such link"); 373*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 374*1cfa752fSRamaswamy Tummala errno = ENOENT; 375*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 376*1cfa752fSRamaswamy Tummala } 377*1cfa752fSRamaswamy Tummala 378*1cfa752fSRamaswamy Tummala /* Check if no attempt should be made to online the link here */ 379*1cfa752fSRamaswamy Tummala if (!(node->pc_state & CACHE_NODE_OFFLINED)) { 380*1cfa752fSRamaswamy Tummala ibpart_log_err(node->pc_linkid, errorp, "link not offlined"); 381*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 382*1cfa752fSRamaswamy Tummala errno = ENOTSUP; 383*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 384*1cfa752fSRamaswamy Tummala } 385*1cfa752fSRamaswamy Tummala 386*1cfa752fSRamaswamy Tummala ibpart_online_ibpart(node); 387*1cfa752fSRamaswamy Tummala 388*1cfa752fSRamaswamy Tummala /* 389*1cfa752fSRamaswamy Tummala * Inform IP interfaces on associated IBPARTs to be onlined 390*1cfa752fSRamaswamy Tummala */ 391*1cfa752fSRamaswamy Tummala ibpart_consumer_online(hd, node, errorp, flags, info); 392*1cfa752fSRamaswamy Tummala 393*1cfa752fSRamaswamy Tummala node->pc_state &= ~CACHE_NODE_OFFLINED; 394*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: online succeeded(%s)\n", rsrc); 395*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 396*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 397*1cfa752fSRamaswamy Tummala } 398*1cfa752fSRamaswamy Tummala 399*1cfa752fSRamaswamy Tummala static void 400*1cfa752fSRamaswamy Tummala ibpart_online_ibpart(link_cache_t *node) 401*1cfa752fSRamaswamy Tummala { 402*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 403*1cfa752fSRamaswamy Tummala dladm_status_t status; 404*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 405*1cfa752fSRamaswamy Tummala 406*1cfa752fSRamaswamy Tummala /* 407*1cfa752fSRamaswamy Tummala * Try to bring on all offlined IBPARTs 408*1cfa752fSRamaswamy Tummala */ 409*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 410*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 411*1cfa752fSRamaswamy Tummala if (!(ibpart->dlib_flags & IBPART_OFFLINED)) 412*1cfa752fSRamaswamy Tummala continue; 413*1cfa752fSRamaswamy Tummala 414*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: online DLID %d\n", 415*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id); 416*1cfa752fSRamaswamy Tummala if ((status = dladm_part_up(dld_handle, 417*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, 0)) != DLADM_STATUS_OK) { 418*1cfa752fSRamaswamy Tummala /* 419*1cfa752fSRamaswamy Tummala * Print a warning message and continue to online 420*1cfa752fSRamaswamy Tummala * other IBPARTs. 421*1cfa752fSRamaswamy Tummala */ 422*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 423*1cfa752fSRamaswamy Tummala _("IBPART: IBPART online failed (%u): %s\n"), 424*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, 425*1cfa752fSRamaswamy Tummala dladm_status2str(status, errmsg)); 426*1cfa752fSRamaswamy Tummala } else { 427*1cfa752fSRamaswamy Tummala ibpart->dlib_flags &= ~IBPART_OFFLINED; 428*1cfa752fSRamaswamy Tummala } 429*1cfa752fSRamaswamy Tummala } 430*1cfa752fSRamaswamy Tummala } 431*1cfa752fSRamaswamy Tummala 432*1cfa752fSRamaswamy Tummala static int 433*1cfa752fSRamaswamy Tummala ibpart_offline_ibpart(link_cache_t *node, uint32_t flags, 434*1cfa752fSRamaswamy Tummala cache_node_state_t state) 435*1cfa752fSRamaswamy Tummala { 436*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 437*1cfa752fSRamaswamy Tummala dladm_status_t status; 438*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 439*1cfa752fSRamaswamy Tummala 440*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_offline_ibpart " 441*1cfa752fSRamaswamy Tummala "(%s %u %u)\n", node->pc_resource, flags, state); 442*1cfa752fSRamaswamy Tummala 443*1cfa752fSRamaswamy Tummala /* 444*1cfa752fSRamaswamy Tummala * Try to delete all explicit created IBPART 445*1cfa752fSRamaswamy Tummala */ 446*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 447*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 448*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: offline DLID %d\n", 449*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id); 450*1cfa752fSRamaswamy Tummala if ((status = dladm_part_delete(dld_handle, 451*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, DLADM_OPT_ACTIVE)) != 452*1cfa752fSRamaswamy Tummala DLADM_STATUS_OK) { 453*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 454*1cfa752fSRamaswamy Tummala _("IBPART: IBPART offline failed (%u): %s\n"), 455*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, 456*1cfa752fSRamaswamy Tummala dladm_status2str(status, errmsg)); 457*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 458*1cfa752fSRamaswamy Tummala } else { 459*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 460*1cfa752fSRamaswamy Tummala "IBPART: IBPART offline succeeded(%u)\n", 461*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id); 462*1cfa752fSRamaswamy Tummala ibpart->dlib_flags |= flags; 463*1cfa752fSRamaswamy Tummala } 464*1cfa752fSRamaswamy Tummala } 465*1cfa752fSRamaswamy Tummala 466*1cfa752fSRamaswamy Tummala node->pc_state |= state; 467*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 468*1cfa752fSRamaswamy Tummala } 469*1cfa752fSRamaswamy Tummala 470*1cfa752fSRamaswamy Tummala /* 471*1cfa752fSRamaswamy Tummala * ibpart_get_info() - Gather usage information for this resource. 472*1cfa752fSRamaswamy Tummala */ 473*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 474*1cfa752fSRamaswamy Tummala int 475*1cfa752fSRamaswamy Tummala ibpart_get_info(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 476*1cfa752fSRamaswamy Tummala char **usagep, char **errorp, nvlist_t *props, rcm_info_t **info) 477*1cfa752fSRamaswamy Tummala { 478*1cfa752fSRamaswamy Tummala link_cache_t *node; 479*1cfa752fSRamaswamy Tummala 480*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: get_info(%s)\n", rsrc); 481*1cfa752fSRamaswamy Tummala 482*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 483*1cfa752fSRamaswamy Tummala node = cache_lookup(hd, rsrc, CACHE_REFRESH); 484*1cfa752fSRamaswamy Tummala if (node == NULL) { 485*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_INFO, 486*1cfa752fSRamaswamy Tummala _("IBPART: get_info(%s) unrecognized resource\n"), rsrc); 487*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 488*1cfa752fSRamaswamy Tummala errno = ENOENT; 489*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 490*1cfa752fSRamaswamy Tummala } 491*1cfa752fSRamaswamy Tummala 492*1cfa752fSRamaswamy Tummala *usagep = ibpart_usage(node); 493*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 494*1cfa752fSRamaswamy Tummala if (*usagep == NULL) { 495*1cfa752fSRamaswamy Tummala /* most likely malloc failure */ 496*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 497*1cfa752fSRamaswamy Tummala _("IBPART: get_info(%s) malloc failure\n"), rsrc); 498*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 499*1cfa752fSRamaswamy Tummala errno = ENOMEM; 500*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 501*1cfa752fSRamaswamy Tummala } 502*1cfa752fSRamaswamy Tummala 503*1cfa752fSRamaswamy Tummala /* Set client/role properties */ 504*1cfa752fSRamaswamy Tummala (void) nvlist_add_string(props, RCM_CLIENT_NAME, "IBPART"); 505*1cfa752fSRamaswamy Tummala 506*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: get_info(%s) info = %s\n", 507*1cfa752fSRamaswamy Tummala rsrc, *usagep); 508*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 509*1cfa752fSRamaswamy Tummala } 510*1cfa752fSRamaswamy Tummala 511*1cfa752fSRamaswamy Tummala /* 512*1cfa752fSRamaswamy Tummala * ibpart_suspend() - Nothing to do, always okay 513*1cfa752fSRamaswamy Tummala */ 514*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 515*1cfa752fSRamaswamy Tummala static int 516*1cfa752fSRamaswamy Tummala ibpart_suspend(rcm_handle_t *hd, char *rsrc, id_t id, timespec_t *interval, 517*1cfa752fSRamaswamy Tummala uint_t flags, char **errorp, rcm_info_t **info) 518*1cfa752fSRamaswamy Tummala { 519*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: suspend(%s)\n", rsrc); 520*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 521*1cfa752fSRamaswamy Tummala } 522*1cfa752fSRamaswamy Tummala 523*1cfa752fSRamaswamy Tummala /* 524*1cfa752fSRamaswamy Tummala * ibpart_resume() - Nothing to do, always okay 525*1cfa752fSRamaswamy Tummala */ 526*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 527*1cfa752fSRamaswamy Tummala static int 528*1cfa752fSRamaswamy Tummala ibpart_resume(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 529*1cfa752fSRamaswamy Tummala char **errorp, rcm_info_t **info) 530*1cfa752fSRamaswamy Tummala { 531*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: resume(%s)\n", rsrc); 532*1cfa752fSRamaswamy Tummala return (RCM_SUCCESS); 533*1cfa752fSRamaswamy Tummala } 534*1cfa752fSRamaswamy Tummala 535*1cfa752fSRamaswamy Tummala /* 536*1cfa752fSRamaswamy Tummala * ibpart_consumer_remove() 537*1cfa752fSRamaswamy Tummala * 538*1cfa752fSRamaswamy Tummala * Notify IBPART consumers to remove cache. 539*1cfa752fSRamaswamy Tummala */ 540*1cfa752fSRamaswamy Tummala static int 541*1cfa752fSRamaswamy Tummala ibpart_consumer_remove(rcm_handle_t *hd, link_cache_t *node, uint_t flags, 542*1cfa752fSRamaswamy Tummala rcm_info_t **info) 543*1cfa752fSRamaswamy Tummala { 544*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart = NULL; 545*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 546*1cfa752fSRamaswamy Tummala int ret = RCM_SUCCESS; 547*1cfa752fSRamaswamy Tummala 548*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_remove (%s)\n", 549*1cfa752fSRamaswamy Tummala node->pc_resource); 550*1cfa752fSRamaswamy Tummala 551*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 552*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 553*1cfa752fSRamaswamy Tummala 554*1cfa752fSRamaswamy Tummala /* 555*1cfa752fSRamaswamy Tummala * This will only be called when the offline operation 556*1cfa752fSRamaswamy Tummala * succeeds, so the IBPART consumers must have been offlined 557*1cfa752fSRamaswamy Tummala * at this point. 558*1cfa752fSRamaswamy Tummala */ 559*1cfa752fSRamaswamy Tummala assert(ibpart->dlib_flags & IBPART_CONSUMER_OFFLINED); 560*1cfa752fSRamaswamy Tummala 561*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", 562*1cfa752fSRamaswamy Tummala RCM_LINK_PREFIX, ibpart->dlib_ibpart_id); 563*1cfa752fSRamaswamy Tummala 564*1cfa752fSRamaswamy Tummala ret = rcm_notify_remove(hd, rsrc, flags, info); 565*1cfa752fSRamaswamy Tummala if (ret != RCM_SUCCESS) { 566*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 567*1cfa752fSRamaswamy Tummala _("IBPART: notify remove failed (%s)\n"), rsrc); 568*1cfa752fSRamaswamy Tummala break; 569*1cfa752fSRamaswamy Tummala } 570*1cfa752fSRamaswamy Tummala } 571*1cfa752fSRamaswamy Tummala 572*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_remove done\n"); 573*1cfa752fSRamaswamy Tummala return (ret); 574*1cfa752fSRamaswamy Tummala } 575*1cfa752fSRamaswamy Tummala 576*1cfa752fSRamaswamy Tummala /* 577*1cfa752fSRamaswamy Tummala * ibpart_remove() - remove a resource from cache 578*1cfa752fSRamaswamy Tummala */ 579*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 580*1cfa752fSRamaswamy Tummala static int 581*1cfa752fSRamaswamy Tummala ibpart_remove(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 582*1cfa752fSRamaswamy Tummala char **errorp, rcm_info_t **info) 583*1cfa752fSRamaswamy Tummala { 584*1cfa752fSRamaswamy Tummala link_cache_t *node; 585*1cfa752fSRamaswamy Tummala int rv; 586*1cfa752fSRamaswamy Tummala 587*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: remove(%s)\n", rsrc); 588*1cfa752fSRamaswamy Tummala 589*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 590*1cfa752fSRamaswamy Tummala node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH); 591*1cfa752fSRamaswamy Tummala if (node == NULL) { 592*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_INFO, 593*1cfa752fSRamaswamy Tummala _("IBPART: remove(%s) unrecognized resource\n"), rsrc); 594*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 595*1cfa752fSRamaswamy Tummala errno = ENOENT; 596*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 597*1cfa752fSRamaswamy Tummala } 598*1cfa752fSRamaswamy Tummala 599*1cfa752fSRamaswamy Tummala /* remove the cached entry for the resource */ 600*1cfa752fSRamaswamy Tummala cache_remove(node); 601*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 602*1cfa752fSRamaswamy Tummala 603*1cfa752fSRamaswamy Tummala rv = ibpart_consumer_remove(hd, node, flags, info); 604*1cfa752fSRamaswamy Tummala node_free(node); 605*1cfa752fSRamaswamy Tummala return (rv); 606*1cfa752fSRamaswamy Tummala } 607*1cfa752fSRamaswamy Tummala 608*1cfa752fSRamaswamy Tummala /* 609*1cfa752fSRamaswamy Tummala * ibpart_notify_event - Project private implementation to receive new resource 610*1cfa752fSRamaswamy Tummala * events. It intercepts all new resource events. If the 611*1cfa752fSRamaswamy Tummala * new resource is a network resource, pass up a notify 612*1cfa752fSRamaswamy Tummala * for it too. The new resource need not be cached, since 613*1cfa752fSRamaswamy Tummala * it is done at register again. 614*1cfa752fSRamaswamy Tummala */ 615*1cfa752fSRamaswamy Tummala /*ARGSUSED*/ 616*1cfa752fSRamaswamy Tummala static int 617*1cfa752fSRamaswamy Tummala ibpart_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, 618*1cfa752fSRamaswamy Tummala char **errorp, nvlist_t *nvl, rcm_info_t **info) 619*1cfa752fSRamaswamy Tummala { 620*1cfa752fSRamaswamy Tummala nvpair_t *nvp = NULL; 621*1cfa752fSRamaswamy Tummala datalink_id_t linkid; 622*1cfa752fSRamaswamy Tummala uint64_t id64; 623*1cfa752fSRamaswamy Tummala int rv = RCM_SUCCESS; 624*1cfa752fSRamaswamy Tummala 625*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, "IBPART: notify_event(%s)\n", rsrc); 626*1cfa752fSRamaswamy Tummala 627*1cfa752fSRamaswamy Tummala if (strcmp(rsrc, RCM_RESOURCE_LINK_NEW) != 0) { 628*1cfa752fSRamaswamy Tummala ibpart_log_err(DATALINK_INVALID_LINKID, errorp, 629*1cfa752fSRamaswamy Tummala "unrecognized event"); 630*1cfa752fSRamaswamy Tummala errno = EINVAL; 631*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 632*1cfa752fSRamaswamy Tummala } 633*1cfa752fSRamaswamy Tummala 634*1cfa752fSRamaswamy Tummala /* Update cache to reflect latest IBPARTs */ 635*1cfa752fSRamaswamy Tummala if (cache_update(hd) < 0) { 636*1cfa752fSRamaswamy Tummala ibpart_log_err(DATALINK_INVALID_LINKID, errorp, 637*1cfa752fSRamaswamy Tummala "private Cache update failed"); 638*1cfa752fSRamaswamy Tummala return (RCM_FAILURE); 639*1cfa752fSRamaswamy Tummala } 640*1cfa752fSRamaswamy Tummala 641*1cfa752fSRamaswamy Tummala /* 642*1cfa752fSRamaswamy Tummala * Try best to recover all configuration. 643*1cfa752fSRamaswamy Tummala */ 644*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART: process_nvlist\n"); 645*1cfa752fSRamaswamy Tummala while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 646*1cfa752fSRamaswamy Tummala if (strcmp(nvpair_name(nvp), RCM_NV_LINKID) != 0) 647*1cfa752fSRamaswamy Tummala continue; 648*1cfa752fSRamaswamy Tummala 649*1cfa752fSRamaswamy Tummala if (nvpair_value_uint64(nvp, &id64) != 0) { 650*1cfa752fSRamaswamy Tummala ibpart_log_err(DATALINK_INVALID_LINKID, errorp, 651*1cfa752fSRamaswamy Tummala "cannot get linkid"); 652*1cfa752fSRamaswamy Tummala rv = RCM_FAILURE; 653*1cfa752fSRamaswamy Tummala continue; 654*1cfa752fSRamaswamy Tummala } 655*1cfa752fSRamaswamy Tummala 656*1cfa752fSRamaswamy Tummala linkid = (datalink_id_t)id64; 657*1cfa752fSRamaswamy Tummala if (ibpart_configure(hd, linkid) != 0) { 658*1cfa752fSRamaswamy Tummala ibpart_log_err(linkid, errorp, "configuring failed"); 659*1cfa752fSRamaswamy Tummala rv = RCM_FAILURE; 660*1cfa752fSRamaswamy Tummala continue; 661*1cfa752fSRamaswamy Tummala } 662*1cfa752fSRamaswamy Tummala 663*1cfa752fSRamaswamy Tummala /* Notify all IBPART consumers */ 664*1cfa752fSRamaswamy Tummala if (ibpart_consumer_notify(hd, linkid, errorp, flags, 665*1cfa752fSRamaswamy Tummala info) != 0) { 666*1cfa752fSRamaswamy Tummala ibpart_log_err(linkid, errorp, 667*1cfa752fSRamaswamy Tummala "consumer notify failed"); 668*1cfa752fSRamaswamy Tummala rv = RCM_FAILURE; 669*1cfa752fSRamaswamy Tummala } 670*1cfa752fSRamaswamy Tummala } 671*1cfa752fSRamaswamy Tummala 672*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 673*1cfa752fSRamaswamy Tummala "IBPART: notify_event: link configuration complete\n"); 674*1cfa752fSRamaswamy Tummala return (rv); 675*1cfa752fSRamaswamy Tummala } 676*1cfa752fSRamaswamy Tummala 677*1cfa752fSRamaswamy Tummala /* 678*1cfa752fSRamaswamy Tummala * ibpart_usage - Determine the usage of a link. 679*1cfa752fSRamaswamy Tummala * The returned buffer is owned by caller, and the caller 680*1cfa752fSRamaswamy Tummala * must free it up when done. 681*1cfa752fSRamaswamy Tummala */ 682*1cfa752fSRamaswamy Tummala static char * 683*1cfa752fSRamaswamy Tummala ibpart_usage(link_cache_t *node) 684*1cfa752fSRamaswamy Tummala { 685*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 686*1cfa752fSRamaswamy Tummala int nibpart; 687*1cfa752fSRamaswamy Tummala char *buf; 688*1cfa752fSRamaswamy Tummala const char *fmt; 689*1cfa752fSRamaswamy Tummala char *sep; 690*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 691*1cfa752fSRamaswamy Tummala char name[MAXLINKNAMELEN]; 692*1cfa752fSRamaswamy Tummala dladm_status_t status; 693*1cfa752fSRamaswamy Tummala size_t bufsz; 694*1cfa752fSRamaswamy Tummala 695*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: usage(%s)\n", node->pc_resource); 696*1cfa752fSRamaswamy Tummala 697*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 698*1cfa752fSRamaswamy Tummala if ((status = dladm_datalink_id2info(dld_handle, node->pc_linkid, NULL, 699*1cfa752fSRamaswamy Tummala NULL, NULL, name, sizeof (name))) != DLADM_STATUS_OK) { 700*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 701*1cfa752fSRamaswamy Tummala _("IBPART: usage(%s) get link name failure(%s)\n"), 702*1cfa752fSRamaswamy Tummala node->pc_resource, dladm_status2str(status, errmsg)); 703*1cfa752fSRamaswamy Tummala return (NULL); 704*1cfa752fSRamaswamy Tummala } 705*1cfa752fSRamaswamy Tummala 706*1cfa752fSRamaswamy Tummala if (node->pc_state & CACHE_NODE_OFFLINED) 707*1cfa752fSRamaswamy Tummala fmt = _("%1$s offlined"); 708*1cfa752fSRamaswamy Tummala else 709*1cfa752fSRamaswamy Tummala fmt = _("%1$s IBPART: "); 710*1cfa752fSRamaswamy Tummala 711*1cfa752fSRamaswamy Tummala /* TRANSLATION_NOTE: separator used between IBPART linkids */ 712*1cfa752fSRamaswamy Tummala sep = _(", "); 713*1cfa752fSRamaswamy Tummala 714*1cfa752fSRamaswamy Tummala nibpart = 0; 715*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 716*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) 717*1cfa752fSRamaswamy Tummala nibpart++; 718*1cfa752fSRamaswamy Tummala 719*1cfa752fSRamaswamy Tummala /* space for IBPARTs and separators, plus message */ 720*1cfa752fSRamaswamy Tummala bufsz = nibpart * (MAXLINKNAMELEN + strlen(sep)) + 721*1cfa752fSRamaswamy Tummala strlen(fmt) + MAXLINKNAMELEN + 1; 722*1cfa752fSRamaswamy Tummala if ((buf = malloc(bufsz)) == NULL) { 723*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 724*1cfa752fSRamaswamy Tummala _("IBPART: usage(%s) malloc failure(%s)\n"), 725*1cfa752fSRamaswamy Tummala node->pc_resource, strerror(errno)); 726*1cfa752fSRamaswamy Tummala return (NULL); 727*1cfa752fSRamaswamy Tummala } 728*1cfa752fSRamaswamy Tummala (void) snprintf(buf, bufsz, fmt, name); 729*1cfa752fSRamaswamy Tummala 730*1cfa752fSRamaswamy Tummala if (node->pc_state & CACHE_NODE_OFFLINED) { 731*1cfa752fSRamaswamy Tummala /* Nothing else to do */ 732*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: usage (%s) info = %s\n", 733*1cfa752fSRamaswamy Tummala node->pc_resource, buf); 734*1cfa752fSRamaswamy Tummala return (buf); 735*1cfa752fSRamaswamy Tummala } 736*1cfa752fSRamaswamy Tummala 737*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 738*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 739*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART:= %u\n", 740*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id); 741*1cfa752fSRamaswamy Tummala 742*1cfa752fSRamaswamy Tummala if ((status = dladm_datalink_id2info(dld_handle, 743*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, NULL, NULL, NULL, name, 744*1cfa752fSRamaswamy Tummala sizeof (name))) != DLADM_STATUS_OK) { 745*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 746*1cfa752fSRamaswamy Tummala _("IBPART: usage(%s) get ibpart %u name " 747*1cfa752fSRamaswamy Tummala "failure(%s)\n"), node->pc_resource, 748*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id, 749*1cfa752fSRamaswamy Tummala dladm_status2str(status, errmsg)); 750*1cfa752fSRamaswamy Tummala free(buf); 751*1cfa752fSRamaswamy Tummala return (NULL); 752*1cfa752fSRamaswamy Tummala } 753*1cfa752fSRamaswamy Tummala 754*1cfa752fSRamaswamy Tummala (void) strlcat(buf, name, bufsz); 755*1cfa752fSRamaswamy Tummala if (ibpart->dlib_next != NULL) 756*1cfa752fSRamaswamy Tummala (void) strlcat(buf, sep, bufsz); 757*1cfa752fSRamaswamy Tummala } 758*1cfa752fSRamaswamy Tummala 759*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: usage (%s) info = %s\n", 760*1cfa752fSRamaswamy Tummala node->pc_resource, buf); 761*1cfa752fSRamaswamy Tummala 762*1cfa752fSRamaswamy Tummala return (buf); 763*1cfa752fSRamaswamy Tummala } 764*1cfa752fSRamaswamy Tummala 765*1cfa752fSRamaswamy Tummala /* 766*1cfa752fSRamaswamy Tummala * Cache management routines, all cache management functions should be 767*1cfa752fSRamaswamy Tummala * be called with cache_lock held. 768*1cfa752fSRamaswamy Tummala */ 769*1cfa752fSRamaswamy Tummala 770*1cfa752fSRamaswamy Tummala /* 771*1cfa752fSRamaswamy Tummala * cache_lookup() - Get a cache node for a resource. 772*1cfa752fSRamaswamy Tummala * Call with cache lock held. 773*1cfa752fSRamaswamy Tummala * 774*1cfa752fSRamaswamy Tummala * This ensures that the cache is consistent with the system state and 775*1cfa752fSRamaswamy Tummala * returns a pointer to the cache element corresponding to the resource. 776*1cfa752fSRamaswamy Tummala */ 777*1cfa752fSRamaswamy Tummala static link_cache_t * 778*1cfa752fSRamaswamy Tummala cache_lookup(rcm_handle_t *hd, char *rsrc, char options) 779*1cfa752fSRamaswamy Tummala { 780*1cfa752fSRamaswamy Tummala link_cache_t *node; 781*1cfa752fSRamaswamy Tummala 782*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: cache lookup(%s)\n", rsrc); 783*1cfa752fSRamaswamy Tummala 784*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 785*1cfa752fSRamaswamy Tummala if (options & CACHE_REFRESH) { 786*1cfa752fSRamaswamy Tummala /* drop lock since update locks cache again */ 787*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 788*1cfa752fSRamaswamy Tummala (void) cache_update(hd); 789*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 790*1cfa752fSRamaswamy Tummala } 791*1cfa752fSRamaswamy Tummala 792*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 793*1cfa752fSRamaswamy Tummala for (; node != &cache_tail; node = node->pc_next) { 794*1cfa752fSRamaswamy Tummala if (strcmp(rsrc, node->pc_resource) == 0) { 795*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, 796*1cfa752fSRamaswamy Tummala "IBPART: cache lookup succeeded(%s)\n", rsrc); 797*1cfa752fSRamaswamy Tummala return (node); 798*1cfa752fSRamaswamy Tummala } 799*1cfa752fSRamaswamy Tummala } 800*1cfa752fSRamaswamy Tummala return (NULL); 801*1cfa752fSRamaswamy Tummala } 802*1cfa752fSRamaswamy Tummala 803*1cfa752fSRamaswamy Tummala /* 804*1cfa752fSRamaswamy Tummala * node_free - Free a node from the cache 805*1cfa752fSRamaswamy Tummala */ 806*1cfa752fSRamaswamy Tummala static void 807*1cfa752fSRamaswamy Tummala node_free(link_cache_t *node) 808*1cfa752fSRamaswamy Tummala { 809*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart, *next; 810*1cfa752fSRamaswamy Tummala 811*1cfa752fSRamaswamy Tummala if (node != NULL) { 812*1cfa752fSRamaswamy Tummala free(node->pc_resource); 813*1cfa752fSRamaswamy Tummala 814*1cfa752fSRamaswamy Tummala /* free the IBPART list */ 815*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; ibpart = next) { 816*1cfa752fSRamaswamy Tummala next = ibpart->dlib_next; 817*1cfa752fSRamaswamy Tummala free(ibpart); 818*1cfa752fSRamaswamy Tummala } 819*1cfa752fSRamaswamy Tummala free(node); 820*1cfa752fSRamaswamy Tummala } 821*1cfa752fSRamaswamy Tummala } 822*1cfa752fSRamaswamy Tummala 823*1cfa752fSRamaswamy Tummala /* 824*1cfa752fSRamaswamy Tummala * cache_insert - Insert a resource node in cache 825*1cfa752fSRamaswamy Tummala */ 826*1cfa752fSRamaswamy Tummala static void 827*1cfa752fSRamaswamy Tummala cache_insert(link_cache_t *node) 828*1cfa752fSRamaswamy Tummala { 829*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 830*1cfa752fSRamaswamy Tummala 831*1cfa752fSRamaswamy Tummala /* insert at the head for best performance */ 832*1cfa752fSRamaswamy Tummala node->pc_next = cache_head.pc_next; 833*1cfa752fSRamaswamy Tummala node->pc_prev = &cache_head; 834*1cfa752fSRamaswamy Tummala 835*1cfa752fSRamaswamy Tummala node->pc_next->pc_prev = node; 836*1cfa752fSRamaswamy Tummala node->pc_prev->pc_next = node; 837*1cfa752fSRamaswamy Tummala } 838*1cfa752fSRamaswamy Tummala 839*1cfa752fSRamaswamy Tummala /* 840*1cfa752fSRamaswamy Tummala * cache_remove() - Remove a resource node from cache. 841*1cfa752fSRamaswamy Tummala */ 842*1cfa752fSRamaswamy Tummala static void 843*1cfa752fSRamaswamy Tummala cache_remove(link_cache_t *node) 844*1cfa752fSRamaswamy Tummala { 845*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 846*1cfa752fSRamaswamy Tummala node->pc_next->pc_prev = node->pc_prev; 847*1cfa752fSRamaswamy Tummala node->pc_prev->pc_next = node->pc_next; 848*1cfa752fSRamaswamy Tummala node->pc_next = NULL; 849*1cfa752fSRamaswamy Tummala node->pc_prev = NULL; 850*1cfa752fSRamaswamy Tummala } 851*1cfa752fSRamaswamy Tummala 852*1cfa752fSRamaswamy Tummala typedef struct ibpart_update_arg_s { 853*1cfa752fSRamaswamy Tummala rcm_handle_t *hd; 854*1cfa752fSRamaswamy Tummala int retval; 855*1cfa752fSRamaswamy Tummala } ibpart_update_arg_t; 856*1cfa752fSRamaswamy Tummala 857*1cfa752fSRamaswamy Tummala /* 858*1cfa752fSRamaswamy Tummala * ibpart_update() - Update physical interface properties 859*1cfa752fSRamaswamy Tummala */ 860*1cfa752fSRamaswamy Tummala static int 861*1cfa752fSRamaswamy Tummala ibpart_update(dladm_handle_t handle, datalink_id_t ibpartid, void *arg) 862*1cfa752fSRamaswamy Tummala { 863*1cfa752fSRamaswamy Tummala ibpart_update_arg_t *ibpart_update_argp = arg; 864*1cfa752fSRamaswamy Tummala rcm_handle_t *hd = ibpart_update_argp->hd; 865*1cfa752fSRamaswamy Tummala link_cache_t *node; 866*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 867*1cfa752fSRamaswamy Tummala char *rsrc; 868*1cfa752fSRamaswamy Tummala dladm_ib_attr_t ibpart_attr; 869*1cfa752fSRamaswamy Tummala dladm_status_t status; 870*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 871*1cfa752fSRamaswamy Tummala boolean_t newnode = B_FALSE; 872*1cfa752fSRamaswamy Tummala int ret = -1; 873*1cfa752fSRamaswamy Tummala 874*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_update(%u)\n", ibpartid); 875*1cfa752fSRamaswamy Tummala 876*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 877*1cfa752fSRamaswamy Tummala status = dladm_part_info(handle, ibpartid, &ibpart_attr, 878*1cfa752fSRamaswamy Tummala DLADM_OPT_ACTIVE); 879*1cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) { 880*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 881*1cfa752fSRamaswamy Tummala "IBPART: ibpart_update() cannot get ibpart information for " 882*1cfa752fSRamaswamy Tummala "%u(%s)\n", ibpartid, dladm_status2str(status, errmsg)); 883*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 884*1cfa752fSRamaswamy Tummala } 885*1cfa752fSRamaswamy Tummala 886*1cfa752fSRamaswamy Tummala if (ibpart_attr.dia_physlinkid == DATALINK_INVALID_LINKID) { 887*1cfa752fSRamaswamy Tummala /* 888*1cfa752fSRamaswamy Tummala * Skip the IB port nodes. 889*1cfa752fSRamaswamy Tummala */ 890*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 891*1cfa752fSRamaswamy Tummala "IBPART: ibpart_update(): skip the PORT nodes %u\n", 892*1cfa752fSRamaswamy Tummala ibpartid); 893*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 894*1cfa752fSRamaswamy Tummala } 895*1cfa752fSRamaswamy Tummala 896*1cfa752fSRamaswamy Tummala rsrc = malloc(RCM_LINK_RESOURCE_MAX); 897*1cfa752fSRamaswamy Tummala if (rsrc == NULL) { 898*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, _("IBPART: malloc error(%s): %u\n"), 899*1cfa752fSRamaswamy Tummala strerror(errno), ibpartid); 900*1cfa752fSRamaswamy Tummala goto done; 901*1cfa752fSRamaswamy Tummala } 902*1cfa752fSRamaswamy Tummala 903*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", 904*1cfa752fSRamaswamy Tummala RCM_LINK_PREFIX, ibpart_attr.dia_physlinkid); 905*1cfa752fSRamaswamy Tummala 906*1cfa752fSRamaswamy Tummala node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH); 907*1cfa752fSRamaswamy Tummala if (node != NULL) { 908*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, 909*1cfa752fSRamaswamy Tummala "IBPART: %s already registered (ibpartid:%d)\n", 910*1cfa752fSRamaswamy Tummala rsrc, ibpart_attr.dia_partlinkid); 911*1cfa752fSRamaswamy Tummala free(rsrc); 912*1cfa752fSRamaswamy Tummala } else { 913*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, 914*1cfa752fSRamaswamy Tummala "IBPART: %s is a new resource (ibpartid:%d)\n", 915*1cfa752fSRamaswamy Tummala rsrc, ibpart_attr.dia_partlinkid); 916*1cfa752fSRamaswamy Tummala if ((node = calloc(1, sizeof (link_cache_t))) == NULL) { 917*1cfa752fSRamaswamy Tummala free(rsrc); 918*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, _("IBPART: calloc: %s\n"), 919*1cfa752fSRamaswamy Tummala strerror(errno)); 920*1cfa752fSRamaswamy Tummala goto done; 921*1cfa752fSRamaswamy Tummala } 922*1cfa752fSRamaswamy Tummala 923*1cfa752fSRamaswamy Tummala node->pc_resource = rsrc; 924*1cfa752fSRamaswamy Tummala node->pc_ibpart = NULL; 925*1cfa752fSRamaswamy Tummala node->pc_linkid = ibpart_attr.dia_physlinkid; 926*1cfa752fSRamaswamy Tummala node->pc_state |= CACHE_NODE_NEW; 927*1cfa752fSRamaswamy Tummala newnode = B_TRUE; 928*1cfa752fSRamaswamy Tummala } 929*1cfa752fSRamaswamy Tummala 930*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 931*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 932*1cfa752fSRamaswamy Tummala if (ibpart->dlib_ibpart_id == ibpartid) { 933*1cfa752fSRamaswamy Tummala ibpart->dlib_flags &= ~IBPART_STALE; 934*1cfa752fSRamaswamy Tummala break; 935*1cfa752fSRamaswamy Tummala } 936*1cfa752fSRamaswamy Tummala } 937*1cfa752fSRamaswamy Tummala 938*1cfa752fSRamaswamy Tummala if (ibpart == NULL) { 939*1cfa752fSRamaswamy Tummala if ((ibpart = calloc(1, sizeof (dl_ibpart_t))) == NULL) { 940*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, _("IBPART: malloc: %s\n"), 941*1cfa752fSRamaswamy Tummala strerror(errno)); 942*1cfa752fSRamaswamy Tummala if (newnode) { 943*1cfa752fSRamaswamy Tummala free(rsrc); 944*1cfa752fSRamaswamy Tummala free(node); 945*1cfa752fSRamaswamy Tummala } 946*1cfa752fSRamaswamy Tummala goto done; 947*1cfa752fSRamaswamy Tummala } 948*1cfa752fSRamaswamy Tummala ibpart->dlib_ibpart_id = ibpartid; 949*1cfa752fSRamaswamy Tummala ibpart->dlib_next = node->pc_ibpart; 950*1cfa752fSRamaswamy Tummala ibpart->dlib_prev = NULL; 951*1cfa752fSRamaswamy Tummala if (node->pc_ibpart != NULL) 952*1cfa752fSRamaswamy Tummala node->pc_ibpart->dlib_prev = ibpart; 953*1cfa752fSRamaswamy Tummala node->pc_ibpart = ibpart; 954*1cfa752fSRamaswamy Tummala } 955*1cfa752fSRamaswamy Tummala 956*1cfa752fSRamaswamy Tummala node->pc_state &= ~CACHE_NODE_STALE; 957*1cfa752fSRamaswamy Tummala 958*1cfa752fSRamaswamy Tummala if (newnode) 959*1cfa752fSRamaswamy Tummala cache_insert(node); 960*1cfa752fSRamaswamy Tummala 961*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE3, "IBPART: ibpart_update: succeeded(%u)\n", 962*1cfa752fSRamaswamy Tummala ibpartid); 963*1cfa752fSRamaswamy Tummala ret = 0; 964*1cfa752fSRamaswamy Tummala done: 965*1cfa752fSRamaswamy Tummala ibpart_update_argp->retval = ret; 966*1cfa752fSRamaswamy Tummala return (ret == 0 ? DLADM_WALK_CONTINUE : DLADM_WALK_TERMINATE); 967*1cfa752fSRamaswamy Tummala } 968*1cfa752fSRamaswamy Tummala 969*1cfa752fSRamaswamy Tummala /* 970*1cfa752fSRamaswamy Tummala * ibpart_update_all() - Determine all IBPART links in the system 971*1cfa752fSRamaswamy Tummala */ 972*1cfa752fSRamaswamy Tummala static int 973*1cfa752fSRamaswamy Tummala ibpart_update_all(rcm_handle_t *hd) 974*1cfa752fSRamaswamy Tummala { 975*1cfa752fSRamaswamy Tummala ibpart_update_arg_t arg = {NULL, 0}; 976*1cfa752fSRamaswamy Tummala 977*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_update_all\n"); 978*1cfa752fSRamaswamy Tummala 979*1cfa752fSRamaswamy Tummala assert(MUTEX_HELD(&cache_lock)); 980*1cfa752fSRamaswamy Tummala arg.hd = hd; 981*1cfa752fSRamaswamy Tummala (void) dladm_walk_datalink_id(ibpart_update, dld_handle, &arg, 982*1cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); 983*1cfa752fSRamaswamy Tummala return (arg.retval); 984*1cfa752fSRamaswamy Tummala } 985*1cfa752fSRamaswamy Tummala 986*1cfa752fSRamaswamy Tummala /* 987*1cfa752fSRamaswamy Tummala * cache_update() - Update cache with latest interface info 988*1cfa752fSRamaswamy Tummala */ 989*1cfa752fSRamaswamy Tummala static int 990*1cfa752fSRamaswamy Tummala cache_update(rcm_handle_t *hd) 991*1cfa752fSRamaswamy Tummala { 992*1cfa752fSRamaswamy Tummala link_cache_t *node, *nnode; 993*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 994*1cfa752fSRamaswamy Tummala int rv; 995*1cfa752fSRamaswamy Tummala 996*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: cache_update\n"); 997*1cfa752fSRamaswamy Tummala 998*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 999*1cfa752fSRamaswamy Tummala 1000*1cfa752fSRamaswamy Tummala /* first we walk the entire cache, marking each entry stale */ 1001*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 1002*1cfa752fSRamaswamy Tummala for (; node != &cache_tail; node = node->pc_next) { 1003*1cfa752fSRamaswamy Tummala node->pc_state |= CACHE_NODE_STALE; 1004*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 1005*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) 1006*1cfa752fSRamaswamy Tummala ibpart->dlib_flags |= IBPART_STALE; 1007*1cfa752fSRamaswamy Tummala } 1008*1cfa752fSRamaswamy Tummala 1009*1cfa752fSRamaswamy Tummala rv = ibpart_update_all(hd); 1010*1cfa752fSRamaswamy Tummala 1011*1cfa752fSRamaswamy Tummala /* 1012*1cfa752fSRamaswamy Tummala * Continue to delete all stale nodes from the cache even 1013*1cfa752fSRamaswamy Tummala * ibpart_update_all() failed. Unregister link that are not offlined 1014*1cfa752fSRamaswamy Tummala * and still in cache 1015*1cfa752fSRamaswamy Tummala */ 1016*1cfa752fSRamaswamy Tummala for (node = cache_head.pc_next; node != &cache_tail; node = nnode) { 1017*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart, *next; 1018*1cfa752fSRamaswamy Tummala 1019*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; ibpart = next) { 1020*1cfa752fSRamaswamy Tummala next = ibpart->dlib_next; 1021*1cfa752fSRamaswamy Tummala 1022*1cfa752fSRamaswamy Tummala /* clear stale IBPARTs */ 1023*1cfa752fSRamaswamy Tummala if (ibpart->dlib_flags & IBPART_STALE) { 1024*1cfa752fSRamaswamy Tummala if (ibpart->dlib_prev != NULL) 1025*1cfa752fSRamaswamy Tummala ibpart->dlib_prev->dlib_next = next; 1026*1cfa752fSRamaswamy Tummala else 1027*1cfa752fSRamaswamy Tummala node->pc_ibpart = next; 1028*1cfa752fSRamaswamy Tummala 1029*1cfa752fSRamaswamy Tummala if (next != NULL) 1030*1cfa752fSRamaswamy Tummala next->dlib_prev = ibpart->dlib_prev; 1031*1cfa752fSRamaswamy Tummala free(ibpart); 1032*1cfa752fSRamaswamy Tummala } 1033*1cfa752fSRamaswamy Tummala } 1034*1cfa752fSRamaswamy Tummala 1035*1cfa752fSRamaswamy Tummala nnode = node->pc_next; 1036*1cfa752fSRamaswamy Tummala if (node->pc_state & CACHE_NODE_STALE) { 1037*1cfa752fSRamaswamy Tummala (void) rcm_unregister_interest(hd, node->pc_resource, 1038*1cfa752fSRamaswamy Tummala 0); 1039*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART: unregistered %s\n", 1040*1cfa752fSRamaswamy Tummala node->pc_resource); 1041*1cfa752fSRamaswamy Tummala assert(node->pc_ibpart == NULL); 1042*1cfa752fSRamaswamy Tummala cache_remove(node); 1043*1cfa752fSRamaswamy Tummala node_free(node); 1044*1cfa752fSRamaswamy Tummala continue; 1045*1cfa752fSRamaswamy Tummala } 1046*1cfa752fSRamaswamy Tummala 1047*1cfa752fSRamaswamy Tummala if (!(node->pc_state & CACHE_NODE_NEW)) 1048*1cfa752fSRamaswamy Tummala continue; 1049*1cfa752fSRamaswamy Tummala 1050*1cfa752fSRamaswamy Tummala if (rcm_register_interest(hd, node->pc_resource, 0, NULL) != 1051*1cfa752fSRamaswamy Tummala RCM_SUCCESS) { 1052*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 1053*1cfa752fSRamaswamy Tummala _("IBPART: failed to register %s\n"), 1054*1cfa752fSRamaswamy Tummala node->pc_resource); 1055*1cfa752fSRamaswamy Tummala rv = -1; 1056*1cfa752fSRamaswamy Tummala } else { 1057*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_DEBUG, "IBPART: registered %s\n", 1058*1cfa752fSRamaswamy Tummala node->pc_resource); 1059*1cfa752fSRamaswamy Tummala node->pc_state &= ~CACHE_NODE_NEW; 1060*1cfa752fSRamaswamy Tummala } 1061*1cfa752fSRamaswamy Tummala } 1062*1cfa752fSRamaswamy Tummala 1063*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1064*1cfa752fSRamaswamy Tummala return (rv); 1065*1cfa752fSRamaswamy Tummala } 1066*1cfa752fSRamaswamy Tummala 1067*1cfa752fSRamaswamy Tummala /* 1068*1cfa752fSRamaswamy Tummala * cache_free() - Empty the cache 1069*1cfa752fSRamaswamy Tummala */ 1070*1cfa752fSRamaswamy Tummala static void 1071*1cfa752fSRamaswamy Tummala cache_free() 1072*1cfa752fSRamaswamy Tummala { 1073*1cfa752fSRamaswamy Tummala link_cache_t *node; 1074*1cfa752fSRamaswamy Tummala 1075*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: cache_free\n"); 1076*1cfa752fSRamaswamy Tummala 1077*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 1078*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 1079*1cfa752fSRamaswamy Tummala while (node != &cache_tail) { 1080*1cfa752fSRamaswamy Tummala cache_remove(node); 1081*1cfa752fSRamaswamy Tummala node_free(node); 1082*1cfa752fSRamaswamy Tummala node = cache_head.pc_next; 1083*1cfa752fSRamaswamy Tummala } 1084*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1085*1cfa752fSRamaswamy Tummala } 1086*1cfa752fSRamaswamy Tummala 1087*1cfa752fSRamaswamy Tummala /* 1088*1cfa752fSRamaswamy Tummala * ibpart_log_err() - RCM error log wrapper 1089*1cfa752fSRamaswamy Tummala */ 1090*1cfa752fSRamaswamy Tummala static void 1091*1cfa752fSRamaswamy Tummala ibpart_log_err(datalink_id_t linkid, char **errorp, char *errmsg) 1092*1cfa752fSRamaswamy Tummala { 1093*1cfa752fSRamaswamy Tummala char link[MAXLINKNAMELEN]; 1094*1cfa752fSRamaswamy Tummala char errstr[DLADM_STRSIZE]; 1095*1cfa752fSRamaswamy Tummala dladm_status_t status; 1096*1cfa752fSRamaswamy Tummala int len; 1097*1cfa752fSRamaswamy Tummala const char *errfmt; 1098*1cfa752fSRamaswamy Tummala char *error; 1099*1cfa752fSRamaswamy Tummala 1100*1cfa752fSRamaswamy Tummala link[0] = '\0'; 1101*1cfa752fSRamaswamy Tummala if (linkid != DATALINK_INVALID_LINKID) { 1102*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 1103*1cfa752fSRamaswamy Tummala 1104*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, sizeof (rsrc), "%s/%u", 1105*1cfa752fSRamaswamy Tummala RCM_LINK_PREFIX, linkid); 1106*1cfa752fSRamaswamy Tummala 1107*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, _("IBPART: %s(%s)\n"), errmsg, rsrc); 1108*1cfa752fSRamaswamy Tummala if ((status = dladm_datalink_id2info(dld_handle, linkid, NULL, 1109*1cfa752fSRamaswamy Tummala NULL, NULL, link, sizeof (link))) != DLADM_STATUS_OK) { 1110*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 1111*1cfa752fSRamaswamy Tummala _("IBPART: cannot get link name for (%s) %s\n"), 1112*1cfa752fSRamaswamy Tummala rsrc, dladm_status2str(status, errstr)); 1113*1cfa752fSRamaswamy Tummala } 1114*1cfa752fSRamaswamy Tummala } else { 1115*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, _("IBPART: %s\n"), errmsg); 1116*1cfa752fSRamaswamy Tummala } 1117*1cfa752fSRamaswamy Tummala 1118*1cfa752fSRamaswamy Tummala errfmt = strlen(link) > 0 ? _("IBPART: %s(%s)") : _("IBPART: %s"); 1119*1cfa752fSRamaswamy Tummala len = strlen(errfmt) + strlen(errmsg) + MAXLINKNAMELEN + 1; 1120*1cfa752fSRamaswamy Tummala if ((error = malloc(len)) != NULL) { 1121*1cfa752fSRamaswamy Tummala if (strlen(link) > 0) 1122*1cfa752fSRamaswamy Tummala (void) snprintf(error, len, errfmt, errmsg, link); 1123*1cfa752fSRamaswamy Tummala else 1124*1cfa752fSRamaswamy Tummala (void) snprintf(error, len, errfmt, errmsg); 1125*1cfa752fSRamaswamy Tummala } 1126*1cfa752fSRamaswamy Tummala 1127*1cfa752fSRamaswamy Tummala if (errorp != NULL) 1128*1cfa752fSRamaswamy Tummala *errorp = error; 1129*1cfa752fSRamaswamy Tummala } 1130*1cfa752fSRamaswamy Tummala 1131*1cfa752fSRamaswamy Tummala /* 1132*1cfa752fSRamaswamy Tummala * ibpart_consumer_online() 1133*1cfa752fSRamaswamy Tummala * 1134*1cfa752fSRamaswamy Tummala * Notify online to IBPART consumers. 1135*1cfa752fSRamaswamy Tummala */ 1136*1cfa752fSRamaswamy Tummala /* ARGSUSED */ 1137*1cfa752fSRamaswamy Tummala static void 1138*1cfa752fSRamaswamy Tummala ibpart_consumer_online(rcm_handle_t *hd, link_cache_t *node, char **errorp, 1139*1cfa752fSRamaswamy Tummala uint_t flags, rcm_info_t **info) 1140*1cfa752fSRamaswamy Tummala { 1141*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 1142*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 1143*1cfa752fSRamaswamy Tummala 1144*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_online (%s)\n", 1145*1cfa752fSRamaswamy Tummala node->pc_resource); 1146*1cfa752fSRamaswamy Tummala 1147*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 1148*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 1149*1cfa752fSRamaswamy Tummala if (!(ibpart->dlib_flags & IBPART_CONSUMER_OFFLINED)) 1150*1cfa752fSRamaswamy Tummala continue; 1151*1cfa752fSRamaswamy Tummala 1152*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", 1153*1cfa752fSRamaswamy Tummala RCM_LINK_PREFIX, ibpart->dlib_ibpart_id); 1154*1cfa752fSRamaswamy Tummala 1155*1cfa752fSRamaswamy Tummala if (rcm_notify_online(hd, rsrc, flags, info) == RCM_SUCCESS) 1156*1cfa752fSRamaswamy Tummala ibpart->dlib_flags &= ~IBPART_CONSUMER_OFFLINED; 1157*1cfa752fSRamaswamy Tummala } 1158*1cfa752fSRamaswamy Tummala 1159*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_online done\n"); 1160*1cfa752fSRamaswamy Tummala } 1161*1cfa752fSRamaswamy Tummala 1162*1cfa752fSRamaswamy Tummala /* 1163*1cfa752fSRamaswamy Tummala * ibpart_consumer_offline() 1164*1cfa752fSRamaswamy Tummala * 1165*1cfa752fSRamaswamy Tummala * Offline IBPART consumers. 1166*1cfa752fSRamaswamy Tummala */ 1167*1cfa752fSRamaswamy Tummala static int 1168*1cfa752fSRamaswamy Tummala ibpart_consumer_offline(rcm_handle_t *hd, link_cache_t *node, char **errorp, 1169*1cfa752fSRamaswamy Tummala uint_t flags, rcm_info_t **info) 1170*1cfa752fSRamaswamy Tummala { 1171*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 1172*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 1173*1cfa752fSRamaswamy Tummala int ret = RCM_SUCCESS; 1174*1cfa752fSRamaswamy Tummala 1175*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_offline (%s)\n", 1176*1cfa752fSRamaswamy Tummala node->pc_resource); 1177*1cfa752fSRamaswamy Tummala 1178*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 1179*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 1180*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", 1181*1cfa752fSRamaswamy Tummala RCM_LINK_PREFIX, ibpart->dlib_ibpart_id); 1182*1cfa752fSRamaswamy Tummala 1183*1cfa752fSRamaswamy Tummala ret = rcm_request_offline(hd, rsrc, flags, info); 1184*1cfa752fSRamaswamy Tummala if (ret != RCM_SUCCESS) 1185*1cfa752fSRamaswamy Tummala break; 1186*1cfa752fSRamaswamy Tummala 1187*1cfa752fSRamaswamy Tummala ibpart->dlib_flags |= IBPART_CONSUMER_OFFLINED; 1188*1cfa752fSRamaswamy Tummala } 1189*1cfa752fSRamaswamy Tummala 1190*1cfa752fSRamaswamy Tummala if (ibpart != NULL) 1191*1cfa752fSRamaswamy Tummala ibpart_consumer_online(hd, node, errorp, flags, info); 1192*1cfa752fSRamaswamy Tummala 1193*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_offline done\n"); 1194*1cfa752fSRamaswamy Tummala return (ret); 1195*1cfa752fSRamaswamy Tummala } 1196*1cfa752fSRamaswamy Tummala 1197*1cfa752fSRamaswamy Tummala /* 1198*1cfa752fSRamaswamy Tummala * Send RCM_RESOURCE_LINK_NEW events to other modules about new IBPARTs. 1199*1cfa752fSRamaswamy Tummala * Return 0 on success, -1 on failure. 1200*1cfa752fSRamaswamy Tummala */ 1201*1cfa752fSRamaswamy Tummala static int 1202*1cfa752fSRamaswamy Tummala ibpart_notify_new_ibpart(rcm_handle_t *hd, char *rsrc) 1203*1cfa752fSRamaswamy Tummala { 1204*1cfa752fSRamaswamy Tummala link_cache_t *node; 1205*1cfa752fSRamaswamy Tummala dl_ibpart_t *ibpart; 1206*1cfa752fSRamaswamy Tummala nvlist_t *nvl = NULL; 1207*1cfa752fSRamaswamy Tummala uint64_t id; 1208*1cfa752fSRamaswamy Tummala int ret = -1; 1209*1cfa752fSRamaswamy Tummala 1210*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_notify_new_ibpart (%s)\n", 1211*1cfa752fSRamaswamy Tummala rsrc); 1212*1cfa752fSRamaswamy Tummala 1213*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 1214*1cfa752fSRamaswamy Tummala if ((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) == NULL) { 1215*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1216*1cfa752fSRamaswamy Tummala return (0); 1217*1cfa752fSRamaswamy Tummala } 1218*1cfa752fSRamaswamy Tummala 1219*1cfa752fSRamaswamy Tummala if (nvlist_alloc(&nvl, 0, 0) != 0) { 1220*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1221*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 1222*1cfa752fSRamaswamy Tummala _("IBPART: failed to allocate nvlist\n")); 1223*1cfa752fSRamaswamy Tummala goto done; 1224*1cfa752fSRamaswamy Tummala } 1225*1cfa752fSRamaswamy Tummala 1226*1cfa752fSRamaswamy Tummala for (ibpart = node->pc_ibpart; ibpart != NULL; 1227*1cfa752fSRamaswamy Tummala ibpart = ibpart->dlib_next) { 1228*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_notify_new_ibpart " 1229*1cfa752fSRamaswamy Tummala "add (%u)\n", ibpart->dlib_ibpart_id); 1230*1cfa752fSRamaswamy Tummala 1231*1cfa752fSRamaswamy Tummala id = ibpart->dlib_ibpart_id; 1232*1cfa752fSRamaswamy Tummala if (nvlist_add_uint64(nvl, RCM_NV_LINKID, id) != 0) { 1233*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 1234*1cfa752fSRamaswamy Tummala _("IBPART: failed to construct nvlist\n")); 1235*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1236*1cfa752fSRamaswamy Tummala goto done; 1237*1cfa752fSRamaswamy Tummala } 1238*1cfa752fSRamaswamy Tummala } 1239*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1240*1cfa752fSRamaswamy Tummala 1241*1cfa752fSRamaswamy Tummala if (rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW, 0, nvl, NULL) != 1242*1cfa752fSRamaswamy Tummala RCM_SUCCESS) { 1243*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_ERROR, 1244*1cfa752fSRamaswamy Tummala _("IBPART: failed to notify %s event for %s\n"), 1245*1cfa752fSRamaswamy Tummala RCM_RESOURCE_LINK_NEW, node->pc_resource); 1246*1cfa752fSRamaswamy Tummala goto done; 1247*1cfa752fSRamaswamy Tummala } 1248*1cfa752fSRamaswamy Tummala 1249*1cfa752fSRamaswamy Tummala ret = 0; 1250*1cfa752fSRamaswamy Tummala done: 1251*1cfa752fSRamaswamy Tummala nvlist_free(nvl); 1252*1cfa752fSRamaswamy Tummala return (ret); 1253*1cfa752fSRamaswamy Tummala } 1254*1cfa752fSRamaswamy Tummala 1255*1cfa752fSRamaswamy Tummala /* 1256*1cfa752fSRamaswamy Tummala * ibpart_consumer_notify() - Notify consumers of IBPARTs coming back online. 1257*1cfa752fSRamaswamy Tummala */ 1258*1cfa752fSRamaswamy Tummala static int 1259*1cfa752fSRamaswamy Tummala ibpart_consumer_notify(rcm_handle_t *hd, datalink_id_t linkid, char **errorp, 1260*1cfa752fSRamaswamy Tummala uint_t flags, rcm_info_t **info) 1261*1cfa752fSRamaswamy Tummala { 1262*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 1263*1cfa752fSRamaswamy Tummala link_cache_t *node; 1264*1cfa752fSRamaswamy Tummala 1265*1cfa752fSRamaswamy Tummala /* Check for the interface in the cache */ 1266*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", RCM_LINK_PREFIX, 1267*1cfa752fSRamaswamy Tummala linkid); 1268*1cfa752fSRamaswamy Tummala 1269*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_notify(%s)\n", 1270*1cfa752fSRamaswamy Tummala rsrc); 1271*1cfa752fSRamaswamy Tummala 1272*1cfa752fSRamaswamy Tummala /* 1273*1cfa752fSRamaswamy Tummala * Inform IP consumers of the new link. 1274*1cfa752fSRamaswamy Tummala */ 1275*1cfa752fSRamaswamy Tummala if (ibpart_notify_new_ibpart(hd, rsrc) != 0) { 1276*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 1277*1cfa752fSRamaswamy Tummala if ((node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH)) != NULL) { 1278*1cfa752fSRamaswamy Tummala (void) ibpart_offline_ibpart(node, IBPART_STALE, 1279*1cfa752fSRamaswamy Tummala CACHE_NODE_STALE); 1280*1cfa752fSRamaswamy Tummala } 1281*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1282*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, 1283*1cfa752fSRamaswamy Tummala "IBPART: ibpart_notify_new_ibpart failed(%s)\n", rsrc); 1284*1cfa752fSRamaswamy Tummala return (-1); 1285*1cfa752fSRamaswamy Tummala } 1286*1cfa752fSRamaswamy Tummala 1287*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_consumer_notify " 1288*1cfa752fSRamaswamy Tummala "succeeded\n"); 1289*1cfa752fSRamaswamy Tummala return (0); 1290*1cfa752fSRamaswamy Tummala } 1291*1cfa752fSRamaswamy Tummala 1292*1cfa752fSRamaswamy Tummala typedef struct ibpart_up_arg_s { 1293*1cfa752fSRamaswamy Tummala datalink_id_t linkid; 1294*1cfa752fSRamaswamy Tummala int retval; 1295*1cfa752fSRamaswamy Tummala } ibpart_up_arg_t; 1296*1cfa752fSRamaswamy Tummala 1297*1cfa752fSRamaswamy Tummala static int 1298*1cfa752fSRamaswamy Tummala ibpart_up(dladm_handle_t handle, datalink_id_t ibpartid, void *arg) 1299*1cfa752fSRamaswamy Tummala { 1300*1cfa752fSRamaswamy Tummala ibpart_up_arg_t *ibpart_up_argp = arg; 1301*1cfa752fSRamaswamy Tummala dladm_status_t status; 1302*1cfa752fSRamaswamy Tummala dladm_ib_attr_t ibpart_attr; 1303*1cfa752fSRamaswamy Tummala char errmsg[DLADM_STRSIZE]; 1304*1cfa752fSRamaswamy Tummala 1305*1cfa752fSRamaswamy Tummala status = dladm_part_info(handle, ibpartid, &ibpart_attr, 1306*1cfa752fSRamaswamy Tummala DLADM_OPT_PERSIST); 1307*1cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) { 1308*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE1, 1309*1cfa752fSRamaswamy Tummala "IBPART: ibpart_up(): cannot get information for IBPART %u " 1310*1cfa752fSRamaswamy Tummala "(%s)\n", ibpartid, dladm_status2str(status, errmsg)); 1311*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 1312*1cfa752fSRamaswamy Tummala } 1313*1cfa752fSRamaswamy Tummala 1314*1cfa752fSRamaswamy Tummala if (ibpart_attr.dia_physlinkid != ibpart_up_argp->linkid) 1315*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 1316*1cfa752fSRamaswamy Tummala 1317*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE3, "IBPART: ibpart_up(%u)\n", ibpartid); 1318*1cfa752fSRamaswamy Tummala if ((status = dladm_part_up(handle, ibpartid, 0)) == DLADM_STATUS_OK) 1319*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 1320*1cfa752fSRamaswamy Tummala 1321*1cfa752fSRamaswamy Tummala /* 1322*1cfa752fSRamaswamy Tummala * Prompt the warning message and continue to UP other IBPARTs. 1323*1cfa752fSRamaswamy Tummala */ 1324*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_WARNING, 1325*1cfa752fSRamaswamy Tummala _("IBPART: IBPART up failed (%u): %s\n"), 1326*1cfa752fSRamaswamy Tummala ibpartid, dladm_status2str(status, errmsg)); 1327*1cfa752fSRamaswamy Tummala 1328*1cfa752fSRamaswamy Tummala ibpart_up_argp->retval = -1; 1329*1cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 1330*1cfa752fSRamaswamy Tummala } 1331*1cfa752fSRamaswamy Tummala 1332*1cfa752fSRamaswamy Tummala /* 1333*1cfa752fSRamaswamy Tummala * ibpart_configure() - Configure IBPARTs over a physical link after it attaches 1334*1cfa752fSRamaswamy Tummala */ 1335*1cfa752fSRamaswamy Tummala static int 1336*1cfa752fSRamaswamy Tummala ibpart_configure(rcm_handle_t *hd, datalink_id_t linkid) 1337*1cfa752fSRamaswamy Tummala { 1338*1cfa752fSRamaswamy Tummala char rsrc[RCM_LINK_RESOURCE_MAX]; 1339*1cfa752fSRamaswamy Tummala link_cache_t *node; 1340*1cfa752fSRamaswamy Tummala ibpart_up_arg_t arg = {DATALINK_INVALID_LINKID, 0}; 1341*1cfa752fSRamaswamy Tummala 1342*1cfa752fSRamaswamy Tummala /* Check for the IBPARTs in the cache */ 1343*1cfa752fSRamaswamy Tummala (void) snprintf(rsrc, sizeof (rsrc), "%s/%u", RCM_LINK_PREFIX, linkid); 1344*1cfa752fSRamaswamy Tummala 1345*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, "IBPART: ibpart_configure(%s)\n", rsrc); 1346*1cfa752fSRamaswamy Tummala 1347*1cfa752fSRamaswamy Tummala /* Check if the link is new or was previously offlined */ 1348*1cfa752fSRamaswamy Tummala (void) mutex_lock(&cache_lock); 1349*1cfa752fSRamaswamy Tummala if (((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) != NULL) && 1350*1cfa752fSRamaswamy Tummala (!(node->pc_state & CACHE_NODE_OFFLINED))) { 1351*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, 1352*1cfa752fSRamaswamy Tummala "IBPART: Skipping configured interface(%s)\n", rsrc); 1353*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1354*1cfa752fSRamaswamy Tummala return (0); 1355*1cfa752fSRamaswamy Tummala } 1356*1cfa752fSRamaswamy Tummala (void) mutex_unlock(&cache_lock); 1357*1cfa752fSRamaswamy Tummala 1358*1cfa752fSRamaswamy Tummala arg.linkid = linkid; 1359*1cfa752fSRamaswamy Tummala (void) dladm_walk_datalink_id(ibpart_up, dld_handle, &arg, 1360*1cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DATALINK_ANY_MEDIATYPE, DLADM_OPT_PERSIST); 1361*1cfa752fSRamaswamy Tummala 1362*1cfa752fSRamaswamy Tummala if (arg.retval == 0) { 1363*1cfa752fSRamaswamy Tummala rcm_log_message(RCM_TRACE2, 1364*1cfa752fSRamaswamy Tummala "IBPART: ibpart_configure succeeded(%s)\n", rsrc); 1365*1cfa752fSRamaswamy Tummala } 1366*1cfa752fSRamaswamy Tummala return (arg.retval); 1367*1cfa752fSRamaswamy Tummala } 1368