LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/lib/format_pool - format_pool.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 26 141 18.4 %
Date: 2010-04-13 Functions: 3 10 30.0 %
Branches: 5 58 8.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
       4                 :            :  *
       5                 :            :  * This file is part of LVM2.
       6                 :            :  *
       7                 :            :  * This copyrighted material is made available to anyone wishing to use,
       8                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       9                 :            :  * of the GNU Lesser General Public License v.2.1.
      10                 :            :  *
      11                 :            :  * You should have received a copy of the GNU Lesser General Public License
      12                 :            :  * along with this program; if not, write to the Free Software Foundation,
      13                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "lib.h"
      17                 :            : #include "label.h"
      18                 :            : #include "metadata.h"
      19                 :            : #include "limits.h"
      20                 :            : #include "display.h"
      21                 :            : #include "toolcontext.h"
      22                 :            : #include "lvmcache.h"
      23                 :            : #include "disk_rep.h"
      24                 :            : #include "format_pool.h"
      25                 :            : #include "pool_label.h"
      26                 :            : 
      27                 :            : /* Must be called after pvs are imported */
      28                 :          0 : static struct user_subpool *_build_usp(struct dm_list *pls, struct dm_pool *mem,
      29                 :            :                                        int *sps)
      30                 :            : {
      31                 :            :         struct pool_list *pl;
      32                 :          0 :         struct user_subpool *usp = NULL, *cur_sp = NULL;
      33                 :          0 :         struct user_device *cur_dev = NULL;
      34                 :            : 
      35                 :            :         /*
      36                 :            :          * FIXME: Need to do some checks here - I'm tempted to add a
      37                 :            :          * user_pool structure and build the entire thing to check against.
      38                 :            :          */
      39         [ #  # ]:          0 :         dm_list_iterate_items(pl, pls) {
      40                 :          0 :                 *sps = pl->pd.pl_subpools;
      41 [ #  # ][ #  # ]:          0 :                 if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
      42                 :          0 :                         log_error("Unable to allocate %d subpool structures",
      43                 :            :                                   *sps);
      44                 :          0 :                         return 0;
      45                 :            :                 }
      46                 :            : 
      47         [ #  # ]:          0 :                 if (cur_sp != &usp[pl->pd.pl_sp_id]) {
      48                 :          0 :                         cur_sp = &usp[pl->pd.pl_sp_id];
      49                 :            : 
      50                 :          0 :                         cur_sp->id = pl->pd.pl_sp_id;
      51                 :          0 :                         cur_sp->striping = pl->pd.pl_striping;
      52                 :          0 :                         cur_sp->num_devs = pl->pd.pl_sp_devs;
      53                 :          0 :                         cur_sp->type = pl->pd.pl_sp_type;
      54                 :          0 :                         cur_sp->initialized = 1;
      55                 :            :                 }
      56                 :            : 
      57   [ #  #  #  # ]:          0 :                 if (!cur_sp->devs &&
      58                 :          0 :                     (!(cur_sp->devs =
      59                 :          0 :                        dm_pool_zalloc(mem,
      60                 :            :                                    sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) {
      61                 :            : 
      62                 :          0 :                         log_error("Unable to allocate %d pool_device "
      63                 :            :                                   "structures", pl->pd.pl_sp_devs);
      64                 :          0 :                         return 0;
      65                 :            :                 }
      66                 :            : 
      67                 :          0 :                 cur_dev = &cur_sp->devs[pl->pd.pl_sp_devid];
      68                 :          0 :                 cur_dev->sp_id = cur_sp->id;
      69                 :          0 :                 cur_dev->devid = pl->pd.pl_sp_id;
      70                 :          0 :                 cur_dev->blocks = pl->pd.pl_blocks;
      71                 :          0 :                 cur_dev->pv = pl->pv;
      72                 :          0 :                 cur_dev->initialized = 1;
      73                 :            :         }
      74                 :            : 
      75                 :          0 :         return usp;
      76                 :            : }
      77                 :            : 
      78                 :          0 : static int _check_usp(char *vgname, struct user_subpool *usp, int sp_count)
      79                 :            : {
      80                 :            :         int i;
      81                 :            :         unsigned j;
      82                 :            : 
      83         [ #  # ]:          0 :         for (i = 0; i < sp_count; i++) {
      84         [ #  # ]:          0 :                 if (!usp[i].initialized) {
      85                 :          0 :                         log_error("Missing subpool %d in pool %s", i, vgname);
      86                 :          0 :                         return 0;
      87                 :            :                 }
      88         [ #  # ]:          0 :                 for (j = 0; j < usp[i].num_devs; j++) {
      89         [ #  # ]:          0 :                         if (!usp[i].devs[j].initialized) {
      90                 :          0 :                                 log_error("Missing device %u for subpool %d"
      91                 :            :                                           " in pool %s", j, i, vgname);
      92                 :          0 :                                 return 0;
      93                 :            :                         }
      94                 :            : 
      95                 :            :                 }
      96                 :            :         }
      97                 :            : 
      98                 :          0 :         return 1;
      99                 :            : }
     100                 :            : 
     101                 :          0 : static struct volume_group *_build_vg_from_pds(struct format_instance
     102                 :            :                                                *fid, struct dm_pool *mem,
     103                 :            :                                                struct dm_list *pds)
     104                 :            : {
     105                 :          0 :         struct dm_pool *smem = fid->fmt->cmd->mem;
     106                 :          0 :         struct volume_group *vg = NULL;
     107                 :          0 :         struct user_subpool *usp = NULL;
     108                 :            :         int sp_count;
     109                 :            : 
     110         [ #  # ]:          0 :         if (!(vg = dm_pool_zalloc(smem, sizeof(*vg)))) {
     111                 :          0 :                 log_error("Unable to allocate volume group structure");
     112                 :          0 :                 return NULL;
     113                 :            :         }
     114                 :            : 
     115                 :          0 :         vg->cmd = fid->fmt->cmd;
     116                 :          0 :         vg->vgmem = mem;
     117                 :          0 :         vg->fid = fid;
     118                 :          0 :         vg->name = NULL;
     119                 :          0 :         vg->status = 0;
     120                 :          0 :         vg->extent_count = 0;
     121                 :          0 :         vg->pv_count = 0;
     122                 :          0 :         vg->seqno = 1;
     123                 :          0 :         vg->system_id = NULL;
     124                 :          0 :         dm_list_init(&vg->pvs);
     125                 :          0 :         dm_list_init(&vg->lvs);
     126                 :          0 :         dm_list_init(&vg->tags);
     127                 :          0 :         dm_list_init(&vg->removed_pvs);
     128                 :            : 
     129         [ #  # ]:          0 :         if (!import_pool_vg(vg, smem, pds))
     130                 :          0 :                 return_NULL;
     131                 :            : 
     132         [ #  # ]:          0 :         if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds))
     133                 :          0 :                 return_NULL;
     134                 :            : 
     135         [ #  # ]:          0 :         if (!import_pool_lvs(vg, smem, pds))
     136                 :          0 :                 return_NULL;
     137                 :            : 
     138                 :            :         /*
     139                 :            :          * I need an intermediate subpool structure that contains all the
     140                 :            :          * relevant info for this.  Then i can iterate through the subpool
     141                 :            :          * structures for checking, and create the segments
     142                 :            :          */
     143         [ #  # ]:          0 :         if (!(usp = _build_usp(pds, mem, &sp_count)))
     144                 :          0 :                 return_NULL;
     145                 :            : 
     146                 :            :         /*
     147                 :            :          * check the subpool structures - we can't handle partial VGs in
     148                 :            :          * the pool format, so this will error out if we're missing PVs
     149                 :            :          */
     150         [ #  # ]:          0 :         if (!_check_usp(vg->name, usp, sp_count))
     151                 :          0 :                 return_NULL;
     152                 :            : 
     153         [ #  # ]:          0 :         if (!import_pool_segments(&vg->lvs, smem, usp, sp_count))
     154                 :          0 :                 return_NULL;
     155                 :            : 
     156                 :          0 :         return vg;
     157                 :            : }
     158                 :            : 
     159                 :          0 : static struct volume_group *_pool_vg_read(struct format_instance *fid,
     160                 :            :                                      const char *vg_name,
     161                 :            :                                      struct metadata_area *mda __attribute((unused)))
     162                 :            : {
     163                 :          0 :         struct dm_pool *mem = dm_pool_create("pool vg_read", VG_MEMPOOL_CHUNK);
     164                 :            :         struct dm_list pds;
     165                 :          0 :         struct volume_group *vg = NULL;
     166                 :            : 
     167                 :          0 :         dm_list_init(&pds);
     168                 :            : 
     169                 :            :         /* We can safely ignore the mda passed in */
     170                 :            : 
     171         [ #  # ]:          0 :         if (!mem)
     172                 :          0 :                 return_NULL;
     173                 :            : 
     174                 :            :         /* Strip dev_dir if present */
     175                 :          0 :         vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
     176                 :            : 
     177                 :            :         /* Read all the pvs in the vg */
     178         [ #  # ]:          0 :         if (!read_pool_pds(fid->fmt, vg_name, mem, &pds))
     179                 :          0 :                 goto_out;
     180                 :            : 
     181                 :            :         /* Do the rest of the vg stuff */
     182         [ #  # ]:          0 :         if (!(vg = _build_vg_from_pds(fid, mem, &pds)))
     183                 :          0 :                 goto_out;
     184                 :            : 
     185                 :          0 :         return vg;
     186                 :            : out:
     187                 :          0 :         dm_pool_destroy(mem);
     188                 :          0 :         return NULL;
     189                 :            : }
     190                 :            : 
     191                 :          0 : static int _pool_pv_setup(const struct format_type *fmt __attribute((unused)),
     192                 :            :                           uint64_t pe_start __attribute((unused)),
     193                 :            :                           uint32_t extent_count __attribute((unused)),
     194                 :            :                           uint32_t extent_size __attribute((unused)),
     195                 :            :                           unsigned long data_alignment __attribute((unused)),
     196                 :            :                           unsigned long data_alignment_offset __attribute((unused)),
     197                 :            :                           int pvmetadatacopies __attribute((unused)),
     198                 :            :                           uint64_t pvmetadatasize __attribute((unused)),
     199                 :            :                           struct dm_list *mdas __attribute((unused)),
     200                 :            :                           struct physical_volume *pv __attribute((unused)),
     201                 :            :                           struct volume_group *vg __attribute((unused)))
     202                 :            : {
     203                 :          0 :         return 1;
     204                 :            : }
     205                 :            : 
     206                 :          0 : static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
     207                 :            :                          struct physical_volume *pv,
     208                 :            :                          struct dm_list *mdas __attribute((unused)),
     209                 :            :                          int scan_label_only __attribute((unused)))
     210                 :            : {
     211                 :          0 :         struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
     212                 :            :         struct pool_list *pl;
     213                 :            :         struct device *dev;
     214                 :          0 :         int r = 0;
     215                 :            : 
     216                 :          0 :         log_very_verbose("Reading physical volume data %s from disk", pv_name);
     217                 :            : 
     218         [ #  # ]:          0 :         if (!mem)
     219                 :          0 :                 return_0;
     220                 :            : 
     221         [ #  # ]:          0 :         if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
     222                 :          0 :                 goto_out;
     223                 :            : 
     224                 :            :         /*
     225                 :            :          * I need to read the disk and populate a pv structure here
     226                 :            :          * I'll probably need to abstract some of this later for the
     227                 :            :          * vg_read code
     228                 :            :          */
     229         [ #  # ]:          0 :         if (!(pl = read_pool_disk(fmt, dev, mem, NULL)))
     230                 :          0 :                 goto_out;
     231                 :            : 
     232         [ #  # ]:          0 :         if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl))
     233                 :          0 :                 goto_out;
     234                 :            : 
     235                 :          0 :         pv->fmt = fmt;
     236                 :            : 
     237                 :          0 :         r = 1;
     238                 :            : 
     239                 :            :       out:
     240                 :          0 :         dm_pool_destroy(mem);
     241                 :          0 :         return r;
     242                 :            : }
     243                 :            : 
     244                 :            : /* *INDENT-OFF* */
     245                 :            : static struct metadata_area_ops _metadata_format_pool_ops = {
     246                 :            :         .vg_read = _pool_vg_read,
     247                 :            : };
     248                 :            : /* *INDENT-ON* */
     249                 :            : 
     250                 :          1 : static struct format_instance *_pool_create_instance(const struct format_type *fmt,
     251                 :            :                                                 const char *vgname __attribute((unused)),
     252                 :            :                                                 const char *vgid __attribute((unused)),
     253                 :            :                                                 void *private __attribute((unused)))
     254                 :            : {
     255                 :            :         struct format_instance *fid;
     256                 :            :         struct metadata_area *mda;
     257                 :            : 
     258         [ -  + ]:          1 :         if (!(fid = dm_pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
     259                 :          0 :                 log_error("Unable to allocate format instance structure for "
     260                 :            :                           "pool format");
     261                 :          0 :                 return NULL;
     262                 :            :         }
     263                 :            : 
     264                 :          1 :         fid->fmt = fmt;
     265                 :          1 :         dm_list_init(&fid->metadata_areas);
     266                 :            : 
     267                 :            :         /* Define a NULL metadata area */
     268         [ -  + ]:          1 :         if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
     269                 :          0 :                 log_error("Unable to allocate metadata area structure "
     270                 :            :                           "for pool format");
     271                 :          0 :                 dm_pool_free(fmt->cmd->mem, fid);
     272                 :          0 :                 return NULL;
     273                 :            :         }
     274                 :            : 
     275                 :          1 :         mda->ops = &_metadata_format_pool_ops;
     276                 :          1 :         mda->metadata_locn = NULL;
     277                 :          1 :         dm_list_add(&fid->metadata_areas, &mda->list);
     278                 :            : 
     279                 :          1 :         return fid;
     280                 :            : }
     281                 :            : 
     282                 :          0 : static void _pool_destroy_instance(struct format_instance *fid __attribute((unused)))
     283                 :            : {
     284                 :          0 : }
     285                 :            : 
     286                 :          3 : static void _pool_destroy(const struct format_type *fmt)
     287                 :            : {
     288                 :          3 :         dm_free((void *) fmt);
     289                 :          3 : }
     290                 :            : 
     291                 :            : /* *INDENT-OFF* */
     292                 :            : static struct format_handler _format_pool_ops = {
     293                 :            :         .pv_read = _pool_pv_read,
     294                 :            :         .pv_setup = _pool_pv_setup,
     295                 :            :         .create_instance = _pool_create_instance,
     296                 :            :         .destroy_instance = _pool_destroy_instance,
     297                 :            :         .destroy = _pool_destroy,
     298                 :            : };
     299                 :            : /* *INDENT-ON */
     300                 :            : 
     301                 :            : #ifdef POOL_INTERNAL
     302                 :          3 : struct format_type *init_pool_format(struct cmd_context *cmd)
     303                 :            : #else                           /* Shared */
     304                 :            : struct format_type *init_format(struct cmd_context *cmd);
     305                 :            : struct format_type *init_format(struct cmd_context *cmd)
     306                 :            : #endif
     307                 :            : {
     308                 :          3 :         struct format_type *fmt = dm_malloc(sizeof(*fmt));
     309                 :            : 
     310         [ -  + ]:          3 :         if (!fmt) {
     311                 :          0 :                 log_error("Unable to allocate format type structure for pool "
     312                 :            :                           "format");
     313                 :          0 :                 return NULL;
     314                 :            :         }
     315                 :            : 
     316                 :          3 :         fmt->cmd = cmd;
     317                 :          3 :         fmt->ops = &_format_pool_ops;
     318                 :          3 :         fmt->name = FMT_POOL_NAME;
     319                 :          3 :         fmt->alias = NULL;
     320                 :          3 :         fmt->orphan_vg_name = FMT_POOL_ORPHAN_VG_NAME;
     321                 :          3 :         fmt->features = 0;
     322                 :          3 :         fmt->private = NULL;
     323                 :            : 
     324         [ -  + ]:          3 :         if (!(fmt->labeller = pool_labeller_create(fmt))) {
     325                 :          0 :                 log_error("Couldn't create pool label handler.");
     326                 :          0 :                 return NULL;
     327                 :            :         }
     328                 :            : 
     329         [ -  + ]:          3 :         if (!(label_register_handler(FMT_POOL_NAME, fmt->labeller))) {
     330                 :          0 :                 log_error("Couldn't register pool label handler.");
     331                 :          0 :                 return NULL;
     332                 :            :         }
     333                 :            : 
     334                 :          3 :         log_very_verbose("Initialised format: %s", fmt->name);
     335                 :            : 
     336                 :          3 :         return fmt;
     337                 :            : }

Generated by: LCOV version 1.8