fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
d3e3772eab14af9b62d61b6d55b6d20457c3075byi zhang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file names
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file header definitions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file flag definitions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * These flags describe the current state of reading or writing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the NVFILE/NVPAIR or the backing file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * These flags are derived from a like NVPAIR/NVFILE implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_ACTIVE 0x01 /* nvlist/nvpair file is active */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_SCHED 0x04 /* flush thread is currently scheduled */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_FLUSHING 0x08 /* in process of being flushed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_ERROR 0x10 /* most recent flush failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_MARK_ACTIVE(flag) (flag |= NVF_ACTIVE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_CLEAR_ACTIVE(flag) (flag &= ~NVF_ACTIVE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_CLEAR_DIRTY(flag) (flag &= ~NVF_DIRTY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_CLEAR_SCHED(flag) (flag &= ~NVF_SCHED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file flush time constants
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_FLUSH_DELAY 10 /* number of ticks before flush */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_RESCHED_MIN_TICKS 5 /* min # of ticks to resched thread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NVF_FLUSH_BACKOFF_DELAY (SEC_TO_TICK(300)) /* re-try flush in 5 min */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file access operations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int nvf_open(char *path, int flags, int mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int nvf_rename(char *oldname, char *newname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic ssize_t nvf_read(int fdes, void *cbuf, ssize_t count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic ssize_t nvf_write(int fdes, void *cbuf, ssize_t count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file header data structure definition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This data structure definition was derived from a like data structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (nvpf_hdr_t) in usr/src/uts/common/sys/devctl_impl.h
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This header is larger than need in order to support extensability in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Local Global Variables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nvlist_t *nvf_list; /* pointer to root nvlist */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t nvf_flags; /* nvfile state flags */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic krwlock_t nvf_list_lock; /* lock for nvlist access */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic timeout_id_t nvf_thread_id; /* thread identifier */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic clock_t nvf_thread_ticks; /* timeout tick value */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char nvf_curr_filename[NVF_MAX_FILENAME_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char nvf_prev_filename[NVF_MAX_FILENAME_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic boolean_t nvf_written_once; /* File has been written once */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Local Function Prototypes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint16_t nvf_chksum(char *buf, int64_t buflen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NVLIST/NVPAIR FILE External Interfaces
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&nvf_getf_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(nvf_curr_filename, NVF_MAX_FILENAME_LEN, "%s_v%d.%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NVF_FILENAME, NVF_HDR_VERSION, NVF_CURR_FILE_SUFFIX);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(nvf_prev_filename, NVF_MAX_FILENAME_LEN, "%s_v%d.%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NVF_FILENAME, NVF_HDR_VERSION, NVF_PREV_FILE_SUFFIX);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_load - load contents of NVLIST/NVPAIR file into memory.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * try to load current file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Rename current file to add corrupted suffix
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(corrupt_filename, NVF_MAX_FILENAME_LEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nvf_rename(nvf_curr_filename, corrupt_filename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * try to load previous file
d3e3772eab14af9b62d61b6d55b6d20457c3075byi zhang - Sun Microsystems - Beijing China rval = nvf_parse(nvf_prev_filename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Rename previous file to add corrupted suffix
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(corrupt_filename, NVF_MAX_FILENAME_LEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nvf_rename(nvf_prev_filename, corrupt_filename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * non-existent or corrupted files are OK. We just create
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an empty root nvlist and then write to file when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * something added. However, ensure that any current root nvlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is deallocated before allocating a new one.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_alloc(&nvf_list, NV_UNIQUE_NAME, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_update - start process of updating the NVPAIR/NVLIST file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is derived from a like NVPAIR/NVFILE implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set dirty flag to indicate data flush is needed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If thread is already started just update number of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ticks before flush, otherwise start thread and set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * number of ticks. The thread will is responsible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for starting the actual store to file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If update error occured previously, reschedule flush to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * occur almost immediately. If error still exists, the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update thread will be backed off again
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvf_thread_id = timeout(nvf_thread, NULL, NVF_FLUSH_DELAY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvf_thread_ticks = ddi_get_lbolt() + NVF_FLUSH_DELAY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If update error occured previously, reschedule flush
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attempt to occur quickly. If an error still exists
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * after a flush attempt, the update thread will be backed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_data_check -- check if specified list exists
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_nvlist(nvf_list, id, &list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_value_set - store value associated with node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update value. If value already exists, it will be replaced
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by this update.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value was set, so update associated file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_value_get - obtain value associated with node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_uint32(nvf_list, id, value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_name_set - store a specific type of name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_name_get - return a specific type of name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_node_name_get(char *id, char *name, uint_t nsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_string(nvf_list, id, &tmpname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensure name is able to fit into given buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unable to fit %s node name into buffer %d %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_data_set -- store data element associated with node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_node_data_set(char *name, void *data, uint_t dsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the address configuration element in the specific
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list. If this element already exists, it will be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * replaced by this update.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_add_byte_array(nvf_list, name, (uchar_t *)data, dsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data was set, so update associated file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_data_get -- obtain a data element associated with node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_node_data_get(char *name, void *data, uint_t dsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_nvfile_status_t status = ISCSI_NVFILE_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_byte_array(nvf_list, name, &value, &vsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensure data is able to fit into given buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_node_data_clear -- remove a data element associated with node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove the specified data element
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_remove(nvf_list, name, DATA_TYPE_BYTE_ARRAY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data was set, so update associated file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_data_set -- store a data element in the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_data_set(char *id, char *name, void *data, uint_t dsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_nvlist(nvf_list, id, &list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_alloc(&list, NV_UNIQUE_NAME, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the data element in the specified list. If this element
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * already exists, it will be replaced by this update.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_add_byte_array(list, name, (uchar_t *)data, dsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data was set, so update file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_data_get -- get a data element from the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_data_get(char *id, char *name, void *data, uint_t dsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_nvlist(nvf_list, id, &list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* obtain data element from list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_byte_array(list, name, &value, &vsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensure data is able to fit into given buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_data_next -- get the next data element in the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_data_next(char *id, void **v, char *name, void *data, uint_t dsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_nvlist(nvf_list, id, &list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get the next nvpair data item in the list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *v = (void *)pair;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get the data bytes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvpair_value_byte_array(pair, &value, &vsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensure data is able to fit into given buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_data_clear -- remove a data element from the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * find the specified list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_lookup_nvlist(nvf_list, id, &list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove the specified data element
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_remove(list, name, DATA_TYPE_BYTE_ARRAY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data was set, so update associated file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | Internal Helper Functions |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_cksum - calculate checksum of given buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function was derived from like function (nvp_cksum) in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (n-- > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_thread - determines when writing of NVLIST/NVPAIR data to a file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should occur.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check whether its time to write to file. If not, reschedule self
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng if ((nticks > NVF_RESCHED_MIN_TICKS) || !modrootloaded) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvf_thread_id = timeout(nvf_thread, NULL, nticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush NVLIST/NVPAIR data to file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!iscsi persistent store update "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvf_thread_ticks = NVF_FLUSH_BACKOFF_DELAY + ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store update ok now "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * re-check whether data is dirty and reschedule if necessary
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (NVF_IS_ACTIVE(nvf_flags) && NVF_IS_DIRTY(nvf_flags)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvf_thread_id = timeout(nvf_thread, NULL, nticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_flush - write contents of NVLIST/NVPAIR to a backing file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is derived from a like NVPAIR/NVFILE implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * duplicate data so access isn't blocked while writing to disk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pack duplicated list to get ready for file write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_pack(tmpnvl, &nvlbuf, &nvllen, NV_ENCODE_NATIVE, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to pack "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate buffer to store both the header and the data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fill buffer with contents of file header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nvf_hdr_t *)nvfbuf)->nvfh_magic = NVF_HDR_MAGIC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nvf_hdr_t *)nvfbuf)->nvfh_ver = NVF_HDR_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nvf_hdr_t *)nvfbuf)->nvfh_datasum = nvf_chksum((char *)nvlbuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((nvf_hdr_t *)nvfbuf)->nvfh_hdrsum = nvf_chksum((char *)nvfbuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy packed nvlist into buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(nvlbuf, nvfbuf + sizeof (nvf_hdr_t), nvllen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free memory used for packed nvlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To make it unlikely we suffer data loss, write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data to the new temporary file. Once successful
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * complete the transaction by renaming the new file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to replace the previous.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove temporary file to ensure data content is written correctly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create tempororary file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte file = nvf_open(NVF_TMP_FILENAME, O_RDWR | O_CREAT, 0600);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "!iscsi persistent store failed to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * write data to tempororary file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to write "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to write "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s (errno:%d)\n\tpartial write %d of %ld bytes\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NVF_TMP_FILENAME, nvf_errno, bytes_written, nvflen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * close tempororary file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * File has been written. Set flag to allow the create and update
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * messages to be displayed in case of create or update failures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rename current original file to previous original file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvf_rename(nvf_curr_filename, nvf_prev_filename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rename %s (errno:%d)", nvf_curr_filename, nvf_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rename temporary file to current original file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvf_rename(NVF_TMP_FILENAME, nvf_curr_filename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rename %s (errno:%d)", NVF_TMP_FILENAME, nvf_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_parse - read contents of NVLIST/NVPAIR file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is derived from a like NVPAIR/NVFILE implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * open current file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * read file header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bytes_read = nvf_read(file, (char *)&hdr, sizeof (hdr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * calculate checksum over file header bytes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * validate file header is as expected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "checksum error %s actual:0x%x expected:0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store %s has an "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * read expected remaining content of file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store incomplete "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check whether file has anymore data. If so this is an error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store file is larger "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "than expected %s bytes:%lld",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * validate file data is as expected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store checksum error %s "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = nvlist_unpack(buf, hdr.nvfh_size, &nvl, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!iscsi persistent store failed unpacking "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * activate nvlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free up old nvlist
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsid_getf -- given a file descriptor returns a file pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_releasef -- release lock on file pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_setf -- stores the file pointer in an empty slot returning index
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < NVF_GETF; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvf_fd[i] == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_freef -- gets the file pointer based on index and releases memory.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_open -- acts like syscall open, but works for kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: This works for regular files only. No umask is provided to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * vn_open which means whatever mode is passed in will be used to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create a file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to convert from user mode flags to file system flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It's unfortunate that the kernel doesn't define a mask for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the read/write bits which would make this conversion easier.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only O_RDONLY/O_WRONLY/O_RDWR are different than their FXXXXX
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * counterparts. If one was provided something like
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fflags = ((flags & mask) + 1) | (flags & ~mask)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * would work. But, that would only be true if the relationship
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be O_XXX and FXXX was defined and it's not. So we have the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * following.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now that fflags has been initialized with the read/write bits
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * look at the other flags and OR them in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvf_errno = vn_open(path, UIO_SYSSPACE, fflags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ---- falloc returns with f_tlock held on success ---- */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_close -- closes down the file by releasing locks and memory.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) VOP_CLOSE(vp, fp->f_flag, 1, 0, kcred, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unfalloc which is called from here will do a mutex_exit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on t_lock in the fp. So don't call nvf_releasef() here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_remove -- remove file from filesystem
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (vn_remove(filename, UIO_SYSSPACE, RMFILE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_rename -- rename file from one name to another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (vn_rename(oldname, newname, UIO_SYSSPACE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_rw -- common read/write code. Very simplistic.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenvf_rw(int fdes, void *cbuf, ssize_t count, enum uio_rw rw)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvf_errno = vn_rdwr(rw, vp, (caddr_t)cbuf, count, fp->f_offset,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_write -- kernel write function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nvf_read -- kernel read function