summaryrefslogtreecommitdiff
path: root/usr/src/cmd/devfsadm/devfsadm_impl.h
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/devfsadm/devfsadm_impl.h
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/devfsadm/devfsadm_impl.h')
-rw-r--r--usr/src/cmd/devfsadm/devfsadm_impl.h549
1 files changed, 549 insertions, 0 deletions
diff --git a/usr/src/cmd/devfsadm/devfsadm_impl.h b/usr/src/cmd/devfsadm/devfsadm_impl.h
new file mode 100644
index 0000000000..3ea72ca908
--- /dev/null
+++ b/usr/src/cmd/devfsadm/devfsadm_impl.h
@@ -0,0 +1,549 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DEVFSADM_IMPL_H
+#define _DEVFSADM_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <locale.h>
+#include <libintl.h>
+#include <ctype.h>
+#include <signal.h>
+#include <deflt.h>
+#include <ftw.h>
+#include <sys/instance.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/int_types.h>
+#include <limits.h>
+#include <strings.h>
+#include <devfsadm.h>
+#include <libdevinfo.h>
+#include <sys/devinfo_impl.h>
+#include <sys/modctl.h>
+#include <libgen.h>
+#include <sys/hwconf.h>
+#include <sys/sunddi.h>
+#include <door.h>
+#include <syslog.h>
+#include <libsysevent.h>
+#include <thread.h>
+#include <message.h>
+#include <sys/cladm.h>
+#include <librcm.h>
+#include <sys/sysevent/eventdefs.h>
+#include <sys/sysevent/dev.h>
+#include <libzonecfg.h>
+#include <device_info.h>
+
+#undef DEBUG
+#ifndef DEBUG
+#define NDEBUG 1
+#else
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+
+
+#define DEV_LOCK_FILE ".devfsadm_dev.lock"
+#define DAEMON_LOCK_FILE ".devfsadm_daemon.lock"
+
+#define DEV "/dev"
+#define DEV_LEN 4
+#define DEVICES "/devices"
+#define DEVICES_LEN 8
+#define MODULE_DIRS "/usr/lib/devfsadm/linkmod"
+#define ALIASFILE "/etc/driver_aliases"
+#define NAME_TO_MAJOR "/etc/name_to_major"
+#define RECONFIG_BOOT "_INIT_RECONFIG"
+#define PID_STR_LEN 10
+#define EXTRA_PRIVS "/etc/security/extra_privs"
+#define DEV_POLICY "/etc/security/device_policy"
+#define LDEV_FILE "/etc/logindevperm"
+
+#define DEVFSADM_DEFAULT_FILE "/etc/default/devfsadm"
+
+#define MINOR_FINI_TIMEOUT_DEFAULT 2
+#define FORCE_CALL_MINOR_FINI 10
+
+
+#define SYNCH_DOOR_PERMS (S_IRUSR | S_IWUSR)
+
+#define ZONE_DOOR_PERMS (S_IRUSR | S_IWUSR)
+#define ZONE_REG_DOOR ".zone_reg_door"
+
+enum zreg_op {
+ ZONE_REG = 1,
+ ZONE_UNREG = 2
+};
+
+enum zreg_err {
+ ZONE_SUCCESS = 0,
+ ZONE_ERR_NOZONE = 1,
+ ZONE_ERR_DOOR = 2,
+ ZONE_ERR_REPOSITORY = 3,
+ ZONE_ERR_NOLIB = 4
+};
+
+struct zreg {
+ char zreg_zonename[ZONENAME_MAX];
+ enum zreg_op zreg_op;
+ enum zreg_err zreg_error;
+ int zreg_errno;
+};
+
+#define DRVCONFIG "drvconfig"
+#define DEVFSADM "devfsadm"
+#define DEVFSADMD "devfsadmd"
+#define DEVLINKS "devlinks"
+#define TAPES "tapes"
+#define AUDLINKS "audlinks"
+#define PORTS "ports"
+#define DISKS "disks"
+
+#define MAX_IDLE_DELAY 5
+#define MAX_DELAY 30
+#define NAME 0x01
+#define ADDR 0x03
+#define MINOR 0x04
+#define COUNTER 0x05
+#define CONSTANT 0x06
+#define TYPE 0x07
+#define TYPE_S "type"
+#define ADDR_S "addr"
+#define ADDR_S_LEN 4
+#define MINOR_S "minor"
+#define MINOR_S_LEN 5
+#define NAME_S "name"
+#define TAB '\t'
+#define NEWLINE '\n'
+#define MAX_DEVLINK_LINE 4028
+#define INTEGER 0
+#define LETTER 1
+#define MAX_PERM_LINE 256
+#define MAX_LDEV_LINE 256
+#define LDEV_DELIMS " \t\n"
+#define LDEV_DRVLIST_DELIMS "="
+#define LDEV_DRV_DELIMS ", \t\n"
+#define LDEV_DEV_DELIM ":"
+#define LDEV_DRVLIST_NAME "driver"
+
+#define TYPE_LINK 0x00
+#define TYPE_DEVICES 0x01
+
+#define CREATE_LINK 0x01
+#define READ_LINK 0x02
+#define CREATE_NODE 0x01
+#define READ_NODE 0x02
+
+#define DCA_CREATE_LINK 0x01
+#define DCA_FREE_LIST 0x02
+#define DCA_LOAD_DRV 0x04
+#define DCA_CHECK_TYPE 0x10
+#define DCA_NOTIFY_RCM 0x20
+#define DCA_FLUSH_PATHINST 0x40
+#define DCA_HOT_PLUG 0x80
+
+#define CACHE_STATE 0x0
+#define SYNC_STATE 0x1
+
+#define MODULE_ACTIVE 0x01
+
+#define MAX_SLEEP 120
+
+#define DEVLINKTAB_FILE "/etc/devlink.tab"
+
+#define MODULE_SUFFIX ".so"
+#define MINOR_INIT "minor_init"
+#define MINOR_FINI "minor_fini"
+#define _DEVFSADM_CREATE_REG "_devfsadm_create_reg"
+#define _DEVFSADM_REMOVE_REG "_devfsadm_remove_reg"
+
+#define NUM_EV_STR 4
+#define EV_TYPE 0
+#define EV_CLASS 1
+#define EV_PATH_NAME 2
+#define EV_MINOR_NAME 3
+
+/* add new debug level and meanings here */
+#define DEVLINK_MID "devfsadm:devlink"
+#define MODLOAD_MID "devfsadm:modload"
+#define INITFINI_MID "devfsadm:initfini"
+#define EVENT_MID "devfsadm:event"
+#define REMOVE_MID "devfsadm:remove"
+#define LOCK_MID "devfsadm:lock"
+#define PATH2INST_MID "devfsadm:path2inst"
+#define CACHE_MID "devfsadm:cache"
+#define BUILDCACHE_MID "devfsadm:buildcache"
+#define RECURSEDEV_MID "devfsadm:recursedev"
+#define INSTSYNC_MID "devfsadm:instsync"
+#define FILES_MID "devfsadm:files"
+#define ENUM_MID "devfsadm:enum"
+#define LINKCACHE_MID "devfsadm:linkcache"
+#define ADDREMCACHE_MID "devfsadm:addremcache"
+#define MALLOC_MID "devfsadm:malloc"
+#define ZONE_MID "devfsadm:zone"
+#define ALL_MID "all"
+
+#define DEVFSADM_DEBUG_ON (verbose == NULL) ? FALSE : TRUE
+
+typedef struct recurse_dev {
+ void (*fcn)(char *, void *);
+ void *data;
+} recurse_dev_t;
+
+typedef struct link {
+ char *devlink; /* without ".../dev/" prefix */
+ char *contents; /* without "../devices" prefix */
+ struct link *next;
+} link_t;
+
+typedef struct linkhead {
+ regex_t dir_re_compiled;
+ char *dir_re;
+ link_t *link;
+ link_t *nextlink;
+ struct linkhead *nexthead;
+} linkhead_t;
+
+typedef struct link_list {
+ int type;
+ char *constant;
+ int arg;
+ struct link_list *next;
+} link_list_t;
+
+typedef struct selector_list {
+ int key;
+ char *val;
+ int arg;
+ struct selector_list *next;
+} selector_list_t;
+
+typedef struct devlinktab_list {
+ int line_number;
+ char *selector_pattern;
+ char *p_link_pattern;
+ char *s_link_pattern;
+ selector_list_t *selector;
+ link_list_t *p_link;
+ link_list_t *s_link;
+ struct devlinktab_list *next;
+} devlinktab_list_t;
+
+typedef struct module {
+ char *name;
+ void *dlhandle;
+ int (*minor_init)();
+ int (*minor_fini)();
+ int flags;
+ struct module *next;
+} module_t;
+
+typedef struct create_list {
+ devfsadm_create_t *create;
+ module_t *modptr;
+ regex_t node_type_comp;
+ regex_t drv_name_comp;
+ struct create_list *next;
+} create_list_t;
+
+struct minor {
+ di_node_t node;
+ di_minor_t minor;
+ struct minor *next;
+};
+
+struct mlist {
+ struct minor *head;
+ struct minor *tail;
+};
+
+typedef struct remove_list {
+ devfsadm_remove_t *remove;
+ module_t *modptr;
+ struct remove_list *next;
+} remove_list_t;
+
+typedef struct cleanup_data {
+ int flags;
+ char *phypath;
+ remove_list_t *rm;
+} cleanup_data_t;
+
+typedef struct n2m {
+ major_t major;
+ char *driver;
+ struct n2m *next;
+} n2m_t;
+
+/* structures for devfsadm_enumerate() */
+typedef struct numeral {
+ char *id;
+ char *full_path;
+ int rule_index;
+ char *cmp_str;
+ struct numeral *next;
+} numeral_t;
+
+typedef struct numeral_set {
+ int re_count;
+ char **re;
+ numeral_t *headnumeral;
+ struct numeral_set *next;
+} numeral_set_t;
+
+typedef struct temp {
+ int integer;
+ struct temp *next;
+} temp_t;
+
+typedef struct driver_alias {
+ char *driver_name;
+ char *alias_name;
+ struct driver_alias *next;
+} driver_alias_t;
+
+struct driver_list {
+ char driver_name[MAXNAMELEN];
+ struct driver_list *next;
+};
+
+struct login_dev {
+ char *ldev_console;
+ int ldev_perms;
+ char *ldev_device;
+ regex_t ldev_device_regex;
+ struct driver_list *ldev_driver_list;
+ struct login_dev *ldev_next;
+};
+
+#define MAX_DEV_NAME_COUNT 100
+struct devlink_cb_arg {
+ char *dev_names[MAX_DEV_NAME_COUNT];
+ char *link_contents[MAX_DEV_NAME_COUNT];
+ int count;
+ int rv;
+};
+
+struct dca_impl {
+ char *dci_root;
+ char *dci_minor;
+ char *dci_driver;
+ void *dci_arg;
+ int dci_error;
+ int dci_flags;
+};
+
+struct zone_devinfo {
+ struct zone_devinfo *zone_next;
+ char *zone_path;
+ char *zone_name;
+ zone_dochandle_t zone_dochdl;
+};
+
+/* RCM related */
+struct rcm_eventq {
+ nvlist_t *nvl;
+ struct rcm_eventq *next;
+};
+
+static int devfsadm_enumerate_int_start(char *devfs_path,
+ int index, char **buf, devfsadm_enumerate_t rules[],
+ int nrules, char *start);
+static void startup_cache_sync_thread(void);
+static void set_root_devices_dev_dir(char *dir, int zone_mode);
+static void pre_and_post_cleanup(int flags);
+static void hot_cleanup(char *, char *, char *, char *, int);
+static void devfsadm_exit(int status);
+static void rm_link_from_cache(char *devlink);
+static void rm_all_links_from_cache();
+static void add_link_to_cache(char *devlink, char *physpath);
+static linkhead_t *get_cached_links(char *dir_re);
+static void build_devlink_list(char *check_link, void *data);
+static void instance_flush_thread(void);
+static void s_rmdir(char *path);
+static void rm_parent_dir_if_empty(char *path);
+static void free_link_list(link_list_t *head);
+static void free_selector_list(selector_list_t *head);
+void devfsadm_err_print(char *message, ...);
+void defvsadm_print(int level, char *message, ...);
+static int call_minor_init(module_t *module);
+static void load_module(char *module, char *cdir);
+static void invalidate_enumerate_cache(void);
+static pid_t enter_dev_lock(void);
+static void exit_dev_lock(void);
+static pid_t enter_daemon_lock(void);
+static void exit_daemon_lock(void);
+static int process_devlink_compat(di_minor_t minor, di_node_t node);
+static int alias(char *, char *);
+static int devfsadm_copy(void);
+static void flush_path_to_inst(void);
+static void detachfromtty(void);
+static void minor_process(di_node_t node, di_minor_t minor,
+ struct mlist *dep);
+static void read_minor_perm_file(void);
+static void read_driver_aliases_file(void);
+static void load_modules(void);
+static void unload_modules(void);
+static void *s_malloc(const size_t size);
+static void *s_zalloc(const size_t size);
+static void devfs_instance_mod(void);
+static void add_minor_pathname(char *, char *, char *);
+static int check_minor_type(di_node_t node, di_minor_t minor, void *arg);
+static void cache_deferred_minor(struct mlist *dep, di_node_t node,
+ di_minor_t minor);
+static int compare_field(char *full_name, char *field_item, int field);
+static int component_cat(char *link, char *name, int field);
+static void recurse_dev_re(char *current_dir, char *path_re, recurse_dev_t *rd);
+static void matching_dev(char *devpath, void *data);
+static int resolve_link(char *devpath, char **content_p, int *type_p,
+ char **devfs_path, int dangle);
+static int clean_ok(devfsadm_remove_t *remove);
+static int translate_major(dev_t old_dev, dev_t *new_dev);
+static int get_major_no(char *driver, major_t *major);
+static int load_n2m_table(char *filename);
+static int get_stat_info(char *, struct stat *);
+static char *new_id(numeral_t *, int, char *);
+static int find_enum_id(devfsadm_enumerate_t rules[], int nrules,
+ char *devfs_path, int index, char *min, int type, char **buf, int multiple);
+static void daemon_update(void);
+static void usage(void);
+static int getnexttoken(char *next, char **nextp, char **tokenpp, char *tchar);
+static int class_ok(char *class);
+static int create_link_common(char *devlink, char *contents, int *exists);
+static char *dequote(char *src);
+static void parse_args(int argc, char *argv[]);
+static void process_devinfo_tree(void);
+static void call_minor_fini_thread(void *arg);
+static void *s_realloc(void *ptr, const size_t size);
+static void read_devlinktab_file(void);
+static selector_list_t *create_selector_list(char *selector);
+static int parse_selector(char **selector, char **key, char **val);
+int devfsadm_noupdate(void);
+const char *devfsadm_root_path(void);
+static link_list_t *create_link_list(char *link);
+static void s_unlink(const char *file);
+static void s_closedir(DIR *dirp);
+static void s_mkdirp(const char *path, const mode_t mode);
+static int is_minor_node(char *contents, char **mn_root);
+static int construct_devlink(char *link, link_list_t *link_build,
+ char *contents, di_minor_t minor,
+ di_node_t node, char *pattern);
+static int split_devlinktab_entry(char *entry, char **selector, char **p_link,
+ char **s_link);
+static int devlink_matches(devlinktab_list_t *entry, di_minor_t minor,
+ di_node_t node);
+static int build_links(devlinktab_list_t *entry, di_minor_t minor,
+ di_node_t node);
+static numeral_set_t *get_enum_cache(devfsadm_enumerate_t rules[],
+ int nrules);
+static void enumerate_recurse(char *current_dir, char *path_left,
+ numeral_set_t *setp, devfsadm_enumerate_t rules[], int index);
+
+static int match_path_component(char *file_re, char *file, char **id,
+ int subexp);
+static void create_cached_numeral(char *path, numeral_set_t *setp,
+ char *numeral_id, devfsadm_enumerate_t rules[], int index);
+static int devfsadm_copy_file(const char *file, const struct stat *stat,
+ int flags, struct FTW *ftw);
+static void getattr(char *devname, char *aminor, int spectype, dev_t dev,
+ mode_t *mode, uid_t *uid, gid_t *gid);
+static int minor_matches_rule(di_node_t node, di_minor_t minor,
+ create_list_t *create);
+static void add_verbose_id(char *mid);
+static char *get_component(char *str, const char *comp_num);
+static char *alloc_cmp_str(const char *devfs_path, devfsadm_enumerate_t *dep);
+static int lookup_enum_cache(numeral_set_t *set, char *cmp_str,
+ devfsadm_enumerate_t rules[], int index, numeral_t **matchnpp);
+static void sync_handler(void *cookie, char *ap, size_t asize,
+ door_desc_t *dp, uint_t ndesc);
+static void zlist_insert(struct zone_devinfo *newzone);
+static void delete_zone(struct zone_devinfo *z);
+static struct zone_devinfo *zlist_remove(char *zone_name);
+static void zlist_deleteall_unlocked(void);
+static void call_zone_register(char *zone_name, int regop);
+static int register_all_zones(void);
+static void zone_reg_handler(void *cookie, char *ap, size_t asize,
+ door_desc_t *dp, uint_t ndesc);
+static int zone_pathcheck(char *checkpath);
+static void process_deferred_links(struct dca_impl *dcip, int flag);
+static void event_handler(sysevent_t *ev);
+static int rcm_init(void);
+static int notify_rcm(di_node_t node, char *minor_name);
+static void dca_impl_init(char *root, char *minor, struct dca_impl *dcip);
+static void lock_dev(void);
+static void unlock_dev(int flag);
+
+int load_devpolicy(void);
+static void load_dev_acl(void);
+static void load_minor_perm_file(void);
+
+static int (*librcm_alloc_handle)(char *, uint_t, void *, rcm_handle_t **);
+static void (*librcm_free_handle)(rcm_handle_t *);
+static int (*librcm_notify_event)(rcm_handle_t *, char *, uint_t, nvlist_t *,
+ rcm_info_t *);
+static nvlist_t *build_event_attributes(char *, char *, char *,
+ di_node_t, char *, int);
+static void log_event(char *, char *, nvlist_t *);
+static void build_and_log_event(char *, char *, char *, di_node_t);
+
+static void read_logindevperm_file(void);
+static void set_logindev_perms(char *devlink);
+
+static void reset_node_permissions(di_node_t, di_minor_t);
+
+
+/* convenient short hands */
+#define vprint devfsadm_print
+#define err_print devfsadm_errprint
+#define TRUE 1
+#define FALSE 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DEVFSADM_IMPL_H */