/*
 * tools/lib/vg_create_remove.c
 *
 * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * March 1997
 * January 1999
 * January 2000
 * February 2001
 *
 *
 * This LVM library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This LVM library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this LVM library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 */

/*
 * Changelog
 *
 *    08/02/2000 - use debug_enter()/debug_leave()
 *    13/02/2001 - use /dev/lvm device rather than /dev/<vg>/group
 *    04/04/2001 - Try both VG_CREATE and VG_CREATE_OLD (for pre-beta6 kernels).
 *                 Note that this will cause a warning message for old kernels,
 *                 but that also encourages people to upgrade the kernel code.
 *    14/06/2001 - Add ENOTTY checking in addition to EINVAL, because this will
 *                 allow us to distinguish between a bad ioctl and bad ioctl
 *                 arguements (as soon as the kernel returns ENOTTY as well).
 *
 */

#include <liblvm.h>

static int vg_create_remove ( const char *lvm_dev_name, vg_t *vg, int ioc)
{
   int lvm_dev;
   int ret = 0;

   if ( ( lvm_dev = open ( lvm_dev_name, O_RDWR)) == -1)
      ret = -LVM_EVG_CREATE_REMOVE_OPEN;
   else {
      debug ( "vg_create_remove -- IOCTL %x on %s with VG ptr %p\n",
	      ioc, lvm_dev_name, vg);
      if ( ( ret = ioctl ( lvm_dev, ioc, vg)) == -1)
         ret = -errno;
      debug ( "vg_create_remove -- IOCTL returned: %d\n", ret);
      close ( lvm_dev);
   }

   return ret;
}


int vg_create ( char *vg_name, vg_t *vg)
{
   int ret;

   debug_enter ( "vg_create -- CALLED with VG %s\n", vg ? vg->vg_name: "NULL");

   ret = vg_check_consistency ( vg);
   if (ret == 0) {
      ret = vg_create_remove ( LVM_DEV, (void *)vg, VG_CREATE);
#ifdef VG_CREATE_OLD
      if (ret == -EINVAL || ret == -ENOTTY) {
         char lvm_dev_name[NAME_LEN];

         memset ( lvm_dev_name, 0, sizeof ( lvm_dev_name));
         snprintf ( lvm_dev_name, sizeof ( lvm_dev_name) - 1,
                                  LVM_DIR_PREFIX "%s/group", vg->vg_name);
         ret = vg_create_remove ( lvm_dev_name, (void *)vg, VG_CREATE_OLD);
      }
#endif
   }

   debug_leave ( "vg_create -- LEAVING with ret: %d\n", ret);
   return ret;
}

int vg_remove ( char *vg_name)
{
   int ret;

   debug_enter ( "vg_remove -- CALLED with VG %s\n", vg_name);

   ret = vg_check_name ( vg_name);
   if (ret == 0) {
      char lvm_dev_name[NAME_LEN];

      sprintf ( lvm_dev_name, LVM_DIR_PREFIX "%s/group", vg_name);
      ret = vg_create_remove ( lvm_dev_name, NULL, VG_REMOVE);
   }

   debug_leave ( "vg_remove -- LEAVING with ret: %d\n", ret);
   return ret;
}
