/* * Populates a fileset with raw files entries. * Returns 0 on success, or an error code from the * call to fileset_populate_subdir if that call fails. */ static int fileset_populate_raw(fileset_t *fileset) { int nfiles = 0; int meandirwidth = *(fileset->fs_dirwidth); int ret; char *raw = "raw:"; char *rawdevs = *fileset->fs_path; char thisdev[1024]; char *next; filesetentry_t *parent; while (rawdevs = strstr (rawdevs, raw)) { /* Locate the first raw: delimeter */ rawdevs += strlen ("raw:"); strcpy (thisdev, rawdevs); if (next = strstr(thisdev, ",")) *next = (char)0; /* Add the raw path to the fileset */ if (ret = fileset_populate_file(fileset, NULL, thisdev, nfiles++)) return(ret); } fileset->fs_realfiles = *(fileset->fs_entries) = nfiles; return(0); }
/* * Creates a directory node in a fileset, by obtaining a * filesetentry entity for the node and initializing it * according to parameters of the fileset. It determines a * directory tree depth and directory width, optionally using * a gamma distribution. If its calculated depth is less then * its actual depth in the directory tree, it becomes a leaf * node and files itself with "width" number of file type * filesetentries, otherwise it files itself with "width" * number of directory type filesetentries, using recursive * calls to fileset_populate_subdir. The end result of the * initial call to this routine is a tree of directories of * random width and varying depth with sufficient leaf * directories to contain all required files. * Returns 0 on success. Returns -1 if ipc path string memory * cannot be allocated and returns an error code (currently * also -1) from calls to fileset_populate_file or recursive * calls to fileset_populate_subdir. */ static int fileset_populate_subdir(fileset_t *fileset, filesetentry_t *parent, int serial, double depth) { double randepth, drand, ranwidth, gamma; int isleaf = 0; char tmpname[16]; filesetentry_t *entry; int i; depth += 1; /* Create dir node */ if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY)) == NULL) { filebench_log(LOG_ERROR, "fileset_populate_subdir: Can't malloc filesetentry"); return (-1); } (void) pthread_mutex_init(&entry->fse_lock, ipc_mutexattr()); (void) snprintf(tmpname, sizeof (tmpname), "%08d", serial); if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) { filebench_log(LOG_ERROR, "fileset_populate_subdir: Can't alloc path string"); return (-1); } entry->fse_parent = parent; entry->fse_flags |= FSE_DIR | FSE_FREE; fileset_insdirlist(fileset, entry); gamma = *(fileset->fs_dirgamma) / 1000.0; if (gamma > 0) { drand = gamma_dist_knuth(gamma, fileset->fs_meandepth / gamma); randepth = (int)drand; } else { randepth = (int)fileset->fs_meandepth; } gamma = *(fileset->fs_sizegamma) / 1000.0; if (gamma > 0) { drand = gamma_dist_knuth(gamma, fileset->fs_meanwidth / gamma); ranwidth = drand; } else { ranwidth = fileset->fs_meanwidth; } if (randepth == 0) randepth = 1; if (ranwidth == 0) ranwidth = 1; if (depth >= randepth) isleaf = 1; /* * Create directory of random width according to distribution, or * if root directory, continue until #files required */ for (i = 1; ((parent == NULL) || (i < ranwidth + 1)) && (fileset->fs_realfiles < *(fileset->fs_entries)); i++) { int ret = 0; if (parent && isleaf) ret = fileset_populate_file(fileset, entry, i); else ret = fileset_populate_subdir(fileset, entry, i, depth); if (ret != 0) return (ret); } return (0); }