LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/tools - pvchange.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 148 0.0 %
Date: 2010-04-13 Functions: 0 2 0.0 %
Branches: 0 106 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2007 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 "tools.h"
      17                 :            : 
      18                 :            : /* FIXME Locking.  PVs in VG. */
      19                 :            : 
      20                 :          0 : static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
      21                 :            :                             void *handle __attribute((unused)))
      22                 :            : {
      23                 :          0 :         struct volume_group *vg = NULL;
      24                 :          0 :         const char *vg_name = NULL;
      25                 :            :         struct pv_list *pvl;
      26                 :            :         uint64_t sector;
      27                 :            :         uint32_t orig_pe_alloc_count;
      28                 :            :         /* FIXME Next three only required for format1. */
      29                 :            :         uint32_t orig_pe_count, orig_pe_size;
      30                 :            :         uint64_t orig_pe_start;
      31                 :            : 
      32                 :          0 :         const char *pv_name = pv_dev_name(pv);
      33                 :          0 :         const char *tag = NULL;
      34                 :            :         const char *orig_vg_name;
      35                 :            :         char uuid[64] __attribute((aligned(8)));
      36                 :            : 
      37                 :          0 :         int allocatable = 0;
      38                 :          0 :         int tagarg = 0;
      39                 :          0 :         int r = 0;
      40                 :            : 
      41         [ #  # ]:          0 :         if (arg_count(cmd, addtag_ARG))
      42                 :          0 :                 tagarg = addtag_ARG;
      43         [ #  # ]:          0 :         else if (arg_count(cmd, deltag_ARG))
      44                 :          0 :                 tagarg = deltag_ARG;
      45                 :            : 
      46         [ #  # ]:          0 :         if (arg_count(cmd, allocatable_ARG))
      47                 :          0 :                 allocatable = !strcmp(arg_str_value(cmd, allocatable_ARG, "n"),
      48                 :            :                                       "y");
      49 [ #  # ][ #  # ]:          0 :         else if (tagarg && !(tag = arg_str_value(cmd, tagarg, NULL))) {
      50                 :          0 :                 log_error("Failed to get tag");
      51                 :          0 :                 return 0;
      52                 :            :         }
      53                 :            : 
      54                 :            :         /* If in a VG, must change using volume group. */
      55         [ #  # ]:          0 :         if (!is_orphan(pv)) {
      56                 :          0 :                 vg_name = pv_vg_name(pv);
      57                 :            : 
      58                 :          0 :                 log_verbose("Finding volume group %s of physical volume %s",
      59                 :            :                             vg_name, pv_name);
      60                 :          0 :                 vg = vg_read_for_update(cmd, vg_name, NULL, 0);
      61         [ #  # ]:          0 :                 if (vg_read_error(vg)) {
      62                 :          0 :                         vg_release(vg);
      63                 :          0 :                         return_0;
      64                 :            :                 }
      65                 :            : 
      66         [ #  # ]:          0 :                 if (!(pvl = find_pv_in_vg(vg, pv_name))) {
      67                 :          0 :                         log_error("Unable to find \"%s\" in volume group \"%s\"",
      68                 :            :                                   pv_name, vg->name);
      69                 :          0 :                         goto out;
      70                 :            :                 }
      71 [ #  # ][ #  # ]:          0 :                 if (tagarg && !(vg->fid->fmt->features & FMT_TAGS)) {
      72                 :          0 :                         log_error("Volume group containing %s does not "
      73                 :            :                                   "support tags", pv_name);
      74                 :          0 :                         goto out;
      75                 :            :                 }
      76 [ #  # ][ #  # ]:          0 :                 if (arg_count(cmd, uuid_ARG) && lvs_in_vg_activated(vg)) {
      77                 :          0 :                         log_error("Volume group containing %s has active "
      78                 :            :                                   "logical volumes", pv_name);
      79                 :          0 :                         goto out;
      80                 :            :                 }
      81                 :          0 :                 pv = pvl->pv;
      82         [ #  # ]:          0 :                 if (!archive(vg))
      83                 :          0 :                         goto out;
      84                 :            :         } else {
      85         [ #  # ]:          0 :                 if (tagarg) {
      86                 :          0 :                         log_error("Can't change tag on Physical Volume %s not "
      87                 :            :                                   "in volume group", pv_name);
      88                 :          0 :                         return 0;
      89                 :            :                 }
      90                 :            : 
      91                 :          0 :                 vg_name = VG_ORPHANS;
      92                 :            : 
      93         [ #  # ]:          0 :                 if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
      94                 :          0 :                         log_error("Can't get lock for orphans");
      95                 :          0 :                         return 0;
      96                 :            :                 }
      97                 :            : 
      98         [ #  # ]:          0 :                 if (!(pv = pv_read(cmd, pv_name, NULL, &sector, 1, 0))) {
      99                 :          0 :                         unlock_vg(cmd, vg_name);
     100                 :          0 :                         log_error("Unable to read PV \"%s\"", pv_name);
     101                 :          0 :                         return 0;
     102                 :            :                 }
     103                 :            :         }
     104                 :            : 
     105         [ #  # ]:          0 :         if (arg_count(cmd, allocatable_ARG)) {
     106 [ #  # ][ #  # ]:          0 :                 if (is_orphan(pv) &&
     107                 :          0 :                     !(pv->fmt->features & FMT_ORPHAN_ALLOCATABLE)) {
     108                 :          0 :                         log_error("Allocatability not supported by orphan "
     109                 :            :                                   "%s format PV %s", pv->fmt->name, pv_name);
     110                 :          0 :                         goto out;
     111                 :            :                 }
     112                 :            : 
     113                 :            :                 /* change allocatability for a PV */
     114 [ #  # ][ #  # ]:          0 :                 if (allocatable && (pv_status(pv) & ALLOCATABLE_PV)) {
     115                 :          0 :                         log_error("Physical volume \"%s\" is already "
     116                 :            :                                   "allocatable", pv_name);
     117                 :          0 :                         r = 1;
     118                 :          0 :                         goto out;
     119                 :            :                 }
     120                 :            : 
     121 [ #  # ][ #  # ]:          0 :                 if (!allocatable && !(pv_status(pv) & ALLOCATABLE_PV)) {
     122                 :          0 :                         log_error("Physical volume \"%s\" is already "
     123                 :            :                                   "unallocatable", pv_name);
     124                 :          0 :                         r = 1;
     125                 :          0 :                         goto out;
     126                 :            :                 }
     127                 :            : 
     128         [ #  # ]:          0 :                 if (allocatable) {
     129                 :          0 :                         log_verbose("Setting physical volume \"%s\" "
     130                 :            :                                     "allocatable", pv_name);
     131                 :          0 :                         pv->status |= ALLOCATABLE_PV;
     132                 :            :                 } else {
     133                 :          0 :                         log_verbose("Setting physical volume \"%s\" NOT "
     134                 :            :                                     "allocatable", pv_name);
     135                 :          0 :                         pv->status &= ~ALLOCATABLE_PV;
     136                 :            :                 }
     137         [ #  # ]:          0 :         } else if (tagarg) {
     138                 :            :                 /* tag or deltag */
     139         [ #  # ]:          0 :                 if ((tagarg == addtag_ARG)) {
     140         [ #  # ]:          0 :                         if (!str_list_add(cmd->mem, &pv->tags, tag)) {
     141                 :          0 :                                 log_error("Failed to add tag %s to physical "
     142                 :            :                                           "volume %s", tag, pv_name);
     143                 :          0 :                                 goto out;
     144                 :            :                         }
     145                 :            :                 } else {
     146         [ #  # ]:          0 :                         if (!str_list_del(&pv->tags, tag)) {
     147                 :          0 :                                 log_error("Failed to remove tag %s from "
     148                 :            :                                           "physical volume" "%s", tag, pv_name);
     149                 :          0 :                                 goto out;
     150                 :            :                         }
     151                 :            :                 }
     152                 :            :         } else {
     153                 :            :                 /* --uuid: Change PV ID randomly */
     154         [ #  # ]:          0 :                 if (!id_create(&pv->id)) {
     155                 :          0 :                         log_error("Failed to generate new random UUID for %s.",
     156                 :            :                                   pv_name);
     157                 :          0 :                         goto out;
     158                 :            :                 }
     159         [ #  # ]:          0 :                 if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
     160                 :          0 :                         goto_out;
     161                 :          0 :                 log_verbose("Changing uuid of %s to %s.", pv_name, uuid);
     162         [ #  # ]:          0 :                 if (!is_orphan(pv)) {
     163                 :          0 :                         orig_vg_name = pv_vg_name(pv);
     164                 :          0 :                         orig_pe_alloc_count = pv_pe_alloc_count(pv);
     165                 :            : 
     166                 :            :                         /* FIXME format1 pv_write doesn't preserve these. */
     167                 :          0 :                         orig_pe_size = pv_pe_size(pv);
     168                 :          0 :                         orig_pe_start = pv_pe_start(pv);
     169                 :          0 :                         orig_pe_count = pv_pe_count(pv);
     170                 :            : 
     171                 :          0 :                         pv->vg_name = pv->fmt->orphan_vg_name;
     172                 :          0 :                         pv->pe_alloc_count = 0;
     173         [ #  # ]:          0 :                         if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
     174                 :          0 :                                 log_error("pv_write with new uuid failed "
     175                 :            :                                           "for %s.", pv_name);
     176                 :          0 :                                 goto out;
     177                 :            :                         }
     178                 :          0 :                         pv->vg_name = orig_vg_name;
     179                 :          0 :                         pv->pe_alloc_count = orig_pe_alloc_count;
     180                 :            : 
     181                 :          0 :                         pv->pe_size = orig_pe_size;
     182                 :          0 :                         pv->pe_start = orig_pe_start;
     183                 :          0 :                         pv->pe_count = orig_pe_count;
     184                 :            :                 }
     185                 :            :         }
     186                 :            : 
     187                 :          0 :         log_verbose("Updating physical volume \"%s\"", pv_name);
     188         [ #  # ]:          0 :         if (!is_orphan(pv)) {
     189 [ #  # ][ #  # ]:          0 :                 if (!vg_write(vg) || !vg_commit(vg)) {
     190                 :          0 :                         log_error("Failed to store physical volume \"%s\" in "
     191                 :            :                                   "volume group \"%s\"", pv_name, vg->name);
     192                 :          0 :                         goto out;
     193                 :            :                 }
     194                 :          0 :                 backup(vg);
     195         [ #  # ]:          0 :         } else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
     196                 :          0 :                 log_error("Failed to store physical volume \"%s\"",
     197                 :            :                           pv_name);
     198                 :          0 :                 goto out;
     199                 :            :         }
     200                 :            : 
     201                 :          0 :         log_print("Physical volume \"%s\" changed", pv_name);
     202                 :          0 :         r = 1;
     203                 :            : out:
     204                 :          0 :         unlock_and_release_vg(cmd, vg, vg_name);
     205                 :          0 :         return r;
     206                 :            : 
     207                 :            : }
     208                 :            : 
     209                 :          0 : int pvchange(struct cmd_context *cmd, int argc, char **argv)
     210                 :            : {
     211                 :          0 :         int opt = 0;
     212                 :          0 :         int done = 0;
     213                 :          0 :         int total = 0;
     214                 :            : 
     215                 :            :         struct physical_volume *pv;
     216                 :            :         char *pv_name;
     217                 :            : 
     218                 :            :         struct pv_list *pvl;
     219                 :            :         struct dm_list *pvslist;
     220                 :            :         struct dm_list mdas;
     221                 :            : 
     222         [ #  # ]:          0 :         if (arg_count(cmd, allocatable_ARG) + arg_count(cmd, addtag_ARG) +
     223                 :          0 :             arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) != 1) {
     224                 :          0 :                 log_error("Please give exactly one option of -x, -uuid, "
     225                 :            :                           "--addtag or --deltag");
     226                 :          0 :                 return EINVALID_CMD_LINE;
     227                 :            :         }
     228                 :            : 
     229 [ #  # ][ #  # ]:          0 :         if (!(arg_count(cmd, all_ARG)) && !argc) {
     230                 :          0 :                 log_error("Please give a physical volume path");
     231                 :          0 :                 return EINVALID_CMD_LINE;
     232                 :            :         }
     233                 :            : 
     234 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, all_ARG) && argc) {
     235                 :          0 :                 log_error("Option a and PhysicalVolumePath are exclusive");
     236                 :          0 :                 return EINVALID_CMD_LINE;
     237                 :            :         }
     238                 :            : 
     239         [ #  # ]:          0 :         if (argc) {
     240                 :          0 :                 log_verbose("Using physical volume(s) on command line");
     241         [ #  # ]:          0 :                 for (; opt < argc; opt++) {
     242                 :          0 :                         pv_name = argv[opt];
     243                 :          0 :                         dm_list_init(&mdas);
     244         [ #  # ]:          0 :                         if (!(pv = pv_read(cmd, pv_name, &mdas, NULL, 1, 0))) {
     245                 :          0 :                                 log_error("Failed to read physical volume %s",
     246                 :            :                                           pv_name);
     247                 :          0 :                                 continue;
     248                 :            :                         }
     249                 :            :                         /*
     250                 :            :                          * If a PV has no MDAs it may appear to be an
     251                 :            :                          * orphan until the metadata is read off
     252                 :            :                          * another PV in the same VG.  Detecting this
     253                 :            :                          * means checking every VG by scanning every
     254                 :            :                          * PV on the system.
     255                 :            :                          */
     256 [ #  # ][ #  # ]:          0 :                         if (is_orphan(pv) && !dm_list_size(&mdas)) {
     257         [ #  # ]:          0 :                                 if (!scan_vgs_for_pvs(cmd)) {
     258                 :          0 :                                         log_error("Rescan for PVs without "
     259                 :            :                                                   "metadata areas failed.");
     260                 :          0 :                                         continue;
     261                 :            :                                 }
     262         [ #  # ]:          0 :                                 if (!(pv = pv_read(cmd, pv_name,
     263                 :            :                                                    NULL, NULL, 1, 0))) {
     264                 :          0 :                                         log_error("Failed to read "
     265                 :            :                                                   "physical volume %s",
     266                 :            :                                                   pv_name);
     267                 :          0 :                                         continue;
     268                 :            :                                 }
     269                 :            :                         }
     270                 :            : 
     271                 :          0 :                         total++;
     272                 :          0 :                         done += _pvchange_single(cmd, pv, NULL);
     273                 :            :                 }
     274                 :            :         } else {
     275                 :          0 :                 log_verbose("Scanning for physical volume names");
     276         [ #  # ]:          0 :                 if (!(pvslist = get_pvs(cmd))) {
     277                 :          0 :                         stack;
     278                 :          0 :                         return ECMD_FAILED;
     279                 :            :                 }
     280                 :            : 
     281         [ #  # ]:          0 :                 dm_list_iterate_items(pvl, pvslist) {
     282                 :          0 :                         total++;
     283                 :          0 :                         done += _pvchange_single(cmd, pvl->pv, NULL);
     284                 :            :                 }
     285                 :            :         }
     286                 :            : 
     287 [ #  # ][ #  # ]:          0 :         log_print("%d physical volume%s changed / %d physical volume%s "
     288                 :            :                   "not changed",
     289                 :            :                   done, done == 1 ? "" : "s",
     290                 :            :                   total - done, (total - done) == 1 ? "" : "s");
     291                 :            : 
     292         [ #  # ]:          0 :         return (total == done) ? ECMD_PROCESSED : ECMD_FAILED;
     293                 :            : }

Generated by: LCOV version 1.8