/*
 * tools/vgremove.c
 *
 * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * February, October 1997
 * May-June,September 1998
 * September-October 1999
 * February 2000
 *
 * vgremove is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * vgremove is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LVM; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 *
 */

/*
 * Changelog
 *
 *    12/10/1997 - added messages
 *    03/05/1998 - enhanced error messages with lvm_tab_vg_remove()
 *    16/05/1998 - added lvmtab checking
 *    13/06/1998 - change to use lvm_tab_vg_read_with_pv_and_lv()
 *                 instead of vg_read() and pv_read_all_pv_of_vg()
 *    27/06/1998 - changed lvm_tab_* calling convention
 *    05/09/1998 - corrected some messages
 *    25/09/1999 - added new exit codes
 *    06/10/1999 - implemented support for long options
 *    15/02/2000 - use lvm_error()
 *
 */

#include <lvm_user.h>

char *cmd = NULL;

#ifdef DEBUG
int opt_d = 0;
#endif

int main ( int argc, char **argv)
{
   int c = 0;
   int opt_v = 0;
   int p = 0;
   int ret = 0;
#ifdef DEBUG
   char *options = "dh?v";
#else
   char *options = "dh?v";
#endif
   struct option long_options[] = {
#ifdef DEBUG
      { "debug",   no_argument, NULL, 'd'},
#endif
      { "help",    no_argument, NULL, 'h'},
      { "verbose", no_argument, NULL, 'v'},
      { NULL,      0,           NULL, 0},
   };
   char *vg_name = NULL;
   vg_t *vg = NULL;
   pv_t **pv = NULL;

   cmd = basename ( argv[0]);

   SUSER_CHECK;
   LVMTAB_CHECK;

   while ( ( c = getopt_long ( argc, argv, options,
                               long_options, NULL)) != EOF) {
      switch ( c) {
#ifdef DEBUG
         case 'd':
            if ( opt_d > 0) {
               fprintf ( stderr, "%s -- d option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_d++;
            break;
#endif

         case 'h':
         case '?':
            printf ( "\n%s  (IOP %d)\n\n%s -- Volume Group Remove\n\n"
                     "Synopsis:\n"
                     "---------\n\n"
                     "%s\n"
#ifdef DEBUG
                     "\t[-d/--debug]\n"
#endif
                     "\t[-h/-?/--help]\n"
                     "\t[-v/--verbose]\n"
                     "\tVolumeGroupName [VolumeGroupName...]\n\n",
                     lvm_version, LVM_LIB_IOP_VERSION,  cmd, cmd);
            return 0;
            break;

         case 'v':
            if ( opt_v > 0) {
               fprintf ( stderr, "%s -- v option already given\n\n", cmd);
               return LVM_EINVALID_CMD_LINE;
            }
            opt_v++;
            break;

         default:
            fprintf ( stderr, "%s -- invalid command line option \"%c\"\n",
                      cmd, c);
            return LVM_EINVALID_CMD_LINE;
      }
   }

   CMD_MINUS_CHK;
   LVM_CHECK_IOP;
   LVM_LOCK ( 0);

   if ( optind == argc) {
      fprintf ( stderr, "%s -- please enter a volume group name\n\n", cmd);
      return LVM_EVGREMOVE_VG_NAME;
   }

   for ( ; optind < argc; optind++) {
      vg_name = argv[optind];
      if ( opt_v > 0) printf ( "%s -- checking volume group name \"%s\"\n",
                              cmd, vg_name);
      if ( vg_check_name ( vg_name) < 0) {
         fprintf ( stderr, "%s -- ERROR: invalid volume group name \"%s\"\n\n",
                           cmd, vg_name);
         return LVM_EVGREMOVE_VG_CHECK_NAME;
      }
   
      if ( opt_v > 0) printf ( "%s -- checking volume group \"%s\" activity\n",
                               cmd, vg_name);
      if ( vg_check_active ( vg_name) == TRUE) {
         fprintf ( stderr, "%s -- ERROR: can't remove active volume "
                           "group \"%s\"\n\n",
                           cmd, vg_name);
         return LVM_EVGREMOVE_VG_CHECK_ACTIVE;
      }
   
      /* does VG exist? */
      if ( opt_v > 0) printf ( "%s -- checking volume group \"%s\" existence\n",
                               cmd, vg_name);
      if ( ( ret = lvm_tab_vg_check_exist ( vg_name, NULL)) != TRUE) {
         if ( ret == -LVM_EVG_CHECK_EXIST_PV_COUNT) {
            fprintf ( stderr, "%s -- ERROR: not all physical volumes of "
                              "volume group \"%s\" are online\n\n",
                              cmd, vg_name);
            return LVM_EVGREMOVE_PV_ONLINE;
         } else if ( ret == FALSE) {
            fprintf ( stderr, "%s -- volume group \"%s\" doesn't exist\n\n",
                              cmd, vg_name);
         } else {
            fprintf ( stderr, "%s -- ERROR \"%s\" checking existence of "
                              "volume group \"%s\"\n\n",
                              cmd, lvm_error ( ret), vg_name);
         }
         return LVM_EVGREMOVE_VG_ERROR;
      }
   
      if ( opt_v > 0) printf ( "%s -- reading data of volume group \"%s\" "
                               "from \"%s\"\n",
                               cmd, vg_name, LVMTAB);
      if ( ( ret = lvm_tab_vg_read_with_pv_and_lv ( vg_name, &vg)) < 0) {
         fprintf ( stderr, "%s -- ERROR \"%s\" can't get data of volume group "
                           "\"%s\" from \"%s\"\n\n",
                           cmd, lvm_error ( ret), vg_name, LVMTAB);
         return LVM_EVGREMOVE_VG_READ;
      }
   
      if ( opt_v > 0) printf ( "%s -- checking for logical volumes in "
                               "volume group \"%s\"\n",
                               cmd, vg_name);
      if ( vg->lv_cur > 0) {
         fprintf ( stderr, "%s -- ERROR: can't remove volume group \"%s\" with"
                           " %u logical volume%s\n\n",
                           cmd, vg_name, vg->lv_cur, vg->lv_cur > 1 ? "s" : "");
         return LVM_EVGREMOVE_LV_EXISTS;
      }
   
      /* init physical volumes */
      if ( opt_v > 0) printf ( "%s -- initializing all physical volumes of "
                               "volume group \"%s\"\n\n",
                               cmd, vg_name);
      for ( p = 0; vg->pv[p] != NULL; p++) {
         if ( opt_v > 0) printf ( "%s -- initializing physical volume \"%s\"\n",
                                  cmd, pv[p]->pv_name);
         if ( ( ret = pv_setup_for_create ( vg->pv[p]->pv_name, vg->pv[p],
                                            vg->pv[p]->pv_size)) < 0) {
            fprintf ( stderr, "%s -- ERROR \"%s\" initializing physical "
                              "volume \"%s\"\n\n",
                              cmd, lvm_error ( ret), vg->pv[p]->pv_name);
            return LVM_EVGREMOVE_PV_SETUP;
         }
      }
   
      lvm_dont_interrupt ( 0);
      if ( opt_v > 0) printf ( "%s -- storing all initialized physical "
                               "volumes of volume group \"%s\" on disk(s)\n",
                               cmd, vg_name);
      if ( ( ret = pv_write_all_pv_of_vg ( vg)) < 0) {
         fprintf ( stderr, "%s -- ERROR \"%s\" storing all %u initialized "
                           "physical volumes of volume group \"%s\"\n\n",
                           cmd, lvm_error ( ret), vg->pv_cur, vg_name);
         return LVM_EVGREMOVE_PV_WRITE_ALL_PV_OF_VG;
      }
   
      if ( opt_v > 0) printf ( "%s -- removing special files of "
                               "volume group \"%s\"\n", cmd, vg_name);
      if ( vg_remove_dir_and_group_and_nodes ( vg_name) < 0) {
         fprintf ( stderr, "%s -- ERROR removing special files of volume "
                           "group \"%s\"\n",
                           cmd, vg_name);
      }
   
      if ( opt_v > 0) printf ( "%s -- removing \"%s\" entry of volume "
                               "group \"%s\"\n",
                               cmd, LVMTAB, vg_name);
      if ( ( ret = lvm_tab_vg_remove ( vg_name)) < 0) {
         fprintf ( stderr, "%s -- ERROR \"%s\" removing volume group \"%s\" "
                           "entry from \"%s\"\n\n",
                           cmd, lvm_error ( ret), vg_name, LVMTAB);
         return LVM_EVGREMOVE_VG_REMOVE;
      }
   
      printf ( "%s -- volume group \"%s\" successfully removed\n",
               cmd, vg_name);
      lvm_interrupt ();
   }

   LVM_UNLOCK ( 0);

   printf ( "\n");
   return 0;
}
