10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58516SAchim.Maurer@Sun.COM * Common Development and Distribution License (the "License"). 68516SAchim.Maurer@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*10728SJohn.Harres@Sun.COM 220Sstevel@tonic-gate /* 238516SAchim.Maurer@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <dlfcn.h> 280Sstevel@tonic-gate #include <meta.h> 290Sstevel@tonic-gate #include <metadyn.h> 300Sstevel@tonic-gate #include <sdssc.h> 310Sstevel@tonic-gate 320Sstevel@tonic-gate #define SDSSC_PATH SDSSC_CL_LIBDIR "/sc/libsds_sc.so" 330Sstevel@tonic-gate 340Sstevel@tonic-gate static func_table_t dl_table[] = { 350Sstevel@tonic-gate { "_sdssc_version", (void **)&sdssc_version }, 360Sstevel@tonic-gate { "_sdssc_create_begin", (void **)&sdssc_create_begin }, 370Sstevel@tonic-gate { "_sdssc_mo_create_begin", (void **)&sdssc_mo_create_begin }, 380Sstevel@tonic-gate { "_sdssc_create_end", (void **)&sdssc_create_end }, 390Sstevel@tonic-gate { "_sdssc_delete_begin", (void **)&sdssc_delete_begin }, 400Sstevel@tonic-gate { "_sdssc_delete_end", (void **)&sdssc_delete_end }, 410Sstevel@tonic-gate { "_sdssc_get_index", (void **)&sdssc_get_index }, 420Sstevel@tonic-gate { "_sdssc_add_hosts", (void **)&sdssc_add_hosts }, 430Sstevel@tonic-gate { "_sdssc_delete_hosts", (void **)&sdssc_delete_hosts }, 440Sstevel@tonic-gate { "_sdssc_get_primary_host", (void **)&sdssc_get_primary_host }, 450Sstevel@tonic-gate { "_sdssc_cmd_proxy", (void **)&sdssc_cmd_proxy }, 460Sstevel@tonic-gate { "_sdssc_getnodelist", (void **)&sdssc_getnodelist }, 470Sstevel@tonic-gate { "_sdssc_freenodelist", (void **)&sdssc_freenodelist }, 480Sstevel@tonic-gate { "_sdssc_binddevs", (void **)&sdssc_binddevs }, 490Sstevel@tonic-gate { "_sdssc_bindclusterdevs", (void **)&sdssc_bindclusterdevs }, 500Sstevel@tonic-gate { "_sdssc_gettransportbynode", (void **)&sdssc_gettransportbynode }, 510Sstevel@tonic-gate { "_sdssc_free_mdcerr_list", (void **)&sdssc_free_mdcerr_list }, 520Sstevel@tonic-gate { "_sdssc_property_get", (void **)&sdssc_property_get }, 530Sstevel@tonic-gate { "_sdssc_property_set", (void **)&sdssc_property_set }, 540Sstevel@tonic-gate { "_sdssc_get_services", (void **)&sdssc_get_services }, 550Sstevel@tonic-gate { "_sdssc_get_services_free", (void **)&sdssc_get_services_free }, 560Sstevel@tonic-gate { "_sdssc_suspend", (void **)&sdssc_suspend }, 570Sstevel@tonic-gate { "_sdssc_convert_cluster_path", 580Sstevel@tonic-gate (void **)&sdssc_convert_cluster_path }, 590Sstevel@tonic-gate { "_sdssc_convert_ctd_path", 600Sstevel@tonic-gate (void **)&sdssc_convert_ctd_path }, 610Sstevel@tonic-gate { "_sdssc_convert_path_free", 620Sstevel@tonic-gate (void **)&sdssc_convert_path_free }, 630Sstevel@tonic-gate { "_sdssc_notify_service", (void **)&sdssc_notify_service }, 640Sstevel@tonic-gate { "_sdssc_cm_nm2nid", (void **)&sdssc_cm_nm2nid }, 650Sstevel@tonic-gate { "_sdssc_cm_sr_nm2nid", (void **)&sdssc_cm_sr_nm2nid }, 660Sstevel@tonic-gate { "_sdssc_cm_nid2nm", (void **)&sdssc_cm_nid2nm }, 670Sstevel@tonic-gate { "_sdssc_cm_sr_nid2nm", (void **)&sdssc_cm_sr_nid2nm }, 680Sstevel@tonic-gate { "_sdssc_get_priv_ipaddr", (void **)&sdssc_get_priv_ipaddr }, 690Sstevel@tonic-gate { (char *)0, (void **)0 } 700Sstevel@tonic-gate }; 710Sstevel@tonic-gate 720Sstevel@tonic-gate static rval_e 730Sstevel@tonic-gate just_dup_string(const char *source, char **dest) 740Sstevel@tonic-gate { 750Sstevel@tonic-gate *dest = strdup(source); 760Sstevel@tonic-gate return (SDSSC_OKAY); 770Sstevel@tonic-gate } 780Sstevel@tonic-gate 790Sstevel@tonic-gate static void 800Sstevel@tonic-gate free_dup_string(char *source) 810Sstevel@tonic-gate { 820Sstevel@tonic-gate free(source); 830Sstevel@tonic-gate } 840Sstevel@tonic-gate 850Sstevel@tonic-gate /* 860Sstevel@tonic-gate * not_bound -- routine to always return NOT_BOUND 870Sstevel@tonic-gate */ 880Sstevel@tonic-gate static rval_e 890Sstevel@tonic-gate not_bound(void) 900Sstevel@tonic-gate { 910Sstevel@tonic-gate return (SDSSC_NOT_BOUND); 920Sstevel@tonic-gate } 930Sstevel@tonic-gate 940Sstevel@tonic-gate /* 950Sstevel@tonic-gate * not_bound_error -- routine to always return SDSSC_NOT_BOUND_ERROR since 960Sstevel@tonic-gate * routine is not bound. This is used when using an older version 970Sstevel@tonic-gate * of libsdssc that doesn't support MN disksets. When an MN specific 980Sstevel@tonic-gate * routine is called (such as sdssc_mo_create_set) an SDSSC_NOT_BOUND_ERROR 990Sstevel@tonic-gate * will be returned. 1000Sstevel@tonic-gate */ 1010Sstevel@tonic-gate static rval_e 1020Sstevel@tonic-gate not_bound_error(void) 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate return (SDSSC_NOT_BOUND_ERROR); 1050Sstevel@tonic-gate } 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate /* 1090Sstevel@tonic-gate * set_common_routine -- set cluster interface routines to return NOT_BOUND 1100Sstevel@tonic-gate */ 1110Sstevel@tonic-gate static void 1120Sstevel@tonic-gate set_common_routine() 1130Sstevel@tonic-gate { 1140Sstevel@tonic-gate func_table_p f; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate for (f = dl_table; f->fptr != (void *)0; f++) { 1170Sstevel@tonic-gate if (strcmp(f->fname, "_sdssc_convert_cluster_path") == 0) { 1180Sstevel@tonic-gate *f->fptr = (void *)&just_dup_string; 1190Sstevel@tonic-gate } else if (strcmp(f->fname, "_sdssc_free_convert_cluster_path") 1200Sstevel@tonic-gate == 0) { 1210Sstevel@tonic-gate *f->fptr = (void *)&free_dup_string; 1220Sstevel@tonic-gate } else { 1230Sstevel@tonic-gate *f->fptr = (void *)¬_bound; 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate } 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate /* 1290Sstevel@tonic-gate * sdssc_bind_library -- entry point which resolves all cluster interface pts. 1300Sstevel@tonic-gate */ 1310Sstevel@tonic-gate rval_e 1320Sstevel@tonic-gate sdssc_bind_library(void) 1330Sstevel@tonic-gate { 1340Sstevel@tonic-gate void *dp; 1350Sstevel@tonic-gate int (*lb)(); 1360Sstevel@tonic-gate func_table_p ftp; 1378516SAchim.Maurer@Sun.COM static int initialised = 0; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate /* 1400Sstevel@tonic-gate * If already bound then just return okay so this routine 1410Sstevel@tonic-gate * becomes idempotent. If this check isn't made then we'll 1420Sstevel@tonic-gate * fail when calling the "_bind_library" function because 1430Sstevel@tonic-gate * dcs_initialize() can only be called once. 1448516SAchim.Maurer@Sun.COM * If not bound first time we try it again. 1450Sstevel@tonic-gate */ 1468516SAchim.Maurer@Sun.COM if (initialised && (void *)sdssc_version != (void *)not_bound) { 1478516SAchim.Maurer@Sun.COM return (SDSSC_OKAY); 1480Sstevel@tonic-gate } 1498516SAchim.Maurer@Sun.COM initialised = 1; 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate if ((dp = dlopen(SDSSC_PATH, RTLD_LAZY)) == NULL) { 1520Sstevel@tonic-gate set_common_routine(); 1530Sstevel@tonic-gate return (SDSSC_NOT_BOUND); 1540Sstevel@tonic-gate } else { 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * Allow the binding library to initialize state if 1580Sstevel@tonic-gate * necessary. Currently this calls the DCS initialize() 1590Sstevel@tonic-gate * routine which checks to see if we're part of a cluster. 1600Sstevel@tonic-gate */ 1610Sstevel@tonic-gate if ((lb = (int (*)())dlsym(dp, "_bind_library")) != NULL) { 1620Sstevel@tonic-gate if (lb() != 0) { 1630Sstevel@tonic-gate set_common_routine(); 1640Sstevel@tonic-gate return (SDSSC_NOT_BOUND); 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * Load 'em up. Pick up the function address and store 1700Sstevel@tonic-gate * the values in the global pointers for other routines 1710Sstevel@tonic-gate * to use. 1720Sstevel@tonic-gate */ 1730Sstevel@tonic-gate for (ftp = dl_table; ftp->fptr != (void *)0; ftp++) { 1740Sstevel@tonic-gate if ((*ftp->fptr = dlsym(dp, ftp->fname)) == NULL) { 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate /* 1770Sstevel@tonic-gate * If old libsdssc library is there, then 178*10728SJohn.Harres@Sun.COM * _sdssc_mo_create_begin is not yet supported. 1790Sstevel@tonic-gate */ 1800Sstevel@tonic-gate if (strcmp(ftp->fname, 181*10728SJohn.Harres@Sun.COM "_sdssc_mo_create_begin") == 0) { 1820Sstevel@tonic-gate *ftp->fptr = (void *)¬_bound_error; 1830Sstevel@tonic-gate continue; 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate /* 1860Sstevel@tonic-gate * If this routine fails to find a single 1870Sstevel@tonic-gate * entry point that it's expecting 188*10728SJohn.Harres@Sun.COM * (except _sdssc_mo_create_begin) then 1890Sstevel@tonic-gate * setup non-sdssc stubs routines 1900Sstevel@tonic-gate * as function pointers. 1910Sstevel@tonic-gate */ 1920Sstevel@tonic-gate set_common_routine(); 1930Sstevel@tonic-gate return (SDSSC_ERROR); 1940Sstevel@tonic-gate } 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate return (SDSSC_OKAY); 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate } 200