17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*facf4a8dSllai1 * Common Development and Distribution License (the "License"). 6*facf4a8dSllai1 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate * 21*facf4a8dSllai1 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 227c478bd9Sstevel@tonic-gate * Use is subject to license terms. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _DEVINFO_DEVLINK_H 277c478bd9Sstevel@tonic-gate #define _DEVINFO_DEVLINK_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #ifdef __cplusplus 327c478bd9Sstevel@tonic-gate extern "C" { 337c478bd9Sstevel@tonic-gate #endif 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #define _POSIX_PTHREAD_SEMANTICS /* For readdir_r */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <stdio.h> 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <fcntl.h> 407c478bd9Sstevel@tonic-gate #include <string.h> 417c478bd9Sstevel@tonic-gate #include <thread.h> 427c478bd9Sstevel@tonic-gate #include <synch.h> 437c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 447c478bd9Sstevel@tonic-gate #include <limits.h> 457c478bd9Sstevel@tonic-gate #include <stdlib.h> 467c478bd9Sstevel@tonic-gate #include <dirent.h> 477c478bd9Sstevel@tonic-gate #include <regex.h> 487c478bd9Sstevel@tonic-gate #include <errno.h> 497c478bd9Sstevel@tonic-gate #include <stdarg.h> 507c478bd9Sstevel@tonic-gate #include <sys/uio.h> 517c478bd9Sstevel@tonic-gate #include <sys/types.h> 527c478bd9Sstevel@tonic-gate #include <sys/stat.h> 537c478bd9Sstevel@tonic-gate #include <sys/time.h> 547c478bd9Sstevel@tonic-gate #include <sys/mman.h> 557c478bd9Sstevel@tonic-gate #include <sys/wait.h> 567c478bd9Sstevel@tonic-gate #include <door.h> 577c478bd9Sstevel@tonic-gate #include <signal.h> 58*facf4a8dSllai1 #include <sys/statvfs.h> 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate struct db_link { 617c478bd9Sstevel@tonic-gate uint32_t attr; /* primary or secondary */ 627c478bd9Sstevel@tonic-gate uint32_t path; /* link path */ 637c478bd9Sstevel@tonic-gate uint32_t content; /* link content */ 647c478bd9Sstevel@tonic-gate uint32_t sib; /* next link for same minor */ 657c478bd9Sstevel@tonic-gate }; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate struct db_minor { 687c478bd9Sstevel@tonic-gate uint32_t name; /* minor name */ 697c478bd9Sstevel@tonic-gate uint32_t nodetype; /* minor node type */ 707c478bd9Sstevel@tonic-gate uint32_t sib; /* next minor for same node */ 717c478bd9Sstevel@tonic-gate uint32_t link; /* next minor for same node */ 727c478bd9Sstevel@tonic-gate }; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate struct db_node { 757c478bd9Sstevel@tonic-gate uint32_t path; /* node path */ 767c478bd9Sstevel@tonic-gate uint32_t sib; /* node's sibling */ 777c478bd9Sstevel@tonic-gate uint32_t child; /* first child for this node */ 787c478bd9Sstevel@tonic-gate uint32_t minor; /* first minor for node */ 797c478bd9Sstevel@tonic-gate }; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate typedef enum db_seg { 827c478bd9Sstevel@tonic-gate DB_NODE = 0, 837c478bd9Sstevel@tonic-gate DB_MINOR, 847c478bd9Sstevel@tonic-gate DB_LINK, 857c478bd9Sstevel@tonic-gate DB_STR, 867c478bd9Sstevel@tonic-gate DB_TYPES, /* Number of non-header segments */ 877c478bd9Sstevel@tonic-gate DB_HEADER 887c478bd9Sstevel@tonic-gate } db_seg_t; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate struct db_hdr { 917c478bd9Sstevel@tonic-gate uint32_t magic; /* Magic number */ 927c478bd9Sstevel@tonic-gate uint32_t vers; /* database format version */ 937c478bd9Sstevel@tonic-gate uint32_t root_idx; /* index for root node */ 947c478bd9Sstevel@tonic-gate uint32_t dngl_idx; /* head of DB dangling links */ 957c478bd9Sstevel@tonic-gate uint32_t page_sz; /* page size for mmap alignment */ 967c478bd9Sstevel@tonic-gate uint32_t update_count; /* updates since last /dev synch up */ 977c478bd9Sstevel@tonic-gate uint32_t nelems[DB_TYPES]; /* Number of elements of each type */ 987c478bd9Sstevel@tonic-gate }; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate typedef struct cache_link { 1027c478bd9Sstevel@tonic-gate char *path; /* link path */ 1037c478bd9Sstevel@tonic-gate char *content; /* link content */ 1047c478bd9Sstevel@tonic-gate uint_t attr; /* link attributes */ 1057c478bd9Sstevel@tonic-gate struct cache_link *hash; /* next link on same hash chain */ 1067c478bd9Sstevel@tonic-gate struct cache_link *sib; /* next link for same minor */ 1077c478bd9Sstevel@tonic-gate struct cache_minor *minor; /* minor for this link */ 1087c478bd9Sstevel@tonic-gate } cache_link_t; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate typedef struct cache_minor { 1117c478bd9Sstevel@tonic-gate char *name; /* minor name */ 1127c478bd9Sstevel@tonic-gate char *nodetype; /* minor nodetype */ 1137c478bd9Sstevel@tonic-gate struct cache_node *node; /* node for this minor */ 1147c478bd9Sstevel@tonic-gate struct cache_minor *sib; /* next minor for same node */ 1157c478bd9Sstevel@tonic-gate struct cache_link *link; /* first link pointing to minor */ 1167c478bd9Sstevel@tonic-gate } cache_minor_t; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate typedef struct cache_node { 1197c478bd9Sstevel@tonic-gate char *path; /* path */ 1207c478bd9Sstevel@tonic-gate struct cache_node *parent; /* node's parent */ 1217c478bd9Sstevel@tonic-gate struct cache_node *sib; /* node's sibling */ 1227c478bd9Sstevel@tonic-gate struct cache_node *child; /* first child for this node */ 1237c478bd9Sstevel@tonic-gate struct cache_minor *minor; /* first minor for node */ 1247c478bd9Sstevel@tonic-gate } cache_node_t; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate struct cache { 1277c478bd9Sstevel@tonic-gate uint_t flags; /* cache state */ 1287c478bd9Sstevel@tonic-gate uint_t update_count; /* updates since /dev synchronization */ 1297c478bd9Sstevel@tonic-gate uint_t hash_sz; /* number of hash chains */ 1307c478bd9Sstevel@tonic-gate cache_link_t **hash; /* hash table */ 1317c478bd9Sstevel@tonic-gate cache_node_t *root; /* root of cache tree */ 1327c478bd9Sstevel@tonic-gate cache_link_t *dngl; /* list of dangling links */ 1337c478bd9Sstevel@tonic-gate cache_minor_t *last_minor; /* last minor looked up */ 1347c478bd9Sstevel@tonic-gate }; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate struct db { 1377c478bd9Sstevel@tonic-gate int db_fd; /* database file */ 1387c478bd9Sstevel@tonic-gate uint_t flags; /* database open mode */ 1397c478bd9Sstevel@tonic-gate struct db_hdr *hdr; /* DB header */ 1407c478bd9Sstevel@tonic-gate int seg_prot[DB_TYPES]; /* protection for segments */ 1417c478bd9Sstevel@tonic-gate caddr_t seg_base[DB_TYPES]; /* base address for segments */ 1427c478bd9Sstevel@tonic-gate }; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate struct di_devlink_handle { 1457c478bd9Sstevel@tonic-gate char *dev_dir; /* <root-dir>/dev */ 146*facf4a8dSllai1 char *db_dir; /* <root-dir>/etc/dev */ 1477c478bd9Sstevel@tonic-gate uint_t flags; /* handle flags */ 1487c478bd9Sstevel@tonic-gate uint_t error; /* records errors encountered */ 1497c478bd9Sstevel@tonic-gate int lock_fd; /* lock file for updates */ 1507c478bd9Sstevel@tonic-gate struct cache cache; 1517c478bd9Sstevel@tonic-gate struct db db; 1527c478bd9Sstevel@tonic-gate }; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate typedef struct link_desc { 1557c478bd9Sstevel@tonic-gate regex_t *regp; 1567c478bd9Sstevel@tonic-gate const char *minor_path; 1577c478bd9Sstevel@tonic-gate uint_t flags; 1587c478bd9Sstevel@tonic-gate void *arg; 1597c478bd9Sstevel@tonic-gate int (*fcn)(di_devlink_t, void *); 1607c478bd9Sstevel@tonic-gate int retval; 1617c478bd9Sstevel@tonic-gate } link_desc_t; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate struct tnode { 1647c478bd9Sstevel@tonic-gate void *node; 1657c478bd9Sstevel@tonic-gate int flags; 1667c478bd9Sstevel@tonic-gate struct di_devlink_handle *handle; 1677c478bd9Sstevel@tonic-gate }; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate struct di_devlink { 1707c478bd9Sstevel@tonic-gate char *rel_path; 1717c478bd9Sstevel@tonic-gate char *abs_path; 1727c478bd9Sstevel@tonic-gate char *content; 1737c478bd9Sstevel@tonic-gate int type; 1747c478bd9Sstevel@tonic-gate }; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate typedef struct recurse { 1777c478bd9Sstevel@tonic-gate void *data; 1787c478bd9Sstevel@tonic-gate int (*fcn)(struct di_devlink_handle *, void *, const char *); 1797c478bd9Sstevel@tonic-gate } recurse_t; 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * Debug levels currently defined. 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate typedef enum { 1857c478bd9Sstevel@tonic-gate DBG_ERR = 1, 1867c478bd9Sstevel@tonic-gate DBG_INFO, 1877c478bd9Sstevel@tonic-gate DBG_STEP, 1887c478bd9Sstevel@tonic-gate DBG_ALL 1897c478bd9Sstevel@tonic-gate } debug_level_t; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate #define DB_MAGIC 0xBAC2ACAB 1937c478bd9Sstevel@tonic-gate #define DB_FILE ".devlink_db" 1947c478bd9Sstevel@tonic-gate #define DB_TMP ".devlink_db_tmp" 1957c478bd9Sstevel@tonic-gate #define DB_LOCK ".devlink_db_lock" 1967c478bd9Sstevel@tonic-gate #define DB_PERMS (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR) 1977c478bd9Sstevel@tonic-gate #define DB_LOCK_PERMS DB_PERMS 1987c478bd9Sstevel@tonic-gate #define DB_VERSION 1 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate #define DB_NIL 0 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate #define DEV "/dev" 203*facf4a8dSllai1 #define ETCDEV "/etc/dev" 2047c478bd9Sstevel@tonic-gate #define DEVICES_SUFFIX "ices" 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate #define HDR_LEN sizeof (struct db_hdr) 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate #define AVG_CHAIN_SIZE 20 /* Average number of links per chain */ 2097c478bd9Sstevel@tonic-gate #define MIN_HASH_SIZE 1024 /* Min number of chains in hash table */ 2107c478bd9Sstevel@tonic-gate #define MAX_UPDATE_INTERVAL 5 /* Max DB writes before synching with /dev */ 2117c478bd9Sstevel@tonic-gate #define MAX_LOCK_RETRY 5 /* Max attempts at locking the update lock */ 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /* 2157c478bd9Sstevel@tonic-gate * Various flags private to the implementation 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate #define A_PRIMARY 0x0001U 2187c478bd9Sstevel@tonic-gate #define A_SECONDARY 0x0002U 2197c478bd9Sstevel@tonic-gate #define A_LINK_TYPES 0x0003U /* Mask */ 2207c478bd9Sstevel@tonic-gate #define A_VALID 0x0004U 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate #define TYPE_DB 0x0008U 2237c478bd9Sstevel@tonic-gate #define TYPE_CACHE 0x0010U 2247c478bd9Sstevel@tonic-gate #define CREATE_FLAG 0x0020U 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate #define INSERT_HEAD 0x0040U 2277c478bd9Sstevel@tonic-gate #define INSERT_TAIL 0x0080U 2287c478bd9Sstevel@tonic-gate #define OPEN_RDWR 0x0100U 2297c478bd9Sstevel@tonic-gate #define OPEN_RDONLY 0x0200U 2307c478bd9Sstevel@tonic-gate #define OPEN_FLAGS 0x0300U /* Mask */ 2317c478bd9Sstevel@tonic-gate #define UNLINK_FROM_HASH 0x0400U 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate #define SET_VALID_ATTR(a) ((a) |= A_VALID) 2347c478bd9Sstevel@tonic-gate #define CLR_VALID_ATTR(a) ((a) &= ~A_VALID) 2357c478bd9Sstevel@tonic-gate #define GET_VALID_ATTR(a) ((a) & A_VALID) 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate #define SET_DB_ERR(h) ((h)->error = 1) 2387c478bd9Sstevel@tonic-gate #define DB_ERR(h) ((h)->error) 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate #define LOOKUP_DB(f) ((f) & TYPE_DB) 2417c478bd9Sstevel@tonic-gate #define LOOKUP_CACHE(f) ((f) & TYPE_CACHE) 2427c478bd9Sstevel@tonic-gate #define CREATE_ELEM(f) ((f) & CREATE_FLAG) 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate #define IS_RDWR(f) (((f) & OPEN_FLAGS) == OPEN_RDWR) 2457c478bd9Sstevel@tonic-gate #define IS_RDONLY(f) (((f) & OPEN_FLAGS) == OPEN_RDONLY) 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate #define HDL_RDWR(h) (((h)->flags & OPEN_FLAGS) == OPEN_RDWR) 2487c478bd9Sstevel@tonic-gate #define HDL_RDONLY(h) (((h)->flags & OPEN_FLAGS) == OPEN_RDONLY) 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate #define CACHE(h) (&(h)->cache) 2517c478bd9Sstevel@tonic-gate #define CACHE_ROOT(h) (CACHE(h)->root) 2527c478bd9Sstevel@tonic-gate #define CACHE_HASH(h, i) (CACHE(h)->hash[i]) 2537c478bd9Sstevel@tonic-gate #define CACHE_LAST(h) (CACHE(h)->last_minor) 2547c478bd9Sstevel@tonic-gate #define CACHE_EMPTY(h) (CACHE(h)->root == NULL && CACHE(h)->dngl == NULL) 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate #define DB(h) (&(h)->db) 2577c478bd9Sstevel@tonic-gate #define DB_HDR(h) (DB(h)->hdr) 2587c478bd9Sstevel@tonic-gate #define DB_NUM(h, t) (DB_HDR(h)->nelems[t]) 2597c478bd9Sstevel@tonic-gate #define DB_SEG(h, t) (DB(h)->seg_base[t]) 2607c478bd9Sstevel@tonic-gate #define DB_SEG_PROT(h, t) (DB(h)->seg_prot[t]) 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate #define DB_OPEN(h) (DB_HDR(h) != NULL) 2637c478bd9Sstevel@tonic-gate #define DB_RDWR(h) ((DB(h)->flags & OPEN_FLAGS) == OPEN_RDWR) 2647c478bd9Sstevel@tonic-gate #define DB_RDONLY(h) ((DB(h)->flags & OPEN_FLAGS) == OPEN_RDONLY) 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate #define DB_EMPTY(h) (DB_HDR(h)->root_idx == DB_NIL && \ 2677c478bd9Sstevel@tonic-gate DB_HDR(h)->dngl_idx == DB_NIL) 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate #define TYPE_NONE(f) (((f) & DI_LINK_TYPES) == 0) 2707c478bd9Sstevel@tonic-gate #define TYPE_PRI(f) (((f) & DI_LINK_TYPES) == DI_PRIMARY_LINK) 2717c478bd9Sstevel@tonic-gate #define TYPE_SEC(f) (((f) & DI_LINK_TYPES) == DI_SECONDARY_LINK) 2727c478bd9Sstevel@tonic-gate #define LINK_TYPE(f) ((f) & DI_LINK_TYPES) 2737c478bd9Sstevel@tonic-gate #define VALID_TYPE(f) (TYPE_NONE(f) || TYPE_PRI(f) || TYPE_SEC(f)) 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate #define VALID_STR(h, i, s) ((i) + strlen(s) + 1 <= DB_HDR(h)->nelems[DB_STR]) 2767c478bd9Sstevel@tonic-gate #define VALID_INDEX(h, t, i) ((i) < DB_HDR(h)->nelems[t]) 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Environment variables used by DEBUG version of code. 2807c478bd9Sstevel@tonic-gate */ 2817c478bd9Sstevel@tonic-gate #define SKIP_DB "DEBUG_SKIP_DB" 2827c478bd9Sstevel@tonic-gate #define SKIP_LAST_CACHE "DEBUG_SKIP_LAST_CACHE" 2837c478bd9Sstevel@tonic-gate #define ALT_DB_DIR "DEBUG_ALT_DB_DIR" 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /* 2867c478bd9Sstevel@tonic-gate * Function prototypes 2877c478bd9Sstevel@tonic-gate */ 2887c478bd9Sstevel@tonic-gate static struct di_devlink_handle *handle_alloc(const char *dev_dir, 2897c478bd9Sstevel@tonic-gate uint_t flags); 2907c478bd9Sstevel@tonic-gate static int cache_alloc(struct di_devlink_handle *hdp); 2917c478bd9Sstevel@tonic-gate static int open_db(struct di_devlink_handle *hdp, int flags); 2927c478bd9Sstevel@tonic-gate static int invalid_db(struct di_devlink_handle *hdp, size_t fsize, long pg_sz); 2937c478bd9Sstevel@tonic-gate static int read_nodes(struct di_devlink_handle *hdp, cache_node_t *pcnp, 2947c478bd9Sstevel@tonic-gate uint32_t nidx); 2957c478bd9Sstevel@tonic-gate static int read_minors(struct di_devlink_handle *hdp, cache_node_t *pcnp, 2967c478bd9Sstevel@tonic-gate uint32_t nidx); 2977c478bd9Sstevel@tonic-gate static int read_links(struct di_devlink_handle *hdp, cache_minor_t *pcmp, 2987c478bd9Sstevel@tonic-gate uint32_t nidx); 2997c478bd9Sstevel@tonic-gate static int init_hdr(struct di_devlink_handle *hdp, long page_sz, 3007c478bd9Sstevel@tonic-gate uint32_t *count); 3017c478bd9Sstevel@tonic-gate static size_t size_db(struct di_devlink_handle *hdp, long page_sz, 3027c478bd9Sstevel@tonic-gate uint32_t *count); 3037c478bd9Sstevel@tonic-gate static size_t seg_size(struct di_devlink_handle *hdp, int seg); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate static cache_node_t *node_insert(struct di_devlink_handle *hdp, 3067c478bd9Sstevel@tonic-gate cache_node_t *pcnp, const char *path, int insert); 3077c478bd9Sstevel@tonic-gate static cache_minor_t *minor_insert(struct di_devlink_handle *hdp, 3087c478bd9Sstevel@tonic-gate cache_node_t *pcnp, const char *name, const char *nodetype, 3097c478bd9Sstevel@tonic-gate cache_minor_t **prev); 3107c478bd9Sstevel@tonic-gate static cache_link_t *link_insert(struct di_devlink_handle *hdp, 3117c478bd9Sstevel@tonic-gate cache_minor_t *mnp, const char *path, const char *content, uint32_t attr); 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate static void minor_delete(di_devlink_handle_t hdp, cache_minor_t *cmnp); 3147c478bd9Sstevel@tonic-gate static void link_delete(di_devlink_handle_t hdp, cache_link_t *clp); 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate static int write_nodes(struct di_devlink_handle *hdp, struct db_node *pdnp, 3177c478bd9Sstevel@tonic-gate cache_node_t *cnp, uint32_t *next); 3187c478bd9Sstevel@tonic-gate static int write_minors(struct di_devlink_handle *hdp, struct db_node *pdnp, 3197c478bd9Sstevel@tonic-gate cache_minor_t *cmnp, uint32_t *next); 3207c478bd9Sstevel@tonic-gate static int write_links(struct di_devlink_handle *hdp, struct db_minor *pdmp, 3217c478bd9Sstevel@tonic-gate cache_link_t *clp, uint32_t *next); 3227c478bd9Sstevel@tonic-gate static void rm_link_from_hash(struct di_devlink_handle *hdp, cache_link_t *clp); 3237c478bd9Sstevel@tonic-gate static uint32_t write_string(struct di_devlink_handle *hdp, const char *str, 3247c478bd9Sstevel@tonic-gate uint32_t *next); 3257c478bd9Sstevel@tonic-gate static int close_db(struct di_devlink_handle *hdp); 3267c478bd9Sstevel@tonic-gate static void cache_free(struct di_devlink_handle *hdp); 3277c478bd9Sstevel@tonic-gate static void handle_free(struct di_devlink_handle **pp); 3287c478bd9Sstevel@tonic-gate static void resolve_dangling_links(struct di_devlink_handle *hdp); 3297c478bd9Sstevel@tonic-gate static void subtree_free(struct di_devlink_handle *hdp, cache_node_t **pp); 3307c478bd9Sstevel@tonic-gate static void node_free(cache_node_t **pp); 3317c478bd9Sstevel@tonic-gate static void minor_free(struct di_devlink_handle *hdp, cache_minor_t **pp); 3327c478bd9Sstevel@tonic-gate static void link_free(cache_link_t **pp); 3337c478bd9Sstevel@tonic-gate static void count_node(cache_node_t *cnp, uint32_t *count); 3347c478bd9Sstevel@tonic-gate static void count_minor(cache_minor_t *mnp, uint32_t *count); 3357c478bd9Sstevel@tonic-gate static void count_link(cache_link_t *clp, uint32_t *count); 3367c478bd9Sstevel@tonic-gate static void count_string(const char *str, uint32_t *count); 3377c478bd9Sstevel@tonic-gate static int visit_node(const char *path, void *arg); 3387c478bd9Sstevel@tonic-gate static int walk_tree(char *cur, void *arg, 3397c478bd9Sstevel@tonic-gate int (*node_callback)(const char *path, void *arg)); 3407c478bd9Sstevel@tonic-gate static void *lookup_node(struct di_devlink_handle *hdp, char *path, 3417c478bd9Sstevel@tonic-gate const int flags); 3427c478bd9Sstevel@tonic-gate static cache_link_t *add_link(struct di_devlink_handle *hdp, const char *link, 3437c478bd9Sstevel@tonic-gate const char *content, int primary); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate static void *lookup_minor(struct di_devlink_handle *hdp, const char *minor_path, 3467c478bd9Sstevel@tonic-gate const char *nodetype, const int flags); 3477c478bd9Sstevel@tonic-gate static cache_link_t *link_hash(di_devlink_handle_t hdp, const char *link, 3487c478bd9Sstevel@tonic-gate uint_t flags); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate static void hash_insert(struct di_devlink_handle *hdp, cache_link_t *clp); 3517c478bd9Sstevel@tonic-gate static uint_t hashfn(struct di_devlink_handle *hdp, const char *str); 3527c478bd9Sstevel@tonic-gate static void get_db_path(struct di_devlink_handle *hdp, const char *fname, 3537c478bd9Sstevel@tonic-gate char *buf, size_t blen); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate static struct db_node *get_node(struct di_devlink_handle *hdp, uint32_t idx); 3567c478bd9Sstevel@tonic-gate static struct db_node *set_node(struct di_devlink_handle *hdp, uint32_t idx); 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate static struct db_minor *get_minor(struct di_devlink_handle *hdp, uint32_t idx); 3597c478bd9Sstevel@tonic-gate static struct db_minor *set_minor(struct di_devlink_handle *hdp, uint32_t idx); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate static struct db_link *get_link(struct di_devlink_handle *hdp, uint32_t idx); 3627c478bd9Sstevel@tonic-gate static struct db_link *set_link(struct di_devlink_handle *hdp, uint32_t idx); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate static char *get_string(struct di_devlink_handle *hdp, uint32_t idx); 3657c478bd9Sstevel@tonic-gate static char *set_string(struct di_devlink_handle *hdp, uint32_t idx); 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate static void *map_seg(struct di_devlink_handle *hdp, uint32_t idx, int prot, 3687c478bd9Sstevel@tonic-gate db_seg_t seg); 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate static int walk_db(struct di_devlink_handle *hdp, link_desc_t *linkp); 3717c478bd9Sstevel@tonic-gate static int walk_all_links(struct di_devlink_handle *hdp, link_desc_t *linkp); 3727c478bd9Sstevel@tonic-gate static int walk_matching_links(struct di_devlink_handle *hdp, 3737c478bd9Sstevel@tonic-gate link_desc_t *linkp); 3747c478bd9Sstevel@tonic-gate static int visit_link(struct di_devlink_handle *hdp, link_desc_t *linkp, 3757c478bd9Sstevel@tonic-gate struct di_devlink *vlp); 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate static void walk_cache_minor(di_devlink_handle_t hdp, const char *mpath, 3787c478bd9Sstevel@tonic-gate link_desc_t *linkp); 3797c478bd9Sstevel@tonic-gate static int walk_cache_links(di_devlink_handle_t hdp, cache_link_t *clp, 3807c478bd9Sstevel@tonic-gate link_desc_t *linkp); 3817c478bd9Sstevel@tonic-gate static void walk_all_cache(di_devlink_handle_t hdp, link_desc_t *linkp); 3827c478bd9Sstevel@tonic-gate static int cache_dev_link(struct di_devlink_handle *hdp, void *data, 3837c478bd9Sstevel@tonic-gate const char *link_path); 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate static int walk_dev(struct di_devlink_handle *hdp, link_desc_t *linkp); 3867c478bd9Sstevel@tonic-gate static int recurse_dev(struct di_devlink_handle *hdp, recurse_t *rp); 3877c478bd9Sstevel@tonic-gate static int do_recurse(const char *dir, struct di_devlink_handle *hdp, 3887c478bd9Sstevel@tonic-gate recurse_t *rp, int *retp); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate static int check_attr(uint32_t attr); 3917c478bd9Sstevel@tonic-gate static int attr2type(uint32_t attr); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate static int check_args(link_desc_t *linkp); 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate static void *get_last_node(struct di_devlink_handle *hdp, const char *path, 3967c478bd9Sstevel@tonic-gate int flags); 3977c478bd9Sstevel@tonic-gate static void *get_last_minor(struct di_devlink_handle *hdp, 3987c478bd9Sstevel@tonic-gate const char *devfs_path, const char *minor_name, int flags); 3997c478bd9Sstevel@tonic-gate static void set_last_minor(struct di_devlink_handle *hdp, cache_minor_t *cmnp, 4007c478bd9Sstevel@tonic-gate int flags); 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate static int enter_update_lock(struct di_devlink_handle *hdp); 4037c478bd9Sstevel@tonic-gate static void exit_update_lock(struct di_devlink_handle *hdp); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate static char *minor_colon(const char *path); 4067c478bd9Sstevel@tonic-gate static const char *rel_path(struct di_devlink_handle *hdp, const char *path); 4077c478bd9Sstevel@tonic-gate static int link_flag(uint_t flags); 4087c478bd9Sstevel@tonic-gate static int s_readlink(const char *link, char *buf, size_t blen); 4097c478bd9Sstevel@tonic-gate static cache_minor_t *link2minor(struct di_devlink_handle *hdp, 4107c478bd9Sstevel@tonic-gate cache_link_t *clp); 4117c478bd9Sstevel@tonic-gate static int link_cmp(cache_link_t *clp, const char *content, int type); 4127c478bd9Sstevel@tonic-gate static void delete_unused_nodes(di_devlink_handle_t hdp, cache_node_t *cnp); 4137c478bd9Sstevel@tonic-gate static void delete_unused_minor(di_devlink_handle_t hdp, cache_minor_t *cmnp); 4147c478bd9Sstevel@tonic-gate static int synchronize_db(di_devlink_handle_t hdp); 4157c478bd9Sstevel@tonic-gate static void dprintf(debug_level_t msglevel, const char *fmt, ...); 4167c478bd9Sstevel@tonic-gate static di_devlink_handle_t devlink_snapshot(const char *root_dir); 4177c478bd9Sstevel@tonic-gate static int devlink_create(const char *root, const char *name); 4187c478bd9Sstevel@tonic-gate static int dca_init(const char *name, struct dca_off *dcp); 4197c478bd9Sstevel@tonic-gate static void exec_cmd(const char *root, struct dca_off *dcp); 4207c478bd9Sstevel@tonic-gate static int do_exec(const char *path, char *const argv[]); 4217c478bd9Sstevel@tonic-gate static int start_daemon(const char *root); 4227c478bd9Sstevel@tonic-gate static void daemon_call(const char *root, struct dca_off *dcp); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate int is_minor_node(const char *contents, const char **mn_root); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate #ifdef __cplusplus 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate #endif 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate #endif /* _DEVINFO_DEVLINK_H */ 431