1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _FB_FILESET_H
  27 #define _FB_FILESET_H
  28 
  29 #include "filebench.h"
  30 #include "config.h"
  31 
  32 #ifndef HAVE_OFF64_T
  33 /*
  34  * We are probably on linux.
  35  * According to http://www.suse.de/~aj/linux_lfs.html, defining the
  36  * above, automatically changes type of off_t to off64_t. so let
  37  * us use only off_t as off64_t is not defined
  38  */
  39 #define off64_t off_t
  40 #endif /* HAVE_OFF64_T */
  41 
  42 #include <stdio.h>
  43 #include <stdlib.h>
  44 #include <unistd.h>
  45 #include <sys/stat.h>
  46 #include <sys/types.h>
  47 #include <sys/param.h>
  48 #include <sys/resource.h>
  49 #include <pthread.h>
  50 
  51 #include "vars.h"
  52 #include "fb_avl.h"
  53 
  54 #define FILE_ALLOC_BLOCK (off64_t)(1024 * 1024)
  55 
  56 #ifdef  __cplusplus
  57 extern "C" {
  58 #endif
  59 
  60 #define FSE_MAXTID 16384
  61 
  62 #define FSE_MAXPATHLEN 16
  63 #define FSE_TYPE_FILE           0x00
  64 #define FSE_TYPE_DIR            0x01
  65 #define FSE_TYPE_LEAFDIR        0x02
  66 #define FSE_TYPE_MASK           0x03
  67 #define FSE_FREE                0x04
  68 #define FSE_EXISTS              0x08
  69 #define FSE_BUSY                0x10
  70 #define FSE_REUSING             0x20
  71 #define FSE_THRD_WAITNG         0x40
  72 
  73 typedef struct filesetentry {
  74         struct filesetentry     *fse_next;      /* master list of entries */
  75         struct filesetentry     *fse_parent;    /* link to directory */
  76         avl_node_t              fse_link;       /* links in avl btree, prot. */
  77                                                 /*    by fs_pick_lock */
  78         uint_t                  fse_index;      /* file order number */
  79         struct filesetentry     *fse_nextoftype; /* List of specific fse */
  80         struct fileset          *fse_fileset;   /* Parent fileset */
  81         char                    *fse_path;
  82         int                     fse_depth;
  83         off64_t                 fse_size;
  84         int                     fse_open_cnt;   /* protected by fs_pick_lock */
  85         int                     fse_flags;      /* protected by fs_pick_lock */
  86 } filesetentry_t;
  87 
  88 #define FSE_OFFSETOF(f) ((size_t)(&(((filesetentry_t *)0)->f)))
  89 
  90 /* type of fileset entry to obtain */
  91 #define FILESET_PICKFILE    0x00 /* Pick a file from the set */
  92 #define FILESET_PICKDIR     0x01 /* Pick a directory */
  93 #define FILESET_PICKLEAFDIR 0x02 /* Pick a leaf directory */
  94 #define FILESET_PICKMASK    0x03 /* Pick type mask */
  95 /* other pick flags */
  96 #define FILESET_PICKUNIQUE  0x04 /* Pick a unique file or leafdir from the */
  97                                     /* fileset until empty */
  98 #define FILESET_PICKEXISTS  0x10 /* Pick an existing file */
  99 #define FILESET_PICKNOEXIST 0x20 /* Pick a file that doesn't exist */
 100 #define FILESET_PICKBYINDEX 0x40 /* use supplied index number to select file */
 101 #define FILESET_PICKFREE    FILESET_PICKUNIQUE
 102 
 103 /* fileset attributes */
 104 #define FILESET_IS_RAW_DEV  0x01 /* fileset is a raw device */
 105 #define FILESET_IS_FILE     0x02 /* Fileset is emulating a single file */
 106 
 107 typedef struct fileset {
 108         struct fileset  *fs_next;       /* Next in list */
 109         avd_t           fs_name;        /* Name */
 110         avd_t           fs_path;        /* Pathname prefix in fileset */
 111         avd_t           fs_entries;     /* Number of entries attr */
 112                                         /* (possibly random) */
 113         fbint_t         fs_constentries; /* Constant version of enties attr */
 114         avd_t           fs_leafdirs;    /* Number of leaf directories attr */
 115                                         /* (possibly random) */
 116         fbint_t         fs_constleafdirs; /* Constant version of leafdirs */
 117                                             /* attr */
 118         avd_t           fs_preallocpercent; /* Prealloc size */
 119         int             fs_attrs;       /* Attributes */
 120         avd_t           fs_dirwidth;    /* Explicit or mean for distribution */
 121         avd_t           fs_dirdepthrv;  /* random variable for dir depth */
 122         avd_t           fs_size;        /* Explicit or mean for distribution */
 123         avd_t           fs_dirgamma;    /* Dirdepth Gamma distribution */
 124                                         /* (* 1000) defaults to 1500, set */
 125                                         /* to 0 for explicit depth */
 126         avd_t           fs_sizegamma;   /* Filesize and dirwidth Gamma */
 127                                         /* distribution (* 1000), default */
 128                                         /* is 1500, set to 0 for explicit */
 129         avd_t           fs_create;      /* Attr */
 130         avd_t           fs_prealloc;    /* Attr */
 131         avd_t           fs_paralloc;    /* Attr */
 132         avd_t           fs_cached;      /* Attr */
 133         avd_t           fs_reuse;       /* Attr */
 134         avd_t           fs_readonly;    /* Attr */
 135         avd_t           fs_trust_tree;  /* Attr */
 136         double          fs_meandepth;   /* Computed mean depth */
 137         double          fs_meanwidth;   /* Specified mean dir width */
 138         double          fs_meansize;    /* Specified mean file size */
 139         int             fs_realfiles;   /* Actual files */
 140         int             fs_realleafdirs; /* Actual explicit leaf directories */
 141         off64_t         fs_bytes;       /* Total space consumed by files */
 142 
 143         int64_t         fs_idle_files;  /* number of files NOT busy */
 144         pthread_cond_t  fs_idle_files_cv; /* idle files condition variable */
 145 
 146         int64_t         fs_idle_dirs;   /* number of dirs NOT busy */
 147         pthread_cond_t  fs_idle_dirs_cv; /* idle dirs condition variable */
 148 
 149         int64_t         fs_idle_leafdirs; /* number of dirs NOT busy */
 150         pthread_cond_t  fs_idle_leafdirs_cv; /* idle dirs condition variable */
 151 
 152         pthread_mutex_t fs_pick_lock;   /* per fileset "pick" function lock */
 153         pthread_cond_t  fs_thrd_wait_cv; /* per fileset file busy wait cv */
 154         avl_tree_t      fs_free_files;  /* btree of free files */
 155         avl_tree_t      fs_exist_files; /* btree of files on device */
 156         avl_tree_t      fs_noex_files;  /* btree of files NOT on device */
 157         avl_tree_t      fs_dirs;        /* btree of internal dirs */
 158         avl_tree_t      fs_free_leaf_dirs; /* btree of free leaf dirs */
 159         avl_tree_t      fs_exist_leaf_dirs; /* btree of leaf dirs on device */
 160         avl_tree_t      fs_noex_leaf_dirs;  /* btree of leaf dirs NOT */
 161                                             /* currently on device */
 162         filesetentry_t  *fs_filelist;   /* List of files */
 163         uint_t          fs_file_exrotor[FSE_MAXTID];    /* next file to */
 164                                                         /* select */
 165         uint_t          fs_file_nerotor;        /* next non existent file */
 166                                                 /* to select for createfile */
 167         filesetentry_t  *fs_dirlist;    /* List of directories */
 168         uint_t          fs_dirrotor;    /* index of next directory to select */
 169         filesetentry_t  *fs_leafdirlist; /* List of leaf directories */
 170         uint_t          fs_leafdir_exrotor;     /* Ptr to next existing leaf */
 171                                                 /* directory to select */
 172         uint_t          fs_leafdir_nerotor;     /* Ptr to next non-existing */
 173         int             *fs_filehistop;         /* Ptr to access histogram */
 174         int             fs_histo_id;    /* shared memory id for filehisto */
 175         pthread_mutex_t fs_histo_lock;  /* lock for incr of histo */
 176 } fileset_t;
 177 
 178 int fileset_createset(fileset_t *);
 179 void fileset_delete_all_filesets(void);
 180 int fileset_openfile(fb_fdesc_t *fd, fileset_t *fileset,
 181     filesetentry_t *entry, int flag, int mode, int attrs);
 182 fileset_t *fileset_define(avd_t);
 183 fileset_t *fileset_find(char *name);
 184 filesetentry_t *fileset_pick(fileset_t *fileset, int flags, int tid,
 185     int index);
 186 char *fileset_resolvepath(filesetentry_t *entry);
 187 void fileset_usage(void);
 188 int fileset_iter(int (*cmd)(fileset_t *fileset, int first));
 189 int fileset_print(fileset_t *fileset, int first);
 190 void fileset_unbusy(filesetentry_t *entry, int update_exist,
 191     int new_exist_val, int open_cnt_incr);
 192 int fileset_dump_histo(fileset_t *fileset, int first);
 193 void fileset_attach_all_histos(void);
 194 
 195 #ifdef  __cplusplus
 196 }
 197 #endif
 198 
 199 #endif  /* _FB_FILESET_H */