1*3c4226f9Spjha /* 2*3c4226f9Spjha * CDDL HEADER START 3*3c4226f9Spjha * 4*3c4226f9Spjha * The contents of this file are subject to the terms of the 5*3c4226f9Spjha * Common Development and Distribution License (the "License"). 6*3c4226f9Spjha * You may not use this file except in compliance with the License. 7*3c4226f9Spjha * 8*3c4226f9Spjha * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*3c4226f9Spjha * or http://www.opensolaris.org/os/licensing. 10*3c4226f9Spjha * See the License for the specific language governing permissions 11*3c4226f9Spjha * and limitations under the License. 12*3c4226f9Spjha * 13*3c4226f9Spjha * When distributing Covered Code, include this CDDL HEADER in each 14*3c4226f9Spjha * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*3c4226f9Spjha * If applicable, add the following below this CDDL HEADER, with the 16*3c4226f9Spjha * fields enclosed by brackets "[]" replaced with your own identifying 17*3c4226f9Spjha * information: Portions Copyright [yyyy] [name of copyright owner] 18*3c4226f9Spjha * 19*3c4226f9Spjha * CDDL HEADER END 20*3c4226f9Spjha */ 21*3c4226f9Spjha 22*3c4226f9Spjha /* 23*3c4226f9Spjha * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*3c4226f9Spjha * Use is subject to license terms. 25*3c4226f9Spjha */ 26*3c4226f9Spjha 27*3c4226f9Spjha #pragma ident "%Z%%M% %I% %E% SMI" 28*3c4226f9Spjha 29*3c4226f9Spjha /* 30*3c4226f9Spjha * Interfaces for getting device configuration data from kernel 31*3c4226f9Spjha * through the devinfo driver. 32*3c4226f9Spjha */ 33*3c4226f9Spjha 34*3c4226f9Spjha #include <stdio.h> 35*3c4226f9Spjha #include <stdlib.h> 36*3c4226f9Spjha #include <string.h> 37*3c4226f9Spjha #include <strings.h> 38*3c4226f9Spjha #include <fcntl.h> 39*3c4226f9Spjha #include <unistd.h> 40*3c4226f9Spjha #include <sys/stat.h> 41*3c4226f9Spjha #include <sys/types.h> 42*3c4226f9Spjha #include <stdarg.h> 43*3c4226f9Spjha #include <unistd.h> 44*3c4226f9Spjha #include <libgen.h> 45*3c4226f9Spjha #include "libdevinfo.h" 46*3c4226f9Spjha 47*3c4226f9Spjha /* Function Prototypes */ 48*3c4226f9Spjha static int di_dli_open(char *, int, short, int); 49*3c4226f9Spjha 50*3c4226f9Spjha #define DLI_NAME 0x1 51*3c4226f9Spjha 52*3c4226f9Spjha /* 53*3c4226f9Spjha * Private hotplug interfaces to be used between cfgadm pci plugin and 54*3c4226f9Spjha * devfsadm link generator. 55*3c4226f9Spjha */ 56*3c4226f9Spjha 57*3c4226f9Spjha 58*3c4226f9Spjha /* 59*3c4226f9Spjha * returns a devlink info file name derived from <path> 60*3c4226f9Spjha * callers need to free the returned string 61*3c4226f9Spjha */ 62*3c4226f9Spjha char * 63*3c4226f9Spjha di_dli_name(char *path) 64*3c4226f9Spjha { 65*3c4226f9Spjha #define dliroot "/etc/devices/dli/info." 66*3c4226f9Spjha #define dliroot_len (sizeof (dliroot) - 1) 67*3c4226f9Spjha 68*3c4226f9Spjha char *dlipath; 69*3c4226f9Spjha int dlipathsz; 70*3c4226f9Spjha char *basep; 71*3c4226f9Spjha 72*3c4226f9Spjha basep = basename(path); 73*3c4226f9Spjha dlipathsz = strlen(basep) + dliroot_len + 1; 74*3c4226f9Spjha dlipath = malloc(sizeof (char) * dlipathsz); 75*3c4226f9Spjha 76*3c4226f9Spjha (void) snprintf(dlipath, dlipathsz, "%s%s", dliroot, basep); 77*3c4226f9Spjha dlipath[dlipathsz - 1] = '\0'; 78*3c4226f9Spjha return (dlipath); 79*3c4226f9Spjha 80*3c4226f9Spjha #undef dlipre 81*3c4226f9Spjha #undef dlipre_len 82*3c4226f9Spjha #undef dliroot 83*3c4226f9Spjha #undef dliroot_len 84*3c4226f9Spjha } 85*3c4226f9Spjha 86*3c4226f9Spjha 87*3c4226f9Spjha static int 88*3c4226f9Spjha di_dli_open(char *path, int oflag, short l_type, int flags) 89*3c4226f9Spjha { 90*3c4226f9Spjha int fd; 91*3c4226f9Spjha char *dlipath, *dlipath_dir, *dlipath_dup; 92*3c4226f9Spjha struct stat statbuf; 93*3c4226f9Spjha int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 94*3c4226f9Spjha flock_t lock; 95*3c4226f9Spjha 96*3c4226f9Spjha dlipath = (flags & DLI_NAME) ? di_dli_name(path) : (char *)path; 97*3c4226f9Spjha dlipath_dup = strdup(dlipath); 98*3c4226f9Spjha dlipath_dir = dirname(dlipath_dup); 99*3c4226f9Spjha 100*3c4226f9Spjha if (stat(dlipath_dir, &statbuf) < 0) { 101*3c4226f9Spjha if (mkdirp(dlipath_dir, 102*3c4226f9Spjha S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) { 103*3c4226f9Spjha fd = -1; 104*3c4226f9Spjha goto OUT; 105*3c4226f9Spjha } 106*3c4226f9Spjha } 107*3c4226f9Spjha 108*3c4226f9Spjha fd = open(dlipath, oflag, mode); 109*3c4226f9Spjha if (fd < 0) 110*3c4226f9Spjha goto OUT; 111*3c4226f9Spjha 112*3c4226f9Spjha if (fchmod(fd, mode) < 0) { 113*3c4226f9Spjha (void) close(fd); 114*3c4226f9Spjha fd = -1; 115*3c4226f9Spjha goto OUT; 116*3c4226f9Spjha } 117*3c4226f9Spjha 118*3c4226f9Spjha bzero(&lock, sizeof (lock)); 119*3c4226f9Spjha lock.l_type = l_type; 120*3c4226f9Spjha if (fcntl(fd, F_SETLKW, &lock) < 0) { 121*3c4226f9Spjha (void) close(fd); 122*3c4226f9Spjha fd = -1; 123*3c4226f9Spjha } 124*3c4226f9Spjha OUT: 125*3c4226f9Spjha free(dlipath_dup); 126*3c4226f9Spjha if (flags & DLI_NAME) 127*3c4226f9Spjha free(dlipath); 128*3c4226f9Spjha return (fd); 129*3c4226f9Spjha } 130*3c4226f9Spjha 131*3c4226f9Spjha 132*3c4226f9Spjha int 133*3c4226f9Spjha di_dli_openr(char *path) 134*3c4226f9Spjha { 135*3c4226f9Spjha return (di_dli_open(path, O_RDONLY, F_RDLCK, DLI_NAME)); 136*3c4226f9Spjha } 137*3c4226f9Spjha 138*3c4226f9Spjha 139*3c4226f9Spjha int 140*3c4226f9Spjha di_dli_openw(char *path) 141*3c4226f9Spjha { 142*3c4226f9Spjha return (di_dli_open(path, O_RDWR | O_SYNC | O_TRUNC | O_CREAT, 143*3c4226f9Spjha F_WRLCK, DLI_NAME)); 144*3c4226f9Spjha } 145*3c4226f9Spjha 146*3c4226f9Spjha 147*3c4226f9Spjha void 148*3c4226f9Spjha di_dli_close(int fd) 149*3c4226f9Spjha { 150*3c4226f9Spjha flock_t lock; 151*3c4226f9Spjha if (fd < 0) 152*3c4226f9Spjha return; 153*3c4226f9Spjha 154*3c4226f9Spjha bzero(&lock, sizeof (lock)); 155*3c4226f9Spjha lock.l_type = F_UNLCK; 156*3c4226f9Spjha (void) fcntl(fd, F_SETLK, &lock); 157*3c4226f9Spjha (void) close(fd); 158*3c4226f9Spjha } 159