/* lvm.c - module to read Logical Volumes.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
 *
 *  GRUB 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/lvm.h>

static struct grub_lvm_vg *vg_list;
static int lv_count;


/* Go the string STR and return the number after STR.  *P will point
   at the number.  In case STR is not found, *P will be NULL and the
   return value will be 0.  */
static int
grub_lvm_getvalue (char **p, char *str)
{
  *p = grub_strstr (*p, str);
  if (! *p)
    return 0;
  *p += grub_strlen (str);
  return grub_strtoul (*p, NULL, 10);
}

static int
grub_lvm_iterate (int (*hook) (const char *name))
{
  struct grub_lvm_vg *vg;
  for (vg = vg_list; vg; vg = vg->next)
    {
      struct grub_lvm_lv *lv;
      if (vg->lvs)
	for (lv = vg->lvs; lv; lv = lv->next)
	  if (hook (lv->name))
	    return 1;
    }

  return 0;
}

#ifdef GRUB_UTIL
static grub_disk_memberlist_t
grub_lvm_memberlist (grub_disk_t disk)
{
  struct grub_lvm_lv *lv = disk->data;
  grub_disk_memberlist_t list = NULL, tmp;
  struct grub_lvm_pv *pv;

  if (lv->vg->pvs)
    for (pv = lv->vg->pvs; pv; pv = pv->next)
      {
	tmp = grub_malloc (sizeof (*tmp));
	tmp->disk = pv->disk;
	tmp->next = list;
	list = tmp;
      }

  return list;
}
#endif

static grub_err_t
grub_lvm_open (const char *name, grub_disk_t disk)
{
  struct grub_lvm_vg *vg;
  struct grub_lvm_lv *lv = NULL;
  for (vg = vg_list; vg; vg = vg->next)
    {
      if (vg->lvs)
	for (lv = vg->lvs; lv; lv = lv->next)
	  if (! grub_strcmp (lv->name, name))
	    break;

      if (lv)
	break;
    }

  if (! lv)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown LVM device %s", name);

  disk->has_partitions = 0;
  disk->id = lv->number;
  disk->data = lv;
  disk->total_sectors = lv->size;

  return 0;
}

static void
grub_lvm_close (grub_disk_t disk __attribute ((unused)))
{
  return;
}

static grub_err_t
grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
		grub_size_t size, char *buf)
{
  grub_err_t err = 0;
  struct grub_lvm_lv *lv = disk->data;
  struct grub_lvm_vg *vg = lv->vg;
  struct grub_lvm_segment *seg = lv->segments;
  struct grub_lvm_pv *pv;
  grub_uint64_t offset;
  grub_uint64_t extent;
  unsigned int i;

  extent = grub_divmod64 (sector, vg->extent_size, NULL);

  /* Find the right segment.  */
  for (i = 0; i < lv->segment_count; i++)
    {
      if ((seg->start_extent <= extent)
	  && ((seg->start_extent + seg->extent_count) > extent))
	{
	  break;
	}

      seg++;
    }

  if (seg->stripe_count == 1)
    {
      /* This segment is linear, so that's easy.  We just need to find
	 out the offset in the physical volume and read SIZE bytes
	 from that.  */
      struct grub_lvm_stripe *stripe = seg->stripes;
      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */

      pv = stripe->pv;
      seg_offset = ((grub_uint64_t) stripe->start
		    * (grub_uint64_t) vg->extent_size) + pv->start;

      offset = sector - ((grub_uint64_t) seg->start_extent
			 * (grub_uint64_t) vg->extent_size) + seg_offset;
    }
  else
    {
      /* This is a striped segment. We have to find the right PV
	 similar to RAID0. */
      struct grub_lvm_stripe *stripe = seg->stripes;
      grub_uint32_t a, b;
      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
      unsigned int stripenr;

      offset = sector - ((grub_uint64_t) seg->start_extent
			 * (grub_uint64_t) vg->extent_size);

      a = grub_divmod64 (offset, seg->stripe_size, NULL);
      grub_divmod64 (a, seg->stripe_count, &stripenr);

      a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
      grub_divmod64 (offset, seg->stripe_size, &b);
      offset = a * seg->stripe_size + b;

      stripe += stripenr;
      pv = stripe->pv;

      seg_offset = ((grub_uint64_t) stripe->start
		    * (grub_uint64_t) vg->extent_size) + pv->start;

      offset += seg_offset;
    }

  /* Check whether we actually know the physical volume we want to
     read from.  */
  if (pv->disk)
    err = grub_disk_read (pv->disk, offset, 0,
			  size << GRUB_DISK_SECTOR_BITS, buf);
  else
    err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
		      "Physical volume %s not found", pv->name);

  return err;
}

static grub_err_t
grub_lvm_write (grub_disk_t disk __attribute ((unused)),
		 grub_disk_addr_t sector __attribute ((unused)),
		 grub_size_t size __attribute ((unused)),
		 const char *buf __attribute ((unused)))
{
  return GRUB_ERR_NOT_IMPLEMENTED_YET;
}

static int
grub_lvm_scan_device (const char *name)
{
  grub_err_t err;
  grub_disk_t disk;
  grub_uint64_t da_offset, da_size, mda_offset, mda_size;
  char buf[GRUB_LVM_LABEL_SIZE];
  char vg_id[GRUB_LVM_ID_STRLEN+1];
  char pv_id[GRUB_LVM_ID_STRLEN+1];
  char *metadatabuf, *p, *q, *vgname;
  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
  struct grub_lvm_pv_header *pvh;
  struct grub_lvm_disk_locn *dlocn;
  struct grub_lvm_mda_header *mdah;
  struct grub_lvm_raw_locn *rlocn;
  unsigned int i, j, vgname_len;
  struct grub_lvm_vg *vg;
  struct grub_lvm_pv *pv;

  disk = grub_disk_open (name);
  if (!disk)
    return 0;

  /* Search for label. */
  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
    {
      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
      if (err)
	goto fail;

      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
			   sizeof (lh->id)))
	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
			      sizeof (lh->type))))
	break;
    }

  /* Return if we didn't find a label. */
  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
    goto fail;

  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));

  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
    {
      pv_id[j++] = pvh->pv_uuid[i];
      if ((i != 1) && (i != 29) && (i % 4 == 1))
	pv_id[j++] = '-';
    }
  pv_id[j] = '\0';

  dlocn = pvh->disk_areas_xl;
  da_offset = grub_le_to_cpu64 (dlocn->offset);
  da_size = grub_le_to_cpu64 (dlocn->size);

  dlocn++;
  /* Is it possible to have multiple data/metadata areas? I haven't
     seen devices that have it. */
  if (dlocn->offset)
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "We don't support multiple LVM data areas");

      goto fail;
    }

  dlocn++;
  mda_offset = grub_le_to_cpu64 (dlocn->offset);
  mda_size = grub_le_to_cpu64 (dlocn->size);

  /* It's possible to have multiple copies of metadata areas, we just use the
     first one.  */

  /* Allocate buffer space for the circular worst-case scenario. */
  metadatabuf = grub_malloc (2 * mda_size);
  if (! metadatabuf)
    goto fail;

  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
  if (err)
    goto fail2;

  mdah = (struct grub_lvm_mda_header *) metadatabuf;
  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
		     sizeof (mdah->magic)))
      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "Unknown LVM metadata header");
      goto fail2;
    }

  rlocn = mdah->raw_locns;
  if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
      grub_le_to_cpu64 (mdah->size))
    {
      /* Metadata is circular. Copy the wrap in place. */
      grub_memcpy (metadatabuf + mda_size,
                   metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
                   grub_le_to_cpu64 (rlocn->offset) +
                   grub_le_to_cpu64 (rlocn->size) -
                   grub_le_to_cpu64 (mdah->size));
    }
  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);

  while (*q != ' ' && q < metadatabuf + mda_size)
    q++;

  if (q == metadatabuf + mda_size)
    goto fail2;

  vgname_len = q - p;
  vgname = grub_malloc (vgname_len + 1);
  if (!vgname)
    goto fail2;

  grub_memcpy (vgname, p, vgname_len);
  vgname[vgname_len] = '\0';

  p = grub_strstr (q, "id = \"");
  if (p == NULL)
    goto fail3;
  p += sizeof ("id = \"") - 1;
  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
  vg_id[GRUB_LVM_ID_STRLEN] = '\0';

  for (vg = vg_list; vg; vg = vg->next)
    {
      if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN))
	break;
    }

  if (! vg)
    {
      /* First time we see this volume group. We've to create the
	 whole volume group structure. */
      vg = grub_malloc (sizeof (*vg));
      if (! vg)
	goto fail3;
      vg->name = vgname;
      grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);

      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
      if (p == NULL)
	goto fail4;

      vg->lvs = NULL;
      vg->pvs = NULL;

      p = grub_strstr (p, "physical_volumes {");
      if (p)
	{
	  p += sizeof ("physical_volumes {") - 1;

	  /* Add all the pvs to the volume group. */
	  while (1)
	    {
	      int s;
	      while (grub_isspace (*p))
		p++;

	      if (*p == '}')
		break;

	      pv = grub_malloc (sizeof (*pv));
	      q = p;
	      while (*q != ' ')
		q++;

	      s = q - p;
	      pv->name = grub_malloc (s + 1);
	      grub_memcpy (pv->name, p, s);
	      pv->name[s] = '\0';

	      p = grub_strstr (p, "id = \"");
	      if (p == NULL)
		goto pvs_fail;
	      p += sizeof("id = \"") - 1;

	      grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
	      pv->id[GRUB_LVM_ID_STRLEN] = '\0';

	      pv->start = grub_lvm_getvalue (&p, "pe_start = ");
	      if (p == NULL)
		goto pvs_fail;

	      p = grub_strchr (p, '}');
	      if (p == NULL)
		goto pvs_fail;
	      p++;

	      pv->disk = NULL;
	      pv->next = vg->pvs;
	      vg->pvs = pv;

	      continue;
	    pvs_fail:
	      grub_free (pv->name);
	      grub_free (pv);
	      goto fail4;
	    }
	}

      p = grub_strstr (p, "logical_volumes");
      if (p)
	{
	  p += 18;

	  /* And add all the lvs to the volume group. */
	  while (1)
	    {
	      int s;
	      struct grub_lvm_lv *lv;
	      struct grub_lvm_segment *seg;

	      while (grub_isspace (*p))
		p++;

	      if (*p == '}')
		break;

	      lv = grub_malloc (sizeof (*lv));

	      q = p;
	      while (*q != ' ')
		q++;

	      s = q - p;
	      lv->name = grub_malloc (vgname_len + 1 + s + 1);
	      grub_memcpy (lv->name, vgname, vgname_len);
	      lv->name[vgname_len] = '-';
	      grub_memcpy (lv->name + vgname_len + 1, p, s);
	      lv->name[vgname_len + 1 + s] = '\0';

	      lv->size = 0;

	      lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
	      if (p == NULL)
		goto lvs_fail;
	      lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
	      seg = lv->segments;

	      for (i = 0; i < lv->segment_count; i++)
		{
		  struct grub_lvm_stripe *stripe;

		  p = grub_strstr (p, "segment");
		  if (p == NULL)
		    goto lvs_segment_fail;

		  seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
		  if (p == NULL)
		    goto lvs_segment_fail;
		  seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
		  if (p == NULL)
		    goto lvs_segment_fail;
		  seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
		  if (p == NULL)
		    goto lvs_segment_fail;

		  lv->size += seg->extent_count * vg->extent_size;

		  if (seg->stripe_count != 1)
		    seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");

		  seg->stripes = grub_malloc (sizeof (*stripe)
					      * seg->stripe_count);
		  stripe = seg->stripes;

		  p = grub_strstr (p, "stripes = [");
		  if (p == NULL)
		    goto lvs_segment_fail2;
		  p += sizeof("stripes = [") - 1;

		  for (j = 0; j < seg->stripe_count; j++)
		    {
		      char *pvname;

		      p = grub_strchr (p, '"');
		      if (p == NULL)
			continue;
		      q = ++p;
		      while (*q != '"')
			q++;

		      s = q - p;

		      pvname = grub_malloc (s + 1);
                      if (pvname == NULL)
                        goto lvs_segment_fail2;

		      grub_memcpy (pvname, p, s);
		      pvname[s] = '\0';

		      if (vg->pvs)
			for (pv = vg->pvs; pv; pv = pv->next)
			  {
			    if (! grub_strcmp (pvname, pv->name))
			      {
				stripe->pv = pv;
				break;
			      }
			  }

		      grub_free(pvname);

		      stripe->start = grub_lvm_getvalue (&p, ",");
		      if (p == NULL)
			continue;

		      stripe++;
		    }

		  seg++;

		  continue;
		lvs_segment_fail2:
		  grub_free (seg->stripes);
		lvs_segment_fail:
		  goto fail4;
		}

	      if (p != NULL)
		p = grub_strchr (p, '}');
	      if (p == NULL)
		goto lvs_fail;
	      p += 3;

	      lv->number = lv_count++;
	      lv->vg = vg;
	      lv->next = vg->lvs;
	      vg->lvs = lv;

	      continue;
	    lvs_fail:
	      grub_free (lv->name);
	      grub_free (lv);
	      goto fail4;
	    }
	}

	vg->next = vg_list;
	vg_list = vg;
    }
  else
    {
      grub_free (vgname);
    }

  /* Match the device we are currently reading from with the right
     PV. */
  if (vg->pvs)
    for (pv = vg->pvs; pv; pv = pv->next)
      {
	if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
	  {
	    /* This could happen to LVM on RAID, pv->disk points to the
	       raid device, we shouldn't change it.  */
	    if (! pv->disk)
	      pv->disk = grub_disk_open (name);
	    break;
	  }
      }

  goto fail2;

  /* Failure path.  */
 fail4:
  grub_free (vg);
 fail3:
  grub_free (vgname);

  /* Normal exit path.  */
 fail2:
  grub_free (metadatabuf);
 fail:
  grub_disk_close (disk);
  return 0;
}

static struct grub_disk_dev grub_lvm_dev =
  {
    .name = "lvm",
    .id = GRUB_DISK_DEVICE_LVM_ID,
    .iterate = grub_lvm_iterate,
    .open = grub_lvm_open,
    .close = grub_lvm_close,
    .read = grub_lvm_read,
    .write = grub_lvm_write,
#ifdef GRUB_UTIL
    .memberlist = grub_lvm_memberlist,
#endif
    .next = 0
  };


GRUB_MOD_INIT(lvm)
{
  grub_device_iterate (&grub_lvm_scan_device);
  if (grub_errno)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
    }

  grub_disk_dev_register (&grub_lvm_dev);
}

GRUB_MOD_FINI(lvm)
{
  grub_disk_dev_unregister (&grub_lvm_dev);
  /* FIXME: free the lvm list. */
}
