1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte /* 22fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte */ 25fcf3ce44SJohn Forte 26fcf3ce44SJohn Forte /* 27fcf3ce44SJohn Forte * This file contains the glue code that allows the NWS software to 28fcf3ce44SJohn Forte * determine whether a cluster disk service is local to this node or 29fcf3ce44SJohn Forte * not. 30fcf3ce44SJohn Forte * 31fcf3ce44SJohn Forte * See PSARC/1999/462 for more information on the interfaces from 32fcf3ce44SJohn Forte * suncluster that are used here. 33fcf3ce44SJohn Forte */ 34fcf3ce44SJohn Forte 35fcf3ce44SJohn Forte #include <sys/types.h> 36fcf3ce44SJohn Forte #include <sys/wait.h> 37fcf3ce44SJohn Forte #include <sys/mkdev.h> 38fcf3ce44SJohn Forte #include <sys/stat.h> 39fcf3ce44SJohn Forte #include <stdlib.h> 40fcf3ce44SJohn Forte #include <unistd.h> 41fcf3ce44SJohn Forte #include <string.h> 42fcf3ce44SJohn Forte #include <strings.h> 43fcf3ce44SJohn Forte #include <errno.h> 44fcf3ce44SJohn Forte #include <fcntl.h> 45fcf3ce44SJohn Forte #include <stdio.h> 46fcf3ce44SJohn Forte #include <dlfcn.h> 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte #include <sys/ncall/ncall.h> 49fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h> 50fcf3ce44SJohn Forte 51fcf3ce44SJohn Forte #include "cfg_cluster.h" 52fcf3ce44SJohn Forte #include "cfg_impl.h" 53fcf3ce44SJohn Forte #include "cfg.h" 54fcf3ce44SJohn Forte 55fcf3ce44SJohn Forte /* 56fcf3ce44SJohn Forte * Static variables 57fcf3ce44SJohn Forte */ 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte static scconf_nodeid_t cl_nodeid = (uint_t)0xffff; 60fcf3ce44SJohn Forte static char *cl_nodename = NULL; 61fcf3ce44SJohn Forte 62fcf3ce44SJohn Forte static void *libscstat; 63fcf3ce44SJohn Forte static void *libscconf; 64fcf3ce44SJohn Forte 65fcf3ce44SJohn Forte static hash_node_t **schash; 66fcf3ce44SJohn Forte static int init_sc_entry(); 67fcf3ce44SJohn Forte 68fcf3ce44SJohn Forte typedef struct hash_data_s { 69fcf3ce44SJohn Forte scstat_node_name_t scstat_node_name; 70fcf3ce44SJohn Forte } hash_data_t; 71fcf3ce44SJohn Forte 72fcf3ce44SJohn Forte /* 73fcf3ce44SJohn Forte * Global variables 74fcf3ce44SJohn Forte */ 75fcf3ce44SJohn Forte int cl_initialized = 0; 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte 78fcf3ce44SJohn Forte /* 79fcf3ce44SJohn Forte * Tell the linker to keep quiet. 80fcf3ce44SJohn Forte */ 81fcf3ce44SJohn Forte 82fcf3ce44SJohn Forte #pragma weak scconf_get_nodename 83fcf3ce44SJohn Forte #pragma weak scconf_strerr 84fcf3ce44SJohn Forte #pragma weak scconf_get_ds_by_devt 85fcf3ce44SJohn Forte 86fcf3ce44SJohn Forte #pragma weak scstat_get_ds_status 87fcf3ce44SJohn Forte #pragma weak scstat_free_ds_status 88fcf3ce44SJohn Forte #pragma weak scstat_strerr 89fcf3ce44SJohn Forte 90fcf3ce44SJohn Forte 91fcf3ce44SJohn Forte /* 92fcf3ce44SJohn Forte * Initialise the library if we have not done so before. 93fcf3ce44SJohn Forte * 94fcf3ce44SJohn Forte * - IMPORTANT - 95fcf3ce44SJohn Forte * 96fcf3ce44SJohn Forte * This must -never- be called from any command that can be started 97fcf3ce44SJohn Forte * from /usr/cluster/lib/sc/run_reserve (and hence 98fcf3ce44SJohn Forte * /usr/cluster/sbin/reconfig) or the system will deadlock 99fcf3ce44SJohn Forte * during switchover. This includes: 100fcf3ce44SJohn Forte * 101fcf3ce44SJohn Forte * - svadm (no options, "print") -- called during sv switchover 102fcf3ce44SJohn Forte * - all boot commands 103fcf3ce44SJohn Forte * 104fcf3ce44SJohn Forte * - grab this node's cluster nodeid 105fcf3ce44SJohn Forte * - attempt to dlopen() the suncluster shared libraries we need 106fcf3ce44SJohn Forte * - grab this node's cluster nodename 107fcf3ce44SJohn Forte * 108fcf3ce44SJohn Forte * Returns: 109fcf3ce44SJohn Forte * 0 - success 110fcf3ce44SJohn Forte * -1 - error, errno is set 111fcf3ce44SJohn Forte */ 112fcf3ce44SJohn Forte 113fcf3ce44SJohn Forte int 114fcf3ce44SJohn Forte cfg_cluster_init(void) 115fcf3ce44SJohn Forte { 116fcf3ce44SJohn Forte const char *scconf = "/usr/cluster/lib/libscconf.so.1"; 117fcf3ce44SJohn Forte const char *scstat = "/usr/cluster/lib/libscstat.so.1"; 118fcf3ce44SJohn Forte #ifdef DEBUG 119fcf3ce44SJohn Forte char errbuf[SCCONF_MAXSTRINGLEN]; 120fcf3ce44SJohn Forte #endif 121fcf3ce44SJohn Forte scconf_nodeid_t id; 122fcf3ce44SJohn Forte scconf_errno_t err; 123fcf3ce44SJohn Forte char *name; 124fcf3ce44SJohn Forte FILE *pipe; 125fcf3ce44SJohn Forte int rc; 126fcf3ce44SJohn Forte 127fcf3ce44SJohn Forte /* 128fcf3ce44SJohn Forte * First check to see if we really are a cluster as clinfo -n can lie 129fcf3ce44SJohn Forte */ 130fcf3ce44SJohn Forte if (cl_nodeid == 0xffff) { 131fcf3ce44SJohn Forte rc = system("/usr/sbin/clinfo"); 132fcf3ce44SJohn Forte if (rc != -1 && WEXITSTATUS(rc) == 1) { 133fcf3ce44SJohn Forte /* not a cluster */ 134fcf3ce44SJohn Forte cl_initialized = 1; 135fcf3ce44SJohn Forte cl_nodeid = 0; 136fcf3ce44SJohn Forte return (0); 137fcf3ce44SJohn Forte } 138fcf3ce44SJohn Forte 139fcf3ce44SJohn Forte pipe = popen("/usr/sbin/clinfo -n 2>/dev/null || echo 0", "r"); 140fcf3ce44SJohn Forte if (pipe == NULL) { 141fcf3ce44SJohn Forte #ifdef DEBUG 142fcf3ce44SJohn Forte fprintf(stderr, "unable to get nodeid: %s\n", 143fcf3ce44SJohn Forte strerror(errno)); 144fcf3ce44SJohn Forte #endif 145fcf3ce44SJohn Forte return (-1); 146fcf3ce44SJohn Forte } 147fcf3ce44SJohn Forte 148fcf3ce44SJohn Forte if ((rc = fscanf(pipe, "%d", &id)) != 1) { 149fcf3ce44SJohn Forte #ifdef DEBUG 150fcf3ce44SJohn Forte fprintf(stderr, "unable to get nodeid: %s\n", 151fcf3ce44SJohn Forte strerror(errno)); 152fcf3ce44SJohn Forte #endif 153fcf3ce44SJohn Forte return (-1); 154fcf3ce44SJohn Forte } 155fcf3ce44SJohn Forte 156fcf3ce44SJohn Forte pclose(pipe); 157fcf3ce44SJohn Forte 158fcf3ce44SJohn Forte cl_nodeid = id; 159fcf3ce44SJohn Forte } 160fcf3ce44SJohn Forte 161fcf3ce44SJohn Forte /* Already loaded the Sun Cluster device tree */ 162fcf3ce44SJohn Forte if (cl_initialized) 163fcf3ce44SJohn Forte return (0); 164fcf3ce44SJohn Forte 165fcf3ce44SJohn Forte /* 166fcf3ce44SJohn Forte * Try and dlopen the various libraries that we need 167fcf3ce44SJohn Forte */ 168fcf3ce44SJohn Forte 169fcf3ce44SJohn Forte libscconf = dlopen(scconf, RTLD_LAZY | RTLD_GLOBAL); 170fcf3ce44SJohn Forte if (libscconf == NULL) 171fcf3ce44SJohn Forte goto error; 172fcf3ce44SJohn Forte 173fcf3ce44SJohn Forte libscstat = dlopen(scstat, RTLD_LAZY | RTLD_GLOBAL); 174fcf3ce44SJohn Forte if (libscstat == NULL) 175fcf3ce44SJohn Forte goto error; 176fcf3ce44SJohn Forte 177fcf3ce44SJohn Forte err = scconf_get_nodename(id, &name); 178fcf3ce44SJohn Forte if (err == SCCONF_EPERM) { 179fcf3ce44SJohn Forte cl_nodename = NULL; 180fcf3ce44SJohn Forte } else if (err != SCCONF_NOERR) { 181fcf3ce44SJohn Forte #ifdef DEBUG 182fcf3ce44SJohn Forte scconf_strerr(errbuf, err); 183fcf3ce44SJohn Forte fprintf(stderr, "scconf_get_nodename: %d: %s\n", err, errbuf); 184fcf3ce44SJohn Forte #endif 185fcf3ce44SJohn Forte goto error; 186fcf3ce44SJohn Forte } else 187fcf3ce44SJohn Forte cl_nodename = name; 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte /* Load the Sun Cluster device tree */ 190fcf3ce44SJohn Forte init_sc_entry(); 191fcf3ce44SJohn Forte cl_initialized = 1; 192fcf3ce44SJohn Forte return (0); 193fcf3ce44SJohn Forte 194fcf3ce44SJohn Forte error: /* error cleanup */ 195fcf3ce44SJohn Forte if (libscconf) 196fcf3ce44SJohn Forte dlclose(libscconf); 197fcf3ce44SJohn Forte 198fcf3ce44SJohn Forte if (libscstat) 199fcf3ce44SJohn Forte dlclose(libscstat); 200fcf3ce44SJohn Forte 201fcf3ce44SJohn Forte libscconf = NULL; 202fcf3ce44SJohn Forte libscstat = NULL; 203fcf3ce44SJohn Forte 204fcf3ce44SJohn Forte errno = ENOSYS; 205fcf3ce44SJohn Forte return (-1); 206fcf3ce44SJohn Forte } 207fcf3ce44SJohn Forte 208fcf3ce44SJohn Forte 209fcf3ce44SJohn Forte /* 210fcf3ce44SJohn Forte * cfg_issuncluster() 211fcf3ce44SJohn Forte * 212fcf3ce44SJohn Forte * Description: 213fcf3ce44SJohn Forte * Return the SunCluster nodeid of this node. 214fcf3ce44SJohn Forte * 215fcf3ce44SJohn Forte * Returns: 216fcf3ce44SJohn Forte * >0 - running in a SunCluster (value is nodeid of this node) 217fcf3ce44SJohn Forte * 0 - not running in a cluster 218fcf3ce44SJohn Forte * -1 - failure; errno is set 219fcf3ce44SJohn Forte */ 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte int 222fcf3ce44SJohn Forte cfg_issuncluster() 223fcf3ce44SJohn Forte { 224fcf3ce44SJohn Forte if (cfg_cluster_init() >= 0) 225fcf3ce44SJohn Forte return ((int)cl_nodeid); 226fcf3ce44SJohn Forte else 227fcf3ce44SJohn Forte return (-1); 228fcf3ce44SJohn Forte } 229fcf3ce44SJohn Forte int 230fcf3ce44SJohn Forte cfg_iscluster() 231fcf3ce44SJohn Forte { 232fcf3ce44SJohn Forte return (cfg_issuncluster()); 233fcf3ce44SJohn Forte } 234fcf3ce44SJohn Forte 235fcf3ce44SJohn Forte /* 236fcf3ce44SJohn Forte * cfg_l_dgname_islocal() 237fcf3ce44SJohn Forte * Check if disk group is local on a non-SunCluster. 238fcf3ce44SJohn Forte * 239fcf3ce44SJohn Forte * Returns as cfg_dgname_islocal(). 240fcf3ce44SJohn Forte */ 241fcf3ce44SJohn Forte #ifndef lint 242fcf3ce44SJohn Forte static int 243fcf3ce44SJohn Forte cfg_l_dgname_islocal(char *dgname, char **othernode) 244fcf3ce44SJohn Forte { 245fcf3ce44SJohn Forte const char *metaset = "/usr/sbin/metaset -s %s -o > /dev/null 2>&1"; 246fcf3ce44SJohn Forte char command[1024]; 247fcf3ce44SJohn Forte int rc; 248fcf3ce44SJohn Forte 249fcf3ce44SJohn Forte if (snprintf(command, sizeof (command), metaset, dgname) >= 250fcf3ce44SJohn Forte sizeof (command)) { 251fcf3ce44SJohn Forte errno = ENOMEM; 252fcf3ce44SJohn Forte return (-1); 253fcf3ce44SJohn Forte } 254fcf3ce44SJohn Forte 255fcf3ce44SJohn Forte rc = system(command); 256fcf3ce44SJohn Forte if (rc < 0) { 257fcf3ce44SJohn Forte return (-1); 258fcf3ce44SJohn Forte } 259fcf3ce44SJohn Forte 260fcf3ce44SJohn Forte if (WEXITSTATUS(rc) != 0) { 261fcf3ce44SJohn Forte if (othernode) { 262fcf3ce44SJohn Forte /* metaset doesn't tell us */ 263fcf3ce44SJohn Forte *othernode = "unknown"; 264fcf3ce44SJohn Forte } 265fcf3ce44SJohn Forte 266fcf3ce44SJohn Forte return (0); 267fcf3ce44SJohn Forte } 268fcf3ce44SJohn Forte 269fcf3ce44SJohn Forte return (1); 270fcf3ce44SJohn Forte } 271fcf3ce44SJohn Forte #endif 272fcf3ce44SJohn Forte 273fcf3ce44SJohn Forte /* 274fcf3ce44SJohn Forte * cfg_dgname_islocal(char *dgname, char **othernode) 275fcf3ce44SJohn Forte * -- determine if the named disk service is mastered on this node 276fcf3ce44SJohn Forte * 277fcf3ce44SJohn Forte * If the disk service is mastered on another node, that nodename 278fcf3ce44SJohn Forte * will be returned in othernode (if not NULL). It is up to the 279fcf3ce44SJohn Forte * calling program to call free() on this value at a later time to 280fcf3ce44SJohn Forte * free the memory allocated. 281fcf3ce44SJohn Forte * 282fcf3ce44SJohn Forte * Returns: 283fcf3ce44SJohn Forte * 1 - disk service is mastered on this node 284fcf3ce44SJohn Forte * 0 - disk service is not mastered on this node (*othernode set) 285fcf3ce44SJohn Forte * -1 - error (errno will be set) 286fcf3ce44SJohn Forte */ 287fcf3ce44SJohn Forte 288fcf3ce44SJohn Forte int 289fcf3ce44SJohn Forte cfg_dgname_islocal(char *dgname, char **othernode) 290fcf3ce44SJohn Forte { 291fcf3ce44SJohn Forte hash_data_t *data; 292fcf3ce44SJohn Forte 293fcf3ce44SJohn Forte if (dgname == NULL || *dgname == '\0' || othernode == NULL) { 294fcf3ce44SJohn Forte errno = EINVAL; 295fcf3ce44SJohn Forte return (-1); 296fcf3ce44SJohn Forte } 297fcf3ce44SJohn Forte 298fcf3ce44SJohn Forte /* Handle non-cluster configurations */ 299fcf3ce44SJohn Forte if (cfg_cluster_init() < 0) { 300fcf3ce44SJohn Forte return (-1); 301fcf3ce44SJohn Forte } else if (cl_nodeid == 0) { 302fcf3ce44SJohn Forte /* it has to be local */ 303fcf3ce44SJohn Forte return (1); 304fcf3ce44SJohn Forte } 305fcf3ce44SJohn Forte 306fcf3ce44SJohn Forte /* 307fcf3ce44SJohn Forte * lookup the current diskgroup name 308fcf3ce44SJohn Forte */ 309fcf3ce44SJohn Forte if (data = (hash_data_t *)nsc_lookup(schash, dgname)) { 310fcf3ce44SJohn Forte if (strcmp(data->scstat_node_name, cl_nodename)) { 311fcf3ce44SJohn Forte if (othernode) 312fcf3ce44SJohn Forte *othernode = strdup(data->scstat_node_name); 313fcf3ce44SJohn Forte return (0); 314fcf3ce44SJohn Forte } else { 315fcf3ce44SJohn Forte return (1); 316fcf3ce44SJohn Forte } 317fcf3ce44SJohn Forte } else { 318fcf3ce44SJohn Forte errno = ENODEV; 319fcf3ce44SJohn Forte return (-1); 320fcf3ce44SJohn Forte } 321fcf3ce44SJohn Forte } 322fcf3ce44SJohn Forte 323fcf3ce44SJohn Forte /* 324fcf3ce44SJohn Forte * cfg_l_dgname() 325fcf3ce44SJohn Forte * parse the disk group name from the a device pathname on a non-SunCluster. 326fcf3ce44SJohn Forte * 327fcf3ce44SJohn Forte * Returns as cfg_dgname(). 328fcf3ce44SJohn Forte */ 329fcf3ce44SJohn Forte 330fcf3ce44SJohn Forte char * 331fcf3ce44SJohn Forte cfg_l_dgname(const char *pathname, char *buffer, size_t buflen) 332fcf3ce44SJohn Forte { 333fcf3ce44SJohn Forte const char *dev = "/dev/"; 334fcf3ce44SJohn Forte const char *vx = "vx/"; 335fcf3ce44SJohn Forte const char *md = "md/"; 336fcf3ce44SJohn Forte const char *dsk = "dsk/"; 337fcf3ce44SJohn Forte const char *start, *cp; 338fcf3ce44SJohn Forte int ll, len, chkdsk; 339fcf3ce44SJohn Forte 340fcf3ce44SJohn Forte bzero(buffer, buflen); 341fcf3ce44SJohn Forte chkdsk = 0; 342fcf3ce44SJohn Forte 343fcf3ce44SJohn Forte ll = strlen(dev); 344fcf3ce44SJohn Forte if (strncmp(pathname, dev, ll) != 0) { 345fcf3ce44SJohn Forte /* not a device pathname */ 346fcf3ce44SJohn Forte errno = EINVAL; 347fcf3ce44SJohn Forte return ((char *)NULL); 348fcf3ce44SJohn Forte } 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte start = pathname + ll; 351fcf3ce44SJohn Forte 352*e373b6e4SYuri Pankov if (strncmp(start, vx, (ll = strlen(vx))) == 0) { 353fcf3ce44SJohn Forte /* 354fcf3ce44SJohn Forte * Veritas -- 355fcf3ce44SJohn Forte * /dev/vx/{r}dsk/dgname/partition 356fcf3ce44SJohn Forte */ 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte start += ll; 359fcf3ce44SJohn Forte 360fcf3ce44SJohn Forte ll = strlen(dsk); 361fcf3ce44SJohn Forte 362fcf3ce44SJohn Forte if (*start == 'r' && strncmp((start + 1), dsk, ll) == 0) 363fcf3ce44SJohn Forte start += ll + 1; 364fcf3ce44SJohn Forte else if (strncmp(start, dsk, ll) == 0) 365fcf3ce44SJohn Forte start += ll; 366fcf3ce44SJohn Forte else { 367fcf3ce44SJohn Forte /* no dgname */ 368fcf3ce44SJohn Forte return (buffer); 369fcf3ce44SJohn Forte } 370fcf3ce44SJohn Forte } else { 371fcf3ce44SJohn Forte /* no dgname */ 372fcf3ce44SJohn Forte return (buffer); 373fcf3ce44SJohn Forte } 374fcf3ce44SJohn Forte 375fcf3ce44SJohn Forte for (cp = start, len = 0; *cp != '\0' && *cp != '/'; cp++) 376fcf3ce44SJohn Forte len++; /* count length of dgname */ 377fcf3ce44SJohn Forte 378fcf3ce44SJohn Forte if (*cp == '\0') { 379fcf3ce44SJohn Forte /* no dgname */ 380fcf3ce44SJohn Forte return (buffer); 381fcf3ce44SJohn Forte } 382fcf3ce44SJohn Forte 383fcf3ce44SJohn Forte #ifdef DEBUG 384fcf3ce44SJohn Forte if (*cp != '/') { 385fcf3ce44SJohn Forte fprintf(stderr, 386fcf3ce44SJohn Forte "cfg_dgname: parse error: *cp = '%c', expected '/'\n", *cp); 387fcf3ce44SJohn Forte errno = EPROTO; 388fcf3ce44SJohn Forte return ((char *)NULL); 389fcf3ce44SJohn Forte } 390fcf3ce44SJohn Forte #endif 391fcf3ce44SJohn Forte 392fcf3ce44SJohn Forte if (chkdsk) { 393fcf3ce44SJohn Forte cp++; /* skip the NULL */ 394fcf3ce44SJohn Forte 395fcf3ce44SJohn Forte ll = strlen(dsk); 396fcf3ce44SJohn Forte 397fcf3ce44SJohn Forte if ((*cp != 'r' || strncmp((cp + 1), dsk, ll) != 0) && 398fcf3ce44SJohn Forte strncmp(cp, dsk, ll) != 0) { 399fcf3ce44SJohn Forte /* no dgname */ 400fcf3ce44SJohn Forte return (buffer); 401fcf3ce44SJohn Forte } 402fcf3ce44SJohn Forte } 403fcf3ce44SJohn Forte 404fcf3ce44SJohn Forte if (len >= buflen) { 405fcf3ce44SJohn Forte errno = E2BIG; 406fcf3ce44SJohn Forte return ((char *)NULL); 407fcf3ce44SJohn Forte } 408fcf3ce44SJohn Forte 409fcf3ce44SJohn Forte (void) strncpy(buffer, start, len); 410fcf3ce44SJohn Forte return (buffer); 411fcf3ce44SJohn Forte } 412fcf3ce44SJohn Forte 413fcf3ce44SJohn Forte 414fcf3ce44SJohn Forte /* 415fcf3ce44SJohn Forte * cfg_dgname() 416fcf3ce44SJohn Forte * determine which cluster resource group the pathname belongs to, if any 417fcf3ce44SJohn Forte * 418fcf3ce44SJohn Forte * Returns: 419fcf3ce44SJohn Forte * NULL - error (errno is set) 420fcf3ce44SJohn Forte * ptr to NULL-string - no dgname 421fcf3ce44SJohn Forte * pointer to string - dgname 422fcf3ce44SJohn Forte */ 423fcf3ce44SJohn Forte 424fcf3ce44SJohn Forte char * 425fcf3ce44SJohn Forte cfg_dgname(const char *pathname, char *buffer, size_t buflen) 426fcf3ce44SJohn Forte { 427fcf3ce44SJohn Forte scconf_errno_t conferr; 428fcf3ce44SJohn Forte char *dsname = NULL; 429fcf3ce44SJohn Forte struct stat stb; 430fcf3ce44SJohn Forte #ifdef DEBUG 431fcf3ce44SJohn Forte char errbuf[SCCONF_MAXSTRINGLEN]; 432fcf3ce44SJohn Forte #endif 433fcf3ce44SJohn Forte 434fcf3ce44SJohn Forte bzero(buffer, buflen); 435fcf3ce44SJohn Forte 436fcf3ce44SJohn Forte if (pathname == NULL || *pathname == '\0') { 437fcf3ce44SJohn Forte errno = EINVAL; 438fcf3ce44SJohn Forte return ((char *)NULL); 439fcf3ce44SJohn Forte } 440fcf3ce44SJohn Forte 441fcf3ce44SJohn Forte /* Handle non-cluster configurations */ 442fcf3ce44SJohn Forte if (cfg_cluster_init() < 0) { 443fcf3ce44SJohn Forte errno = EINVAL; 444fcf3ce44SJohn Forte return ((char *)NULL); 445fcf3ce44SJohn Forte } else if (cl_nodeid == 0) { 446fcf3ce44SJohn Forte /* must be local - return NULL-string dgname */ 447fcf3ce44SJohn Forte return (buffer); 448fcf3ce44SJohn Forte } 449fcf3ce44SJohn Forte 450fcf3ce44SJohn Forte if (stat(pathname, &stb) < 0) { 451fcf3ce44SJohn Forte errno = EINVAL; 452fcf3ce44SJohn Forte return ((char *)NULL); 453fcf3ce44SJohn Forte } 454fcf3ce44SJohn Forte 455fcf3ce44SJohn Forte conferr = scconf_get_ds_by_devt(major(stb.st_rdev), 456fcf3ce44SJohn Forte minor(stb.st_rdev), &dsname); 457fcf3ce44SJohn Forte 458fcf3ce44SJohn Forte if (conferr == SCCONF_ENOEXIST) { 459fcf3ce44SJohn Forte return (buffer); 460fcf3ce44SJohn Forte } else if (conferr != SCCONF_NOERR) { 461fcf3ce44SJohn Forte #ifdef DEBUG 462fcf3ce44SJohn Forte scconf_strerr(errbuf, conferr); 463fcf3ce44SJohn Forte fprintf(stderr, 464fcf3ce44SJohn Forte "scconf_get_ds_by_devt: %d: %s\n", conferr, errbuf); 465fcf3ce44SJohn Forte #endif 466fcf3ce44SJohn Forte errno = EINVAL; 467fcf3ce44SJohn Forte return ((char *)NULL); 468fcf3ce44SJohn Forte } 469fcf3ce44SJohn Forte 470fcf3ce44SJohn Forte strncpy(buffer, dsname, buflen); 471fcf3ce44SJohn Forte free(dsname); 472fcf3ce44SJohn Forte 473fcf3ce44SJohn Forte return (buffer); 474fcf3ce44SJohn Forte } 475fcf3ce44SJohn Forte 476fcf3ce44SJohn Forte 477fcf3ce44SJohn Forte /* 478fcf3ce44SJohn Forte * init_sc_entry 479fcf3ce44SJohn Forte * 480fcf3ce44SJohn Forte * Add an entry into the sclist and the schash for future lookups. 481fcf3ce44SJohn Forte * 482fcf3ce44SJohn Forte * - IMPORTANT - 483fcf3ce44SJohn Forte * 484fcf3ce44SJohn Forte * This must -never- be called from any command that can be started 485fcf3ce44SJohn Forte * from /usr/cluster/lib/sc/run_reserve (and hence 486fcf3ce44SJohn Forte * /usr/cluster/sbin/reconfig) or the system will deadlock 487fcf3ce44SJohn Forte * during switchover. This includes: 488fcf3ce44SJohn Forte * 489fcf3ce44SJohn Forte * - svadm (no options, "print") -- called during sv switchover 490fcf3ce44SJohn Forte * - all boot commands 491fcf3ce44SJohn Forte * 492fcf3ce44SJohn Forte * Return values: 493fcf3ce44SJohn Forte * -1 An error occurred. 494fcf3ce44SJohn Forte * 0 Entry added 495fcf3ce44SJohn Forte * 1 Entry already exists. 496fcf3ce44SJohn Forte */ 497fcf3ce44SJohn Forte static int 498fcf3ce44SJohn Forte init_sc_entry() 499fcf3ce44SJohn Forte { 500fcf3ce44SJohn Forte scstat_ds_node_state_t *dsn; 501fcf3ce44SJohn Forte scstat_ds_name_t dsname; 502fcf3ce44SJohn Forte scstat_ds_t *dsstatus, *dsp; 503fcf3ce44SJohn Forte scstat_errno_t err; 504fcf3ce44SJohn Forte #ifdef DEBUG 505fcf3ce44SJohn Forte char errbuf[SCCONF_MAXSTRINGLEN]; 506fcf3ce44SJohn Forte #endif 507fcf3ce44SJohn Forte 508fcf3ce44SJohn Forte hash_data_t *hdp; 509fcf3ce44SJohn Forte 510fcf3ce44SJohn Forte /* 511fcf3ce44SJohn Forte * Allocate a hash table 512fcf3ce44SJohn Forte */ 513fcf3ce44SJohn Forte if ((schash = nsc_create_hash()) == NULL) 514fcf3ce44SJohn Forte return (-1); 515fcf3ce44SJohn Forte 516fcf3ce44SJohn Forte /* 517fcf3ce44SJohn Forte * the API is broken here - the function is written to expect 518fcf3ce44SJohn Forte * the first argument to be (scstat_ds_name_t), but the function 519fcf3ce44SJohn Forte * declaration in scstat.h requires (scstat_ds_name_t *). 520fcf3ce44SJohn Forte * 521fcf3ce44SJohn Forte * We just cast it to get rid of the compiler warnings. 522fcf3ce44SJohn Forte * If "dsname" is NULL, information for all device services is returned 523fcf3ce44SJohn Forte */ 524fcf3ce44SJohn Forte dsstatus = NULL; 525fcf3ce44SJohn Forte dsname = NULL; 526fcf3ce44SJohn Forte /* LINTED pointer alignment */ 527fcf3ce44SJohn Forte err = scstat_get_ds_status((scstat_ds_name_t *)dsname, &dsstatus); 528fcf3ce44SJohn Forte if (err != SCSTAT_ENOERR) { 529fcf3ce44SJohn Forte #ifdef DEBUG 530fcf3ce44SJohn Forte scstat_strerr(err, errbuf); 531fcf3ce44SJohn Forte fprintf(stderr, "scstat_get_ds_status(): %d: %s\n", 532fcf3ce44SJohn Forte err, errbuf); 533fcf3ce44SJohn Forte #endif 534fcf3ce44SJohn Forte errno = ENOSYS; 535fcf3ce44SJohn Forte return (-1); 536fcf3ce44SJohn Forte } 537fcf3ce44SJohn Forte 538fcf3ce44SJohn Forte if (dsstatus == NULL) { 539fcf3ce44SJohn Forte errno = ENODEV; 540fcf3ce44SJohn Forte return (-1); 541fcf3ce44SJohn Forte } 542fcf3ce44SJohn Forte 543fcf3ce44SJohn Forte /* 544fcf3ce44SJohn Forte * Traverse scstat_ds list, saving away resource in out hash table 545fcf3ce44SJohn Forte */ 546fcf3ce44SJohn Forte for (dsp = dsstatus; dsp; dsp = dsp->scstat_ds_next) { 547fcf3ce44SJohn Forte 548fcf3ce44SJohn Forte /* Skip over NULL scstat_ds_name's */ 549fcf3ce44SJohn Forte if ((dsp->scstat_ds_name == NULL) || 550fcf3ce44SJohn Forte (dsp->scstat_ds_name[0] == '\0')) 551fcf3ce44SJohn Forte continue; 552fcf3ce44SJohn Forte 553fcf3ce44SJohn Forte /* See element exits already, error if so */ 554fcf3ce44SJohn Forte if (nsc_lookup(schash, dsp->scstat_ds_name)) { 555fcf3ce44SJohn Forte fprintf(stderr, "scstat_get_ds_status: duplicate %s", 556fcf3ce44SJohn Forte dsp->scstat_ds_name); 557fcf3ce44SJohn Forte errno = EEXIST; 558fcf3ce44SJohn Forte return (-1); 559fcf3ce44SJohn Forte } 560fcf3ce44SJohn Forte 561fcf3ce44SJohn Forte /* Traverse the node status list */ 562fcf3ce44SJohn Forte for (dsn = dsp->scstat_node_state_list; dsn; 563fcf3ce44SJohn Forte dsn = dsn->scstat_node_next) { 564fcf3ce44SJohn Forte /* 565fcf3ce44SJohn Forte * Only keep trace of primary nodes 566fcf3ce44SJohn Forte */ 567fcf3ce44SJohn Forte if (dsn->scstat_node_state != SCSTAT_PRIMARY) 568fcf3ce44SJohn Forte continue; 569fcf3ce44SJohn Forte 570fcf3ce44SJohn Forte /* Create an element to insert */ 571fcf3ce44SJohn Forte hdp = (hash_data_t *)malloc(sizeof (hash_data_t)); 572fcf3ce44SJohn Forte hdp->scstat_node_name = strdup(dsn->scstat_node_name); 573fcf3ce44SJohn Forte nsc_insert_node(schash, hdp, dsp->scstat_ds_name); 574fcf3ce44SJohn Forte } 575fcf3ce44SJohn Forte } 576fcf3ce44SJohn Forte 577fcf3ce44SJohn Forte /* 578fcf3ce44SJohn Forte * Free up scstat resources 579fcf3ce44SJohn Forte */ 580fcf3ce44SJohn Forte scstat_free_ds_status(dsstatus); 581fcf3ce44SJohn Forte return (0); 582fcf3ce44SJohn Forte } 583