/*
 * tools/lib/lv_write_all_lv.c
 *
 * Copyright (C) 1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * March 1997
 * August 1998
 * January 2000
 *
 *
 * 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
 *
 *    30/08/1998 - seperated disk and core lv structures
 *                 by using lv_copy_to_disk()
 *    31/01/2000 - use debug_enter()/debug_leave()
 *
 */

#include <liblvm.h>


int lv_write_all_lv ( char *pv_name, vg_t *vg) {
   int ret = 0;
   int l = 0;
   int pvol = -1;
   uint size = 0;
   lv_disk_t *lv_this = NULL;
   lv_disk_t *lv_disk_tmp = NULL;

   debug_enter ( "lv_write_all_lv -- CALLED  pv_name: %s\n", pv_name);

   if ( pv_name == NULL ||
        pv_check_name ( pv_name) < 0 ||
        vg == NULL ||
        vg_check_name ( vg->vg_name) < 0 ||
        vg->lv_max == 0 ||
        vg->lv_max > MAX_LV) {
      ret = -LVM_EPARAM;
      goto lv_write_all_lv_end;
   }

   size = vg->lv_max * sizeof ( lv_disk_t);
   if ( ( lv_this = malloc ( size)) == NULL) {
      fprintf ( stderr, "malloc error in %s [line %d]\n",
                        __FILE__, __LINE__);
      ret = -LVM_ELV_WRITE_ALL_LV_MALLOC;
      goto lv_write_all_lv_end;
   }

   for ( l = 0; l < vg->lv_max; l++) {
      if ( vg->lv[l] != NULL) {
         debug ( "lv_write_all_lv -- copying vg->lv[%d] \"%s\"\n",
                  l, vg->lv[l]->lv_name);
         memcpy ( &lv_this[l],
                  ( lv_disk_tmp = lv_copy_to_disk ( vg->lv[l])),
                  sizeof ( lv_disk_t));
         free ( lv_disk_tmp);
      } else {
         debug ( "lv_write_all_lv -- copying EMPTY LV #%d\n", l);
         memset ( &lv_this[l], 0, sizeof ( lv_disk_t));
      }
   }
   debug ( "lv_write_all_lv -- storing %d byte of %d LVs on %s\n",
            size, vg->lv_max, pv_name);
   if ( ( pvol = open ( pv_name, O_WRONLY)) == -1)
      ret = -LVM_ELV_WRITE_ALL_LV_OPEN;
   else if ( lseek ( pvol, vg->pv[0]->lv_on_disk.base, SEEK_SET) != \
             vg->pv[0]->lv_on_disk.base)
      ret = -LVM_ELV_WRITE_ALL_LV_LSEEK;
   else if ( write ( pvol, lv_this, size) != size)
      ret = -LVM_ELV_WRITE_ALL_LV_WRITE;
   free ( lv_this);

   if ( pvol != -1) {
      fsync ( pvol);
      close ( pvol);
   }

lv_write_all_lv_end:

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