/* * 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); }
/* * 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); }
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() */
/* * 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(); }