1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _DEVINFO_DEVLINK_H 28*7c478bd9Sstevel@tonic-gate #define _DEVINFO_DEVLINK_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 33*7c478bd9Sstevel@tonic-gate extern "C" { 34*7c478bd9Sstevel@tonic-gate #endif 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #define _POSIX_PTHREAD_SEMANTICS /* For readdir_r */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate #include <thread.h> 43*7c478bd9Sstevel@tonic-gate #include <synch.h> 44*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 45*7c478bd9Sstevel@tonic-gate #include <limits.h> 46*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 47*7c478bd9Sstevel@tonic-gate #include <dirent.h> 48*7c478bd9Sstevel@tonic-gate #include <regex.h> 49*7c478bd9Sstevel@tonic-gate #include <errno.h> 50*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/uio.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/mman.h> 56*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 57*7c478bd9Sstevel@tonic-gate #include <door.h> 58*7c478bd9Sstevel@tonic-gate #include <signal.h> 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate struct db_link { 61*7c478bd9Sstevel@tonic-gate uint32_t attr; /* primary or secondary */ 62*7c478bd9Sstevel@tonic-gate uint32_t path; /* link path */ 63*7c478bd9Sstevel@tonic-gate uint32_t content; /* link content */ 64*7c478bd9Sstevel@tonic-gate uint32_t sib; /* next link for same minor */ 65*7c478bd9Sstevel@tonic-gate }; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate struct db_minor { 68*7c478bd9Sstevel@tonic-gate uint32_t name; /* minor name */ 69*7c478bd9Sstevel@tonic-gate uint32_t nodetype; /* minor node type */ 70*7c478bd9Sstevel@tonic-gate uint32_t sib; /* next minor for same node */ 71*7c478bd9Sstevel@tonic-gate uint32_t link; /* next minor for same node */ 72*7c478bd9Sstevel@tonic-gate }; 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate struct db_node { 75*7c478bd9Sstevel@tonic-gate uint32_t path; /* node path */ 76*7c478bd9Sstevel@tonic-gate uint32_t sib; /* node's sibling */ 77*7c478bd9Sstevel@tonic-gate uint32_t child; /* first child for this node */ 78*7c478bd9Sstevel@tonic-gate uint32_t minor; /* first minor for node */ 79*7c478bd9Sstevel@tonic-gate }; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate typedef enum db_seg { 82*7c478bd9Sstevel@tonic-gate DB_NODE = 0, 83*7c478bd9Sstevel@tonic-gate DB_MINOR, 84*7c478bd9Sstevel@tonic-gate DB_LINK, 85*7c478bd9Sstevel@tonic-gate DB_STR, 86*7c478bd9Sstevel@tonic-gate DB_TYPES, /* Number of non-header segments */ 87*7c478bd9Sstevel@tonic-gate DB_HEADER 88*7c478bd9Sstevel@tonic-gate } db_seg_t; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate struct db_hdr { 91*7c478bd9Sstevel@tonic-gate uint32_t magic; /* Magic number */ 92*7c478bd9Sstevel@tonic-gate uint32_t vers; /* database format version */ 93*7c478bd9Sstevel@tonic-gate uint32_t root_idx; /* index for root node */ 94*7c478bd9Sstevel@tonic-gate uint32_t dngl_idx; /* head of DB dangling links */ 95*7c478bd9Sstevel@tonic-gate uint32_t page_sz; /* page size for mmap alignment */ 96*7c478bd9Sstevel@tonic-gate uint32_t update_count; /* updates since last /dev synch up */ 97*7c478bd9Sstevel@tonic-gate uint32_t nelems[DB_TYPES]; /* Number of elements of each type */ 98*7c478bd9Sstevel@tonic-gate }; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate typedef struct cache_link { 102*7c478bd9Sstevel@tonic-gate char *path; /* link path */ 103*7c478bd9Sstevel@tonic-gate char *content; /* link content */ 104*7c478bd9Sstevel@tonic-gate uint_t attr; /* link attributes */ 105*7c478bd9Sstevel@tonic-gate struct cache_link *hash; /* next link on same hash chain */ 106*7c478bd9Sstevel@tonic-gate struct cache_link *sib; /* next link for same minor */ 107*7c478bd9Sstevel@tonic-gate struct cache_minor *minor; /* minor for this link */ 108*7c478bd9Sstevel@tonic-gate } cache_link_t; 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate typedef struct cache_minor { 111*7c478bd9Sstevel@tonic-gate char *name; /* minor name */ 112*7c478bd9Sstevel@tonic-gate char *nodetype; /* minor nodetype */ 113*7c478bd9Sstevel@tonic-gate struct cache_node *node; /* node for this minor */ 114*7c478bd9Sstevel@tonic-gate struct cache_minor *sib; /* next minor for same node */ 115*7c478bd9Sstevel@tonic-gate struct cache_link *link; /* first link pointing to minor */ 116*7c478bd9Sstevel@tonic-gate } cache_minor_t; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate typedef struct cache_node { 119*7c478bd9Sstevel@tonic-gate char *path; /* path */ 120*7c478bd9Sstevel@tonic-gate struct cache_node *parent; /* node's parent */ 121*7c478bd9Sstevel@tonic-gate struct cache_node *sib; /* node's sibling */ 122*7c478bd9Sstevel@tonic-gate struct cache_node *child; /* first child for this node */ 123*7c478bd9Sstevel@tonic-gate struct cache_minor *minor; /* first minor for node */ 124*7c478bd9Sstevel@tonic-gate } cache_node_t; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate struct cache { 127*7c478bd9Sstevel@tonic-gate uint_t flags; /* cache state */ 128*7c478bd9Sstevel@tonic-gate uint_t update_count; /* updates since /dev synchronization */ 129*7c478bd9Sstevel@tonic-gate uint_t hash_sz; /* number of hash chains */ 130*7c478bd9Sstevel@tonic-gate cache_link_t **hash; /* hash table */ 131*7c478bd9Sstevel@tonic-gate cache_node_t *root; /* root of cache tree */ 132*7c478bd9Sstevel@tonic-gate cache_link_t *dngl; /* list of dangling links */ 133*7c478bd9Sstevel@tonic-gate cache_minor_t *last_minor; /* last minor looked up */ 134*7c478bd9Sstevel@tonic-gate }; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate struct db { 137*7c478bd9Sstevel@tonic-gate int db_fd; /* database file */ 138*7c478bd9Sstevel@tonic-gate uint_t flags; /* database open mode */ 139*7c478bd9Sstevel@tonic-gate struct db_hdr *hdr; /* DB header */ 140*7c478bd9Sstevel@tonic-gate int seg_prot[DB_TYPES]; /* protection for segments */ 141*7c478bd9Sstevel@tonic-gate caddr_t seg_base[DB_TYPES]; /* base address for segments */ 142*7c478bd9Sstevel@tonic-gate }; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate struct di_devlink_handle { 145*7c478bd9Sstevel@tonic-gate char *dev_dir; /* <root-dir>/dev */ 146*7c478bd9Sstevel@tonic-gate uint_t flags; /* handle flags */ 147*7c478bd9Sstevel@tonic-gate uint_t error; /* records errors encountered */ 148*7c478bd9Sstevel@tonic-gate int lock_fd; /* lock file for updates */ 149*7c478bd9Sstevel@tonic-gate struct cache cache; 150*7c478bd9Sstevel@tonic-gate struct db db; 151*7c478bd9Sstevel@tonic-gate }; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate typedef struct link_desc { 154*7c478bd9Sstevel@tonic-gate regex_t *regp; 155*7c478bd9Sstevel@tonic-gate const char *minor_path; 156*7c478bd9Sstevel@tonic-gate uint_t flags; 157*7c478bd9Sstevel@tonic-gate void *arg; 158*7c478bd9Sstevel@tonic-gate int (*fcn)(di_devlink_t, void *); 159*7c478bd9Sstevel@tonic-gate int retval; 160*7c478bd9Sstevel@tonic-gate } link_desc_t; 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate struct tnode { 163*7c478bd9Sstevel@tonic-gate void *node; 164*7c478bd9Sstevel@tonic-gate int flags; 165*7c478bd9Sstevel@tonic-gate struct di_devlink_handle *handle; 166*7c478bd9Sstevel@tonic-gate }; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate struct di_devlink { 169*7c478bd9Sstevel@tonic-gate char *rel_path; 170*7c478bd9Sstevel@tonic-gate char *abs_path; 171*7c478bd9Sstevel@tonic-gate char *content; 172*7c478bd9Sstevel@tonic-gate int type; 173*7c478bd9Sstevel@tonic-gate }; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate typedef struct recurse { 176*7c478bd9Sstevel@tonic-gate void *data; 177*7c478bd9Sstevel@tonic-gate int (*fcn)(struct di_devlink_handle *, void *, const char *); 178*7c478bd9Sstevel@tonic-gate } recurse_t; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate /* 181*7c478bd9Sstevel@tonic-gate * Debug levels currently defined. 182*7c478bd9Sstevel@tonic-gate */ 183*7c478bd9Sstevel@tonic-gate typedef enum { 184*7c478bd9Sstevel@tonic-gate DBG_ERR = 1, 185*7c478bd9Sstevel@tonic-gate DBG_INFO, 186*7c478bd9Sstevel@tonic-gate DBG_STEP, 187*7c478bd9Sstevel@tonic-gate DBG_ALL 188*7c478bd9Sstevel@tonic-gate } debug_level_t; 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate #define DB_MAGIC 0xBAC2ACAB 192*7c478bd9Sstevel@tonic-gate #define DB_FILE ".devlink_db" 193*7c478bd9Sstevel@tonic-gate #define DB_TMP ".devlink_db_tmp" 194*7c478bd9Sstevel@tonic-gate #define DB_LOCK ".devlink_db_lock" 195*7c478bd9Sstevel@tonic-gate #define DB_PERMS (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR) 196*7c478bd9Sstevel@tonic-gate #define DB_LOCK_PERMS DB_PERMS 197*7c478bd9Sstevel@tonic-gate #define DB_VERSION 1 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate #define DB_NIL 0 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate #define DEV "/dev" 202*7c478bd9Sstevel@tonic-gate #define DEVICES_SUFFIX "ices" 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate #define HDR_LEN sizeof (struct db_hdr) 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate #define AVG_CHAIN_SIZE 20 /* Average number of links per chain */ 207*7c478bd9Sstevel@tonic-gate #define MIN_HASH_SIZE 1024 /* Min number of chains in hash table */ 208*7c478bd9Sstevel@tonic-gate #define MAX_UPDATE_INTERVAL 5 /* Max DB writes before synching with /dev */ 209*7c478bd9Sstevel@tonic-gate #define MAX_LOCK_RETRY 5 /* Max attempts at locking the update lock */ 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* 213*7c478bd9Sstevel@tonic-gate * Various flags private to the implementation 214*7c478bd9Sstevel@tonic-gate */ 215*7c478bd9Sstevel@tonic-gate #define A_PRIMARY 0x0001U 216*7c478bd9Sstevel@tonic-gate #define A_SECONDARY 0x0002U 217*7c478bd9Sstevel@tonic-gate #define A_LINK_TYPES 0x0003U /* Mask */ 218*7c478bd9Sstevel@tonic-gate #define A_VALID 0x0004U 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate #define TYPE_DB 0x0008U 221*7c478bd9Sstevel@tonic-gate #define TYPE_CACHE 0x0010U 222*7c478bd9Sstevel@tonic-gate #define CREATE_FLAG 0x0020U 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate #define INSERT_HEAD 0x0040U 225*7c478bd9Sstevel@tonic-gate #define INSERT_TAIL 0x0080U 226*7c478bd9Sstevel@tonic-gate #define OPEN_RDWR 0x0100U 227*7c478bd9Sstevel@tonic-gate #define OPEN_RDONLY 0x0200U 228*7c478bd9Sstevel@tonic-gate #define OPEN_FLAGS 0x0300U /* Mask */ 229*7c478bd9Sstevel@tonic-gate #define UNLINK_FROM_HASH 0x0400U 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate #define SET_VALID_ATTR(a) ((a) |= A_VALID) 232*7c478bd9Sstevel@tonic-gate #define CLR_VALID_ATTR(a) ((a) &= ~A_VALID) 233*7c478bd9Sstevel@tonic-gate #define GET_VALID_ATTR(a) ((a) & A_VALID) 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate #define SET_DB_ERR(h) ((h)->error = 1) 236*7c478bd9Sstevel@tonic-gate #define DB_ERR(h) ((h)->error) 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate #define LOOKUP_DB(f) ((f) & TYPE_DB) 239*7c478bd9Sstevel@tonic-gate #define LOOKUP_CACHE(f) ((f) & TYPE_CACHE) 240*7c478bd9Sstevel@tonic-gate #define CREATE_ELEM(f) ((f) & CREATE_FLAG) 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate #define IS_RDWR(f) (((f) & OPEN_FLAGS) == OPEN_RDWR) 243*7c478bd9Sstevel@tonic-gate #define IS_RDONLY(f) (((f) & OPEN_FLAGS) == OPEN_RDONLY) 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate #define HDL_RDWR(h) (((h)->flags & OPEN_FLAGS) == OPEN_RDWR) 246*7c478bd9Sstevel@tonic-gate #define HDL_RDONLY(h) (((h)->flags & OPEN_FLAGS) == OPEN_RDONLY) 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate #define CACHE(h) (&(h)->cache) 249*7c478bd9Sstevel@tonic-gate #define CACHE_ROOT(h) (CACHE(h)->root) 250*7c478bd9Sstevel@tonic-gate #define CACHE_HASH(h, i) (CACHE(h)->hash[i]) 251*7c478bd9Sstevel@tonic-gate #define CACHE_LAST(h) (CACHE(h)->last_minor) 252*7c478bd9Sstevel@tonic-gate #define CACHE_EMPTY(h) (CACHE(h)->root == NULL && CACHE(h)->dngl == NULL) 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate #define DB(h) (&(h)->db) 255*7c478bd9Sstevel@tonic-gate #define DB_HDR(h) (DB(h)->hdr) 256*7c478bd9Sstevel@tonic-gate #define DB_NUM(h, t) (DB_HDR(h)->nelems[t]) 257*7c478bd9Sstevel@tonic-gate #define DB_SEG(h, t) (DB(h)->seg_base[t]) 258*7c478bd9Sstevel@tonic-gate #define DB_SEG_PROT(h, t) (DB(h)->seg_prot[t]) 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate #define DB_OPEN(h) (DB_HDR(h) != NULL) 261*7c478bd9Sstevel@tonic-gate #define DB_RDWR(h) ((DB(h)->flags & OPEN_FLAGS) == OPEN_RDWR) 262*7c478bd9Sstevel@tonic-gate #define DB_RDONLY(h) ((DB(h)->flags & OPEN_FLAGS) == OPEN_RDONLY) 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate #define DB_EMPTY(h) (DB_HDR(h)->root_idx == DB_NIL && \ 265*7c478bd9Sstevel@tonic-gate DB_HDR(h)->dngl_idx == DB_NIL) 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate #define TYPE_NONE(f) (((f) & DI_LINK_TYPES) == 0) 268*7c478bd9Sstevel@tonic-gate #define TYPE_PRI(f) (((f) & DI_LINK_TYPES) == DI_PRIMARY_LINK) 269*7c478bd9Sstevel@tonic-gate #define TYPE_SEC(f) (((f) & DI_LINK_TYPES) == DI_SECONDARY_LINK) 270*7c478bd9Sstevel@tonic-gate #define LINK_TYPE(f) ((f) & DI_LINK_TYPES) 271*7c478bd9Sstevel@tonic-gate #define VALID_TYPE(f) (TYPE_NONE(f) || TYPE_PRI(f) || TYPE_SEC(f)) 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate #define VALID_STR(h, i, s) ((i) + strlen(s) + 1 <= DB_HDR(h)->nelems[DB_STR]) 274*7c478bd9Sstevel@tonic-gate #define VALID_INDEX(h, t, i) ((i) < DB_HDR(h)->nelems[t]) 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * Environment variables used by DEBUG version of code. 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate #define SKIP_DB "DEBUG_SKIP_DB" 280*7c478bd9Sstevel@tonic-gate #define SKIP_LAST_CACHE "DEBUG_SKIP_LAST_CACHE" 281*7c478bd9Sstevel@tonic-gate #define ALT_DB_DIR "DEBUG_ALT_DB_DIR" 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate /* 284*7c478bd9Sstevel@tonic-gate * Function prototypes 285*7c478bd9Sstevel@tonic-gate */ 286*7c478bd9Sstevel@tonic-gate static struct di_devlink_handle *handle_alloc(const char *dev_dir, 287*7c478bd9Sstevel@tonic-gate uint_t flags); 288*7c478bd9Sstevel@tonic-gate static int cache_alloc(struct di_devlink_handle *hdp); 289*7c478bd9Sstevel@tonic-gate static int open_db(struct di_devlink_handle *hdp, int flags); 290*7c478bd9Sstevel@tonic-gate static int invalid_db(struct di_devlink_handle *hdp, size_t fsize, long pg_sz); 291*7c478bd9Sstevel@tonic-gate static int read_nodes(struct di_devlink_handle *hdp, cache_node_t *pcnp, 292*7c478bd9Sstevel@tonic-gate uint32_t nidx); 293*7c478bd9Sstevel@tonic-gate static int read_minors(struct di_devlink_handle *hdp, cache_node_t *pcnp, 294*7c478bd9Sstevel@tonic-gate uint32_t nidx); 295*7c478bd9Sstevel@tonic-gate static int read_links(struct di_devlink_handle *hdp, cache_minor_t *pcmp, 296*7c478bd9Sstevel@tonic-gate uint32_t nidx); 297*7c478bd9Sstevel@tonic-gate static int init_hdr(struct di_devlink_handle *hdp, long page_sz, 298*7c478bd9Sstevel@tonic-gate uint32_t *count); 299*7c478bd9Sstevel@tonic-gate static size_t size_db(struct di_devlink_handle *hdp, long page_sz, 300*7c478bd9Sstevel@tonic-gate uint32_t *count); 301*7c478bd9Sstevel@tonic-gate static size_t seg_size(struct di_devlink_handle *hdp, int seg); 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate static cache_node_t *node_insert(struct di_devlink_handle *hdp, 304*7c478bd9Sstevel@tonic-gate cache_node_t *pcnp, const char *path, int insert); 305*7c478bd9Sstevel@tonic-gate static cache_minor_t *minor_insert(struct di_devlink_handle *hdp, 306*7c478bd9Sstevel@tonic-gate cache_node_t *pcnp, const char *name, const char *nodetype, 307*7c478bd9Sstevel@tonic-gate cache_minor_t **prev); 308*7c478bd9Sstevel@tonic-gate static cache_link_t *link_insert(struct di_devlink_handle *hdp, 309*7c478bd9Sstevel@tonic-gate cache_minor_t *mnp, const char *path, const char *content, uint32_t attr); 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate static void minor_delete(di_devlink_handle_t hdp, cache_minor_t *cmnp); 312*7c478bd9Sstevel@tonic-gate static void link_delete(di_devlink_handle_t hdp, cache_link_t *clp); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate static int write_nodes(struct di_devlink_handle *hdp, struct db_node *pdnp, 315*7c478bd9Sstevel@tonic-gate cache_node_t *cnp, uint32_t *next); 316*7c478bd9Sstevel@tonic-gate static int write_minors(struct di_devlink_handle *hdp, struct db_node *pdnp, 317*7c478bd9Sstevel@tonic-gate cache_minor_t *cmnp, uint32_t *next); 318*7c478bd9Sstevel@tonic-gate static int write_links(struct di_devlink_handle *hdp, struct db_minor *pdmp, 319*7c478bd9Sstevel@tonic-gate cache_link_t *clp, uint32_t *next); 320*7c478bd9Sstevel@tonic-gate static void rm_link_from_hash(struct di_devlink_handle *hdp, cache_link_t *clp); 321*7c478bd9Sstevel@tonic-gate static uint32_t write_string(struct di_devlink_handle *hdp, const char *str, 322*7c478bd9Sstevel@tonic-gate uint32_t *next); 323*7c478bd9Sstevel@tonic-gate static int close_db(struct di_devlink_handle *hdp); 324*7c478bd9Sstevel@tonic-gate static void cache_free(struct di_devlink_handle *hdp); 325*7c478bd9Sstevel@tonic-gate static void handle_free(struct di_devlink_handle **pp); 326*7c478bd9Sstevel@tonic-gate static void resolve_dangling_links(struct di_devlink_handle *hdp); 327*7c478bd9Sstevel@tonic-gate static void subtree_free(struct di_devlink_handle *hdp, cache_node_t **pp); 328*7c478bd9Sstevel@tonic-gate static void node_free(cache_node_t **pp); 329*7c478bd9Sstevel@tonic-gate static void minor_free(struct di_devlink_handle *hdp, cache_minor_t **pp); 330*7c478bd9Sstevel@tonic-gate static void link_free(cache_link_t **pp); 331*7c478bd9Sstevel@tonic-gate static void count_node(cache_node_t *cnp, uint32_t *count); 332*7c478bd9Sstevel@tonic-gate static void count_minor(cache_minor_t *mnp, uint32_t *count); 333*7c478bd9Sstevel@tonic-gate static void count_link(cache_link_t *clp, uint32_t *count); 334*7c478bd9Sstevel@tonic-gate static void count_string(const char *str, uint32_t *count); 335*7c478bd9Sstevel@tonic-gate static int visit_node(const char *path, void *arg); 336*7c478bd9Sstevel@tonic-gate static int walk_tree(char *cur, void *arg, 337*7c478bd9Sstevel@tonic-gate int (*node_callback)(const char *path, void *arg)); 338*7c478bd9Sstevel@tonic-gate static void *lookup_node(struct di_devlink_handle *hdp, char *path, 339*7c478bd9Sstevel@tonic-gate const int flags); 340*7c478bd9Sstevel@tonic-gate static cache_link_t *add_link(struct di_devlink_handle *hdp, const char *link, 341*7c478bd9Sstevel@tonic-gate const char *content, int primary); 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate static void *lookup_minor(struct di_devlink_handle *hdp, const char *minor_path, 344*7c478bd9Sstevel@tonic-gate const char *nodetype, const int flags); 345*7c478bd9Sstevel@tonic-gate static cache_link_t *link_hash(di_devlink_handle_t hdp, const char *link, 346*7c478bd9Sstevel@tonic-gate uint_t flags); 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate static void hash_insert(struct di_devlink_handle *hdp, cache_link_t *clp); 349*7c478bd9Sstevel@tonic-gate static uint_t hashfn(struct di_devlink_handle *hdp, const char *str); 350*7c478bd9Sstevel@tonic-gate static void get_db_path(struct di_devlink_handle *hdp, const char *fname, 351*7c478bd9Sstevel@tonic-gate char *buf, size_t blen); 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate static struct db_node *get_node(struct di_devlink_handle *hdp, uint32_t idx); 354*7c478bd9Sstevel@tonic-gate static struct db_node *set_node(struct di_devlink_handle *hdp, uint32_t idx); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate static struct db_minor *get_minor(struct di_devlink_handle *hdp, uint32_t idx); 357*7c478bd9Sstevel@tonic-gate static struct db_minor *set_minor(struct di_devlink_handle *hdp, uint32_t idx); 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate static struct db_link *get_link(struct di_devlink_handle *hdp, uint32_t idx); 360*7c478bd9Sstevel@tonic-gate static struct db_link *set_link(struct di_devlink_handle *hdp, uint32_t idx); 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate static char *get_string(struct di_devlink_handle *hdp, uint32_t idx); 363*7c478bd9Sstevel@tonic-gate static char *set_string(struct di_devlink_handle *hdp, uint32_t idx); 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate static void *map_seg(struct di_devlink_handle *hdp, uint32_t idx, int prot, 366*7c478bd9Sstevel@tonic-gate db_seg_t seg); 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate static int walk_db(struct di_devlink_handle *hdp, link_desc_t *linkp); 369*7c478bd9Sstevel@tonic-gate static int walk_all_links(struct di_devlink_handle *hdp, link_desc_t *linkp); 370*7c478bd9Sstevel@tonic-gate static int walk_matching_links(struct di_devlink_handle *hdp, 371*7c478bd9Sstevel@tonic-gate link_desc_t *linkp); 372*7c478bd9Sstevel@tonic-gate static int visit_link(struct di_devlink_handle *hdp, link_desc_t *linkp, 373*7c478bd9Sstevel@tonic-gate struct di_devlink *vlp); 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate static void walk_cache_minor(di_devlink_handle_t hdp, const char *mpath, 376*7c478bd9Sstevel@tonic-gate link_desc_t *linkp); 377*7c478bd9Sstevel@tonic-gate static int walk_cache_links(di_devlink_handle_t hdp, cache_link_t *clp, 378*7c478bd9Sstevel@tonic-gate link_desc_t *linkp); 379*7c478bd9Sstevel@tonic-gate static void walk_all_cache(di_devlink_handle_t hdp, link_desc_t *linkp); 380*7c478bd9Sstevel@tonic-gate static int cache_dev_link(struct di_devlink_handle *hdp, void *data, 381*7c478bd9Sstevel@tonic-gate const char *link_path); 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate static int walk_dev(struct di_devlink_handle *hdp, link_desc_t *linkp); 384*7c478bd9Sstevel@tonic-gate static int recurse_dev(struct di_devlink_handle *hdp, recurse_t *rp); 385*7c478bd9Sstevel@tonic-gate static int do_recurse(const char *dir, struct di_devlink_handle *hdp, 386*7c478bd9Sstevel@tonic-gate recurse_t *rp, int *retp); 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate static int check_attr(uint32_t attr); 389*7c478bd9Sstevel@tonic-gate static int attr2type(uint32_t attr); 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate static int check_args(link_desc_t *linkp); 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate static void *get_last_node(struct di_devlink_handle *hdp, const char *path, 394*7c478bd9Sstevel@tonic-gate int flags); 395*7c478bd9Sstevel@tonic-gate static void *get_last_minor(struct di_devlink_handle *hdp, 396*7c478bd9Sstevel@tonic-gate const char *devfs_path, const char *minor_name, int flags); 397*7c478bd9Sstevel@tonic-gate static void set_last_minor(struct di_devlink_handle *hdp, cache_minor_t *cmnp, 398*7c478bd9Sstevel@tonic-gate int flags); 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate static int enter_update_lock(struct di_devlink_handle *hdp); 401*7c478bd9Sstevel@tonic-gate static void exit_update_lock(struct di_devlink_handle *hdp); 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate static char *minor_colon(const char *path); 404*7c478bd9Sstevel@tonic-gate static const char *rel_path(struct di_devlink_handle *hdp, const char *path); 405*7c478bd9Sstevel@tonic-gate static int link_flag(uint_t flags); 406*7c478bd9Sstevel@tonic-gate static int s_readlink(const char *link, char *buf, size_t blen); 407*7c478bd9Sstevel@tonic-gate static cache_minor_t *link2minor(struct di_devlink_handle *hdp, 408*7c478bd9Sstevel@tonic-gate cache_link_t *clp); 409*7c478bd9Sstevel@tonic-gate static int link_cmp(cache_link_t *clp, const char *content, int type); 410*7c478bd9Sstevel@tonic-gate static void delete_unused_nodes(di_devlink_handle_t hdp, cache_node_t *cnp); 411*7c478bd9Sstevel@tonic-gate static void delete_unused_minor(di_devlink_handle_t hdp, cache_minor_t *cmnp); 412*7c478bd9Sstevel@tonic-gate static int synchronize_db(di_devlink_handle_t hdp); 413*7c478bd9Sstevel@tonic-gate static void dprintf(debug_level_t msglevel, const char *fmt, ...); 414*7c478bd9Sstevel@tonic-gate static di_devlink_handle_t devlink_snapshot(const char *root_dir); 415*7c478bd9Sstevel@tonic-gate static int devlink_create(const char *root, const char *name); 416*7c478bd9Sstevel@tonic-gate static int dca_init(const char *name, struct dca_off *dcp); 417*7c478bd9Sstevel@tonic-gate static void exec_cmd(const char *root, struct dca_off *dcp); 418*7c478bd9Sstevel@tonic-gate static int do_exec(const char *path, char *const argv[]); 419*7c478bd9Sstevel@tonic-gate static int start_daemon(const char *root); 420*7c478bd9Sstevel@tonic-gate static void daemon_call(const char *root, struct dca_off *dcp); 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate int is_minor_node(const char *contents, const char **mn_root); 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate #endif 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate #endif /* _DEVINFO_DEVLINK_H */ 429