diff options
author | llai1 <none@none> | 2006-08-25 17:24:25 -0700 |
---|---|---|
committer | llai1 <none@none> | 2006-08-25 17:24:25 -0700 |
commit | facf4a8d7b59fde89a8662b4f4c73a758e6c402c (patch) | |
tree | 4e0024c5508351006df1496ec4be6e7b564c3ce8 /usr/src/uts/common/os/devctl.c | |
parent | adcafb0fe4c49c4d46c0b393dfba36d4e1b55c0e (diff) | |
download | illumos-gate-facf4a8d7b59fde89a8662b4f4c73a758e6c402c.tar.gz |
PSARC/2003/246 Filesystem Driven Device Naming
5050715 logical device names not created during early boot
6292952 devfsadm mishandles optarg
6362924 devfsadm secondary link generation is not zones aware
6413127 Integrate the Devname Project
6464196 bfu should remove pt_chmod, obsoleted by /dev filesystem
--HG--
rename : usr/src/cmd/pt_chmod/Makefile => deleted_files/usr/src/cmd/pt_chmod/Makefile
rename : usr/src/cmd/pt_chmod/pt_chmod.c => deleted_files/usr/src/cmd/pt_chmod/pt_chmod.c
Diffstat (limited to 'usr/src/uts/common/os/devctl.c')
-rw-r--r-- | usr/src/uts/common/os/devctl.c | 447 |
1 files changed, 326 insertions, 121 deletions
diff --git a/usr/src/uts/common/os/devctl.c b/usr/src/uts/common/os/devctl.c index 57a7c05ac8..90354cde34 100644 --- a/usr/src/uts/common/os/devctl.c +++ b/usr/src/uts/common/os/devctl.c @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -51,7 +50,6 @@ #include <sys/fs/snode.h> #include <sys/fs/dv_node.h> #include <sys/kobj.h> - #include <sys/devctl_impl.h> @@ -65,6 +63,8 @@ int devid_discovery_secs = 0; int devid_cache_read_disable = 0; int devid_cache_write_disable = 0; +int sdev_cache_read_disable = 0; +int sdev_cache_write_disable = 0; int kfio_report_error = 0; /* kernel file i/o operations */ int devid_report_error = 0; /* devid cache operations */ @@ -78,13 +78,46 @@ static kmutex_t devid_discovery_mutex; static kcondvar_t devid_discovery_cv; static clock_t devid_last_discovery = 0; + +static int devid_nvp2nvl(nvfd_t *, nvlist_t **); +static nvp_list_t *devid_nvl2nvp(nvlist_t *, char *); +static void devid_nvp_free(nvp_list_t *); + +static int sdev_nvp2nvl(nvfd_t *, nvlist_t **); +static nvp_list_t *sdev_nvl2nvp(nvlist_t *, char *); +static void sdev_nvp_free(nvp_list_t *); + /* - * Descriptor for /etc/devices/devid_cache + * Descriptors for the /etc/devices cache files */ -nvfd_t devid_cache_fd = { +static nvfd_t devid_cache_fd = { "/etc/devices/devid_cache", + devid_nvp2nvl, /* nvf_nvp2nvl */ + devid_nvl2nvp, /* nvf_nvl2nvp */ + devid_nvp_free, /* nvf_nvp_free */ + NULL, /* nvf_write_complete */ + 0, NULL, NULL, 0 + }; -static nvfd_t *dcfd = &devid_cache_fd; +static nvfd_t sdev_cache_fd = { + "/etc/devices/devname_cache", + sdev_nvp2nvl, /* nvf_nvp2nvl */ + sdev_nvl2nvp, /* nvf_nvl2nvp */ + sdev_nvp_free, /* nvf_nvp_free */ + NULL, /* nvf_write_complete */ + 0, NULL, NULL, 0 +}; + +static nvfd_t *dcfd = &devid_cache_fd; +nvfd_t *sdevfd = &sdev_cache_fd; + +static nvfd_t *cachefds[] = { + &devid_cache_fd, + &sdev_cache_fd +}; + +#define NCACHEFDS ((sizeof (cachefds)) / (sizeof (nvfd_t *))) + extern int modrootloaded; @@ -122,6 +155,11 @@ i_ddi_devices_init(void) dcfd->nvf_tail = NULL; rw_init(&dcfd->nvf_lock, NULL, RW_DRIVER, NULL); + sdevfd->nvf_flags = 0; + sdevfd->nvf_list = NULL; + sdevfd->nvf_tail = NULL; + rw_init(&sdevfd->nvf_lock, NULL, RW_DRIVER, NULL); + mutex_init(&devid_discovery_mutex, NULL, MUTEX_DEFAULT, NULL); cv_init(&devid_discovery_cv, NULL, CV_DRIVER, NULL); } @@ -546,44 +584,63 @@ e_fwrite_nvlist(nvfd_t *nvfd, nvlist_t *nvl) } static void -nvp_free(nvp_list_t *np) +devid_nvp_free(nvp_list_t *np) +{ + nvp_devid_t *dp = NVP2DEVID(np); + + if (dp->nvp_devpath) + kmem_free(dp->nvp_devpath, strlen(dp->nvp_devpath)+1); + if (dp->nvp_devid) + kmem_free(dp->nvp_devid, ddi_devid_sizeof(dp->nvp_devid)); + + kmem_free(dp, sizeof (nvp_devid_t)); +} + +static void +sdev_nvp_free(nvp_list_t *np) { - if (np->nvp_devpath) - kmem_free(np->nvp_devpath, strlen(np->nvp_devpath)+1); - if (np->nvp_devid) - kmem_free(np->nvp_devid, ddi_devid_sizeof(np->nvp_devid)); + nvp_devname_t *dp = NVP2DEVNAME(np); + int i; + char **p; + + if (dp->nvp_npaths > 0) { + p = dp->nvp_paths; + for (i = 0; i < dp->nvp_npaths; i++, p++) { + kmem_free(*p, strlen(*p)+1); + } + kmem_free(dp->nvp_paths, + dp->nvp_npaths * sizeof (char *)); + kmem_free(dp->nvp_expirecnts, + dp->nvp_npaths * sizeof (int)); + } - kmem_free(np, sizeof (nvp_list_t)); + kmem_free(dp, sizeof (nvp_devname_t)); } static void -nvp_list_free(nvp_list_t *nvp) +nvp_list_free(nvfd_t *nvf, nvp_list_t *nvp) { nvp_list_t *np; nvp_list_t *next; for (np = nvp; np; np = next) { next = np->nvp_next; - nvp_free(np); + (nvf->nvf_nvp_free)(np); } } + /* - * Free the devid-related information in an nvp element - * If no more data is stored in the nvp element, free - * it and unlink it from the list - * - * Since at present there is no further use of nvp's, - * there's nothing to check. + * Free an nvp element in a list */ -static nvp_list_t * -nfd_devid_free_and_unlink(nvfd_t *nvf, nvp_list_t *np) +void +nfd_nvp_free_and_unlink(nvfd_t *nvf, nvp_list_t *np) { nvp_list_t *pv, *next; pv = np->nvp_prev; next = np->nvp_next; - nvp_free(np); + (nvf->nvf_nvp_free)(np); /* remove element at head */ if (pv == NULL) { @@ -602,12 +659,10 @@ nfd_devid_free_and_unlink(nvfd_t *nvf, nvp_list_t *np) pv->nvp_next = next; next->nvp_prev = pv; } - - return (next); } -static void -nfd_devid_link(nvfd_t *nvf, nvp_list_t *np) +void +nfd_nvp_link(nvfd_t *nvf, nvp_list_t *np) { if (nvf->nvf_list == NULL) { nvf->nvf_list = np; @@ -622,16 +677,17 @@ nfd_devid_link(nvfd_t *nvf, nvp_list_t *np) /* * Convert a device path/nvlist pair to an nvp_list_t * Used to parse the nvlist format when reading + * /etc/devices/devid_cache */ static nvp_list_t * -nvlist_to_nvp(nvlist_t *nvl, char *name) +devid_nvl2nvp(nvlist_t *nvl, char *name) { - nvp_list_t *np; + nvp_devid_t *np; ddi_devid_t devidp; int rval; uint_t n; - np = kmem_zalloc(sizeof (nvp_list_t), KM_SLEEP); + np = kmem_zalloc(sizeof (nvp_devid_t), KM_SLEEP); np->nvp_devpath = i_ddi_strdup(name, KM_SLEEP); NVP_DEVID_DEBUG_PATH((np->nvp_devpath)); @@ -654,18 +710,70 @@ nvlist_to_nvp(nvlist_t *nvl, char *name) } } - return (np); + return (NVPLIST(np)); } /* + * Convert a device path/nvlist pair to an nvp_list_t + * Used to parse the nvlist format when reading + * /etc/devices/devname_cache + */ +static nvp_list_t * +sdev_nvl2nvp(nvlist_t *nvl, char *name) +{ + nvp_devname_t *np; + char **strs; + int *cnts; + uint_t nstrs, ncnts; + int rval, i; + + /* name of the sublist must match what we created */ + if (strcmp(name, DP_DEVNAME_ID) != 0) { + return (NULL); + } + + np = kmem_zalloc(sizeof (nvp_devname_t), KM_SLEEP); + + rval = nvlist_lookup_string_array(nvl, + DP_DEVNAME_NCACHE_ID, &strs, &nstrs); + if (rval) { + kmem_free(np, sizeof (nvp_devname_t)); + return (NULL); + } + + np->nvp_npaths = nstrs; + np->nvp_paths = kmem_zalloc(nstrs * sizeof (char *), KM_SLEEP); + for (i = 0; i < nstrs; i++) { + np->nvp_paths[i] = i_ddi_strdup(strs[i], KM_SLEEP); + } + np->nvp_expirecnts = kmem_zalloc(nstrs * sizeof (int), KM_SLEEP); + for (i = 0; i < nstrs; i++) { + np->nvp_expirecnts[i] = 4; /* XXX sdev_nc_expirecnt */ + } + + rval = nvlist_lookup_int32_array(nvl, + DP_DEVNAME_NC_EXPIRECNT_ID, &cnts, &ncnts); + if (rval == 0) { + ASSERT(ncnts == nstrs); + ncnts = max(ncnts, nstrs); + for (i = 0; i < nstrs; i++) { + np->nvp_expirecnts[i] = cnts[i]; + } + } + + return (NVPLIST(np)); +} + + +/* * Convert a list of nvp_list_t's to a single nvlist - * Used when writing the nvlist file + * Used when writing the nvlist file. */ static int -nvp_to_nvlist(nvfd_t *nvfd, nvlist_t **ret_nvl) +devid_nvp2nvl(nvfd_t *nvfd, nvlist_t **ret_nvl) { nvlist_t *nvl, *sub_nvl; - nvp_list_t *np; + nvp_devid_t *np; int rval; ASSERT(modrootloaded); @@ -677,7 +785,7 @@ nvp_to_nvlist(nvfd_t *nvfd, nvlist_t **ret_nvl) return (DDI_FAILURE); } - for (np = nvfd->nvf_list; np; np = np->nvp_next) { + for (np = NVF_DEVID_LIST(nvfd); np; np = NVP_DEVID_NEXT(np)) { if (np->nvp_devid == NULL) continue; NVP_DEVID_DEBUG_PATH(np->nvp_devpath); @@ -689,18 +797,16 @@ nvp_to_nvlist(nvfd_t *nvfd, nvlist_t **ret_nvl) goto err; } - if (np->nvp_devid) { - rval = nvlist_add_byte_array(sub_nvl, DP_DEVID_ID, - (uchar_t *)np->nvp_devid, - ddi_devid_sizeof(np->nvp_devid)); - if (rval == 0) { - NVP_DEVID_DEBUG_DEVID(np->nvp_devid); - } else { - KFIOERR((CE_CONT, - "%s: nvlist add error %d (devid)\n", - nvfd->nvf_name, rval)); - goto err; - } + rval = nvlist_add_byte_array(sub_nvl, DP_DEVID_ID, + (uchar_t *)np->nvp_devid, + ddi_devid_sizeof(np->nvp_devid)); + if (rval == 0) { + NVP_DEVID_DEBUG_DEVID(np->nvp_devid); + } else { + KFIOERR((CE_CONT, + "%s: nvlist add error %d (devid)\n", + nvfd->nvf_name, rval)); + goto err; } rval = nvlist_add_nvlist(nvl, np->nvp_devpath, sub_nvl); @@ -723,6 +829,76 @@ err: return (DDI_FAILURE); } +/* + * Convert a list of nvp_list_t's to a single nvlist + * Used when writing the nvlist file. + */ +static int +sdev_nvp2nvl(nvfd_t *nvfd, nvlist_t **ret_nvl) +{ + nvlist_t *nvl, *sub_nvl; + nvp_devname_t *np; + int rval; + + ASSERT(modrootloaded); + + rval = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP); + if (rval != 0) { + KFIOERR((CE_CONT, "%s: nvlist alloc error %d\n", + nvfd->nvf_name, rval)); + return (DDI_FAILURE); + } + + if ((np = NVF_DEVNAME_LIST(nvfd)) != NULL) { + ASSERT(NVP_DEVNAME_NEXT(np) == NULL); + + rval = nvlist_alloc(&sub_nvl, NV_UNIQUE_NAME, KM_SLEEP); + if (rval != 0) { + KFIOERR((CE_CONT, "%s: nvlist alloc error %d\n", + nvfd->nvf_name, rval)); + sub_nvl = NULL; + goto err; + } + + rval = nvlist_add_string_array(sub_nvl, + DP_DEVNAME_NCACHE_ID, np->nvp_paths, np->nvp_npaths); + if (rval != 0) { + KFIOERR((CE_CONT, + "%s: nvlist add error %d (sdev)\n", + nvfd->nvf_name, rval)); + goto err; + } + + rval = nvlist_add_int32_array(sub_nvl, + DP_DEVNAME_NC_EXPIRECNT_ID, + np->nvp_expirecnts, np->nvp_npaths); + if (rval != 0) { + KFIOERR((CE_CONT, + "%s: nvlist add error %d (sdev)\n", + nvfd->nvf_name, rval)); + goto err; + } + + rval = nvlist_add_nvlist(nvl, DP_DEVNAME_ID, sub_nvl); + if (rval != 0) { + KFIOERR((CE_CONT, "%s: nvlist add error %d (sublist)\n", + nvfd->nvf_name, rval)); + goto err; + } + nvlist_free(sub_nvl); + } + + *ret_nvl = nvl; + return (DDI_SUCCESS); + +err: + if (sub_nvl) + nvlist_free(sub_nvl); + nvlist_free(nvl); + *ret_nvl = NULL; + return (DDI_FAILURE); +} + /* * Read a file in the nvlist format @@ -769,17 +945,18 @@ fread_nvp_list(nvfd_t *nvfd) * convert nvlist for this device to * an nvp_list_t struct */ - np = nvlist_to_nvp(sublist, name); - np->nvp_next = NULL; - np->nvp_prev = nvp_tail; + np = (nvfd->nvf_nvl2nvp)(sublist, name); + if (np) { + np->nvp_next = NULL; + np->nvp_prev = nvp_tail; - if (nvp_list == NULL) { - nvp_list = np; - } else { - nvp_tail->nvp_next = np; + if (nvp_list == NULL) { + nvp_list = np; + } else { + nvp_tail->nvp_next = np; + } + nvp_tail = np; } - nvp_tail = np; - break; default: @@ -800,7 +977,7 @@ fread_nvp_list(nvfd_t *nvfd) error: nvlist_free(nvl); if (nvp_list) - nvp_list_free(nvp_list); + nvp_list_free(nvfd, nvp_list); return (rval); } @@ -810,7 +987,7 @@ i_ddi_read_one_nvfile(nvfd_t *nvfd) { int rval; - KFDEBUG((CE_CONT, "Reading %s\n", nvfd->nvf_name)); + KFDEBUG((CE_CONT, "reading %s\n", nvfd->nvf_name)); rval = fread_nvp_list(nvfd); if (rval) { @@ -836,39 +1013,26 @@ i_ddi_read_one_nvfile(nvfd_t *nvfd) return (rval); } +/* for information possibly required to mount root */ void i_ddi_read_devices_files(void) { - nvfd_t nvfd; - int rval; - mdi_read_devices_files(); - if (devid_cache_read_disable) - return; - - nvfd.nvf_name = dcfd->nvf_name; - nvfd.nvf_flags = 0; - nvfd.nvf_list = NULL; - nvfd.nvf_tail = NULL; - rw_init(&nvfd.nvf_lock, NULL, RW_DRIVER, NULL); - - rval = i_ddi_read_one_nvfile(&nvfd); - - rw_enter(&dcfd->nvf_lock, RW_WRITER); - - if (rval == 0) { - if (dcfd->nvf_list != NULL) { - nvp_list_free(dcfd->nvf_list); - } - dcfd->nvf_list = nvfd.nvf_list; - dcfd->nvf_tail = nvfd.nvf_tail; + if (devid_cache_read_disable == 0) { + ASSERT(dcfd->nvf_list == NULL); + (void) i_ddi_read_one_nvfile(dcfd); } - dcfd->nvf_flags = nvfd.nvf_flags; - - rw_exit(&dcfd->nvf_lock); +} - rw_destroy(&nvfd.nvf_lock); +/* may be done after root is mounted */ +void +i_ddi_read_devname_file(void) +{ + if (sdev_cache_read_disable == 0) { + ASSERT(sdevfd->nvf_list == NULL); + (void) i_ddi_read_one_nvfile(sdevfd); + } } static int @@ -1003,8 +1167,8 @@ e_ddi_devid_discovery(ddi_devid_t devid) int e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) { - nvp_list_t *np; - nvp_list_t *new_nvp; + nvp_devid_t *np; + nvp_devid_t *new_nvp; ddi_devid_t new_devid; int new_devid_size; char *path, *fullpath; @@ -1022,14 +1186,14 @@ e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) DEVID_LOG_REG(("register", devid, path)); - new_nvp = kmem_zalloc(sizeof (nvp_list_t), KM_SLEEP); + new_nvp = kmem_zalloc(sizeof (nvp_devid_t), KM_SLEEP); new_devid_size = ddi_devid_sizeof(devid); new_devid = kmem_alloc(new_devid_size, KM_SLEEP); (void) bcopy(devid, new_devid, new_devid_size); rw_enter(&dcfd->nvf_lock, RW_WRITER); - for (np = dcfd->nvf_list; np != NULL; np = np->nvp_next) { + for (np = NVF_DEVID_LIST(dcfd); np; np = NVP_DEVID_NEXT(np)) { if (strcmp(path, np->nvp_devpath) == 0) { DEVID_DEBUG2((CE_CONT, "register: %s path match\n", path)); @@ -1041,7 +1205,7 @@ e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) np->nvp_dip = dip; NVF_MARK_DIRTY(dcfd); rw_exit(&dcfd->nvf_lock); - kmem_free(new_nvp, sizeof (nvp_list_t)); + kmem_free(new_nvp, sizeof (nvp_devid_t)); kmem_free(path, pathlen); goto exit; } @@ -1063,8 +1227,7 @@ e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) * may map to multiple paths but one path * should only map to one devid. */ - (void) nfd_devid_free_and_unlink( - dcfd, np); + nfd_nvp_free_and_unlink(dcfd, NVPLIST(np)); np = NULL; break; } else { @@ -1074,7 +1237,7 @@ e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) NVP_DEVID_DIP | NVP_DEVID_REGISTERED; np->nvp_dip = dip; rw_exit(&dcfd->nvf_lock); - kmem_free(new_nvp, sizeof (nvp_list_t)); + kmem_free(new_nvp, sizeof (nvp_devid_t)); kmem_free(path, pathlen); kmem_free(new_devid, new_devid_size); return (DDI_SUCCESS); @@ -1093,7 +1256,7 @@ e_devid_cache_register(dev_info_t *dip, ddi_devid_t devid) new_nvp->nvp_devid = new_devid; NVF_MARK_DIRTY(dcfd); - nfd_devid_link(dcfd, new_nvp); + nfd_nvp_link(dcfd, NVPLIST(new_nvp)); rw_exit(&dcfd->nvf_lock); @@ -1101,7 +1264,8 @@ exit: if (free_devid) kmem_free(free_devid, ddi_devid_sizeof(free_devid)); - wake_nvpflush_daemon(dcfd); + if (!devid_cache_write_disable) + wake_nvpflush_daemon(); return (DDI_SUCCESS); } @@ -1115,11 +1279,11 @@ exit: void e_devid_cache_unregister(dev_info_t *dip) { - nvp_list_t *np; + nvp_devid_t *np; rw_enter(&dcfd->nvf_lock, RW_WRITER); - for (np = dcfd->nvf_list; np != NULL; np = np->nvp_next) { + for (np = NVF_DEVID_LIST(dcfd); np; np = NVP_DEVID_NEXT(np)) { if (np->nvp_devid == NULL) continue; if ((np->nvp_flags & NVP_DEVID_DIP) && np->nvp_dip == dip) { @@ -1138,26 +1302,26 @@ e_devid_cache_unregister(dev_info_t *dip) void e_devid_cache_cleanup(void) { - nvp_list_t *np, *next; + nvp_devid_t *np, *next; rw_enter(&dcfd->nvf_lock, RW_WRITER); - for (np = dcfd->nvf_list; np != NULL; np = next) { - next = np->nvp_next; + for (np = NVF_DEVID_LIST(dcfd); np; np = next) { + next = NVP_DEVID_NEXT(np); if (np->nvp_devid == NULL) continue; if ((np->nvp_flags & NVP_DEVID_REGISTERED) == 0) { DEVID_LOG_REMOVE((CE_CONT, "cleanup: %s\n", np->nvp_devpath)); NVF_MARK_DIRTY(dcfd); - next = nfd_devid_free_and_unlink(dcfd, np); + nfd_nvp_free_and_unlink(dcfd, NVPLIST(np)); } } rw_exit(&dcfd->nvf_lock); if (NVF_IS_DIRTY(dcfd)) - wake_nvpflush_daemon(dcfd); + wake_nvpflush_daemon(); } @@ -1229,7 +1393,7 @@ static int e_devid_cache_devi_path_lists(ddi_devid_t devid, int retmax, int *retndevis, dev_info_t **retdevis, int *retnpaths, char **retpaths) { - nvp_list_t *np; + nvp_devid_t *np; int ndevis, npaths; dev_info_t *dip, *pdip; int circ; @@ -1238,7 +1402,7 @@ e_devid_cache_devi_path_lists(ddi_devid_t devid, int retmax, ndevis = 0; npaths = 0; - for (np = dcfd->nvf_list; np != NULL; np = np->nvp_next) { + for (np = NVF_DEVID_LIST(dcfd); np; np = NVP_DEVID_NEXT(np)) { if (np->nvp_devid == NULL) continue; if (ddi_devid_valid(np->nvp_devid) != DDI_SUCCESS) { @@ -1514,6 +1678,25 @@ static clock_t nvpticks; static void nvpflush_daemon(void); +void +nvf_register_write_complete(nvfd_t *fd, void (*f)(nvfd_t *)) +{ + fd->nvf_write_complete = f; +} + +void +nvf_unregister_write_complete(nvfd_t *fd) +{ + fd->nvf_write_complete = NULL; +} + +static void +nvf_write_complete(nvfd_t *fd) +{ + if (fd->nvf_write_complete) { + (*(fd->nvf_write_complete))(fd); + } +} void i_ddi_start_flush_daemon(void) @@ -1523,8 +1706,9 @@ i_ddi_start_flush_daemon(void) mutex_init(&nvpflush_lock, NULL, MUTEX_DRIVER, NULL); cv_init(&nvpflush_cv, NULL, CV_DRIVER, NULL); - if (NVF_IS_DIRTY(dcfd)) { - wake_nvpflush_daemon(dcfd); + if ((NVF_IS_DIRTY(dcfd) && !devid_cache_write_disable) || + (NVF_IS_DIRTY(sdevfd) && !sdevfd && sdev_cache_write_disable)) { + wake_nvpflush_daemon(); } } @@ -1542,6 +1726,7 @@ nvpflush_timeout(void *arg) nvpflush_id = timeout(nvpflush_timeout, NULL, nticks); } else { do_nvpflush = 1; + NVPDAEMON_DEBUG((CE_CONT, "signal nvpdaemon\n")); cv_signal(&nvpflush_cv); nvpflush_id = 0; nvpflush_timer_busy = 0; @@ -1549,17 +1734,16 @@ nvpflush_timeout(void *arg) } } -static void -wake_nvpflush_daemon(nvfd_t *nvfp) +void +wake_nvpflush_daemon() { clock_t nticks; /* - * If root is readonly or the system isn't up yet + * If the system isn't up yet * don't even think about starting a flush. */ - if (devid_cache_write_disable || - !i_ddi_io_initialized() || NVF_IS_READONLY(nvfp)) + if (!i_ddi_io_initialized()) return; mutex_enter(&nvpflush_lock); @@ -1603,7 +1787,7 @@ nvpflush_one(nvfd_t *nvfd) rw_exit(&nvfd->nvf_lock); return (DDI_FAILURE); } - if (nvp_to_nvlist(nvfd, &nvl) != DDI_SUCCESS) { + if (((nvfd->nvf_nvp2nvl)(nvfd, &nvl)) != DDI_SUCCESS) { KFIOERR((CE_CONT, "nvpflush: " "%s nvlist construction failed\n", nvfd->nvf_name)); rw_exit(&nvfd->nvf_lock); @@ -1654,12 +1838,14 @@ nvpflush_one(nvfd_t *nvfd) return (rval); } + static void nvpflush_daemon(void) { callb_cpr_t cprinfo; clock_t clk; int rval; + int i; ASSERT(modrootloaded); @@ -1701,21 +1887,40 @@ nvpflush_daemon(void) * Try flushing what's dirty, reschedule if there's * a failure or data gets marked as dirty again. */ - NVPDAEMON_DEBUG((CE_CONT, "nvpdaemon: flush\n")); - rval = nvpflush_one(dcfd); + for (i = 0; i < NCACHEFDS; i++) { + rw_enter(&cachefds[i]->nvf_lock, RW_READER); + if (NVF_IS_DIRTY(cachefds[i])) { + NVPDAEMON_DEBUG((CE_CONT, + "nvpdaemon: flush %s\n", + cachefds[i]->nvf_name)); + rw_exit(&cachefds[i]->nvf_lock); + rval = nvpflush_one(cachefds[i]); + rw_enter(&cachefds[i]->nvf_lock, RW_READER); + if (rval != DDI_SUCCESS || + NVF_IS_DIRTY(cachefds[i])) { + rw_exit(&cachefds[i]->nvf_lock); + NVPDAEMON_DEBUG((CE_CONT, + "nvpdaemon: %s dirty again\n", + cachefds[i]->nvf_name)); + wake_nvpflush_daemon(); + } else { + rw_exit(&cachefds[i]->nvf_lock); + nvf_write_complete(cachefds[i]); + } + } else { + NVPDAEMON_DEBUG((CE_CONT, + "nvpdaemon: not dirty %s\n", + cachefds[i]->nvf_name)); + rw_exit(&cachefds[i]->nvf_lock); + } + } - rw_enter(&dcfd->nvf_lock, RW_READER); - if (rval != DDI_SUCCESS || NVF_IS_DIRTY(dcfd)) { - rw_exit(&dcfd->nvf_lock); - NVPDAEMON_DEBUG((CE_CONT, "nvpdaemon: dirty again\n")); - wake_nvpflush_daemon(dcfd); - } else - rw_exit(&dcfd->nvf_lock); mutex_enter(&nvpflush_lock); nvpbusy = 0; } } + void i_ddi_clean_devices_files(void) { |