Exemple #1
0
/*
 * Called when the module is first loaded, this routine loads the configuration
 * file into the SPA namespace.  It does not actually open or load the pools; it
 * only populates the namespace.
 */
void
spa_config_load(void)
{
	void *buf = NULL;
	nvlist_t *nvlist, *child;
	nvpair_t *nvpair;
	char *pathname;
	struct _buf *file;
	uint64_t fsize;

	/*
	 * Open the configuration file.
	 */
	pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP);

	(void) snprintf(pathname, MAXPATHLEN, "%s", spa_config_path);

	file = kobj_open_file(pathname);

	kmem_free(pathname, MAXPATHLEN);

	if (file == (struct _buf *)-1)
		return;

	if (kobj_get_filesize(file, &fsize) != 0)
		goto out;

	buf = kmem_alloc(fsize, KM_SLEEP);

	/*
	 * Read the nvlist from the file.
	 */
	if (kobj_read_file(file, buf, fsize, 0) < 0)
		goto out;

	/*
	 * Unpack the nvlist.
	 */
	if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0)
		goto out;

	/*
	 * Iterate over all elements in the nvlist, creating a new spa_t for
	 * each one with the specified configuration.
	 */
	mutex_enter(&spa_namespace_lock);
	nvpair = NULL;
	while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) {
		if (nvpair_type(nvpair) != DATA_TYPE_NVLIST)
			continue;

		VERIFY(nvpair_value_nvlist(nvpair, &child) == 0);

		if (spa_lookup(nvpair_name(nvpair)) != NULL)
			continue;
		(void) spa_add(nvpair_name(nvpair), child, NULL);
	}
	mutex_exit(&spa_namespace_lock);

	nvlist_free(nvlist);

out:
	if (buf != NULL)
		kmem_free(buf, fsize);

	kobj_close_file(file);
}
Exemple #2
0
/*
 * Called when the module is first loaded, this routine loads the configuration
 * file into the SPA namespace.  It does not actually open or load the pools; it
 * only populates the namespace.
 */
void
spa_config_load(void)
{
    void *buf = NULL;
    nvlist_t *nvlist, *child;
    nvpair_t *nvpair;
    spa_t *spa;
    char pathname[128];
    struct _buf *file;
    uint64_t fsize;

    /*
     * Open the configuration file.
     */
#ifdef __native_client__
    (void) snprintf(pathname, sizeof (pathname), "%s", spa_config_path);
#else
    (void) snprintf(pathname, sizeof (pathname), "%s%s",
                    (rootdir != NULL) ? "./" : "", spa_config_path);
#endif //__native_client__

    file = kobj_open_file(pathname);
    if (file == (struct _buf *)-1)
        return;

    if (kobj_get_filesize(file, &fsize) != 0)
        goto out;

    buf = kmem_alloc(fsize, KM_SLEEP);

    /*
     * Read the nvlist from the file.
     */
    if (kobj_read_file(file, buf, fsize, 0) < 0)
        goto out;

    /*
     * Unpack the nvlist.
     */
    if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0)
        goto out;

    /*
     * Iterate over all elements in the nvlist, creating a new spa_t for
     * each one with the specified configuration.
     */
    mutex_enter(&spa_namespace_lock);
    nvpair = NULL;
    while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) {

        if (nvpair_type(nvpair) != DATA_TYPE_NVLIST)
            continue;

        VERIFY(nvpair_value_nvlist(nvpair, &child) == 0);

        if (spa_lookup(nvpair_name(nvpair)) != NULL)
            continue;
        spa = spa_add(nvpair_name(nvpair), NULL);

        /*
         * We blindly duplicate the configuration here.  If it's
         * invalid, we will catch it when the pool is first opened.
         */
        VERIFY(nvlist_dup(child, &spa->spa_config, 0) == 0);
    }
    mutex_exit(&spa_namespace_lock);

    nvlist_free(nvlist);

out:
    if (buf != NULL)
        kmem_free(buf, fsize);

    kobj_close_file(file);
}
Exemple #3
0
static int
splat_kobj_test2(struct file *file, void *arg)
{
	struct _buf *f;
	char *buf;
	uint64_t size;
	int rc;

	f = kobj_open_file(SPLAT_KOBJ_TEST_FILE);
	if (f == (struct _buf *)-1) {
		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed to open "
			     "test file: %s\n", SPLAT_KOBJ_TEST_FILE);
		return -ENOENT;
	}

	rc = kobj_get_filesize(f, &size);
	if (rc) {
		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed stat of "
			     "test file: %s (%d)\n", SPLAT_KOBJ_TEST_FILE, rc);
		goto out;
	}

	buf = kmalloc(size + 1, GFP_KERNEL);
	if (!buf) {
		rc = -ENOMEM;
		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed to alloc "
			     "%lld bytes for tmp buffer (%d)\n",
			     (long long)size, rc);
		goto out;
	}

	memset(buf, 0, size + 1);
	rc = kobj_read_file(f, buf, size, 0);
	if (rc < 0) {
		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Failed read of "
			     "test file: %s (%d)\n", SPLAT_KOBJ_TEST_FILE, rc);
		goto out2;
	}

	/* Validate we read as many bytes as expected based on the stat.  This
	 * isn't a perfect test since we didn't create the file however it is
	 * pretty unlikely there are garbage characters in your /etc/fstab */
	if (size != (uint64_t)strlen(buf)) {
		rc = -EFBIG;
		splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Stat'ed size "
			     "(%lld) does not match number of bytes read "
			     "(%lld)\n", (long long)size,
			     (long long)strlen(buf));
		goto out2;
	}

	rc = 0;
	splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "\n%s\n", buf);
	splat_vprint(file, SPLAT_KOBJ_TEST2_NAME, "Successfully stat'ed "
		     "and read expected number of bytes (%lld) from test "
		     "file: %s\n", (long long)size, SPLAT_KOBJ_TEST_FILE);
out2:
	kfree(buf);
out:
	kobj_close_file(f);

        return rc;
} /* splat_kobj_test2() */
Exemple #4
0
/*
 * open / read / parse / close devicedb/master file
 */
void
process_master_file() {
	FILE_T *file;
	char tokbuf[MASTER_LINE_MAX];
	int token;
	int done = 0;
	int line_begin;
	int x = 0;
	int total_line_processed = 0;

	set_master_ops_debug_flags();

	incore_master_head = incore_master_tail = NULL;
	if ((file = kobj_open_file(masterfile)) == (struct _buf *)-1) {
		cmn_err(CE_WARN, "!cannot open master file: %s", masterfile);
		return;
	}
	one_master_line = (char *)kmem_zalloc(MASTER_LINE_MAX, KM_SLEEP);
	master_skip(file); /* skip the first line which is "version" */
	mf_column = 0;
	while (!done) {
		if (mf_column == 0) {
			x = master_get_a_line(file);
			total_line_processed++;
			if (x == EOF) { /* end of file */
				done = 1;
				continue;
			}
			if (x == 0) { /* blank line */
				continue;
			}
		}
		token = master_lex(tokbuf);
		switch (token) {
		case POUND: /* ignore comment line */
			if (master_ops_debug & MASTER_OPS_DEBUG_PROCESS) {
				printf("master_ops: # found skip this line\n");
			}
			mf_column = 0;
			break;
		case NAME: /* found actual string, parse and keep it */
			if (mf_column == 0) {
				if (incore_master_tail == NULL) {
					/* very 1st line */
					incore_master_head =
					incore_master_tail = (struct
					    master_line *) kmem_zalloc(
					    sizeof (struct master_line),
					    KM_SLEEP);
					incore_master_head->text = (char *)
					    kmem_zalloc(one_master_line_max,
					    KM_SLEEP);
					incore_master_head->line_size =
					    one_master_line_max;
				} else {
					incore_master_tail->next = (struct
					    master_line *)kmem_zalloc(
					    sizeof (struct master_line),
					    KM_SLEEP);
					incore_master_tail =
					    incore_master_tail->next;
					incore_master_tail->text = (char *)
					    kmem_zalloc(one_master_line_max,
					    KM_SLEEP);
					incore_master_tail->line_size =
					    one_master_line_max;
				}
				line_begin = 0;
				incore_master_table_line_count++;
			}
			if ((line_begin + strlen(tokbuf) + 1) >
			    MASTER_LINE_MAX) {
				mf_column = 0;
				cmn_err(CE_WARN, "!master file line too long");
				cmn_err(CE_CONT, "line data: \"%s\"",
				    one_master_line);
				master_skip(file); /* skip this line */
				break;
			}
			(void) strcpy(incore_master_tail->text + line_begin,
			    tokbuf);
			incore_master_tail->column[mf_column] = line_begin +
			    incore_master_tail->text;
			if (master_ops_debug & MASTER_OPS_DEBUG_PROCESS) {
				printf("master_ops: line=%d column[%x] found:"\
				    " \"%s\"\n",
				    incore_master_table_line_count, mf_column,
				    incore_master_tail->column[mf_column]);
			}
			line_begin += strlen(tokbuf) + 1;
			mf_column++;
			break;
		case EOF: /* end of file */
			if (master_ops_debug & MASTER_OPS_DEBUG_PROCESS) {
				printf("master_ops: EOF found. We're done.\n");
			}
			done = 1;
			break;
		case EOL: /* end of line */
			if (master_ops_debug & MASTER_OPS_DEBUG_PROCESS) {
				printf("master_ops: EOL found.\n");
			}
			mf_column = 0;
			one_master_line_max = 0;
			dup_devices();
			break;
		default: /* something went wrong */
			cmn_err(CE_WARN, "!master_ops: something went wrong "\
			    "parsing master file: %s", tokbuf);
		}
	}
	kobj_close_file(file);

	if (master_ops_debug & MASTER_OPS_DEBUG_PROCESS) {
		printf("master_ops: incore line count: %d\n",
		    incore_master_table_line_count);
		printf("master_ops: total line processed: %d\n",
		    total_line_processed);
	}
	print_incore_master_table();
}