/*
 *------------------------------------------------------------------
 * svmtool.c
 *
 * Copyright (c) 2009 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/fifo.h>
#include <vppinfra/time.h>
#include <vppinfra/mheap.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>

#include "svm.h"



/*
 * format_all_svm_regions
 * Maps / unmaps regions. Do NOT call from client code!
 */
u8 *
format_all_svm_regions (u8 * s, va_list * args)
{
  int verbose = va_arg (*args, int);
  svm_region_t *root_rp = svm_get_root_rp ();
  svm_main_region_t *mp;
  svm_subregion_t *subp;
  svm_region_t *rp;
  svm_map_region_args_t *a = 0;
  u8 **svm_names = 0;
  u8 *name = 0;
  int i;

  ASSERT (root_rp);

  pthread_mutex_lock (&root_rp->mutex);

  s = format (s, "%U", format_svm_region, root_rp, verbose);

  mp = root_rp->data_base;

  /*
   * Snapshoot names, can't hold root rp mutex across
   * find_or_create.
   */
  /* *INDENT-OFF* */
  pool_foreach (subp, mp->subregions, ({
        name = vec_dup (subp->subregion_name);
        vec_add1(svm_names, name);
      }));
  /* *INDENT-ON* */

  pthread_mutex_unlock (&root_rp->mutex);

  for (i = 0; i < vec_len (svm_names); i++)
    {
      vec_validate (a, 0);
      a->name = (char *) svm_names[i];
      rp = svm_region_find_or_create (a);
      if (rp)
	{
	  pthread_mutex_lock (&rp->mutex);
	  s = format (s, "%U", format_svm_region, rp, verbose);
	  pthread_mutex_unlock (&rp->mutex);
	  svm_region_unmap (rp);
	  vec_free (svm_names[i]);
	}
      vec_free (a);
    }
  vec_free (svm_names);
  return (s);
}

void
show (char *chroot_path, int verbose)
{
  svm_map_region_args_t *a = 0;

  vec_validate (a, 0);

  svm_region_init_chroot (chroot_path);

  fformat (stdout, "My pid is %d\n", getpid ());

  fformat (stdout, "%U", format_all_svm_regions, verbose);

  svm_region_exit ();

  vec_free (a);
}


static void *
svm_map_region_nolock (svm_map_region_args_t * a)
{
  int svm_fd;
  svm_region_t *rp;
  int deadman = 0;
  u8 *shm_name;

  ASSERT ((a->size & ~(MMAP_PAGESIZE - 1)) == a->size);

  shm_name = shm_name_from_svm_map_region_args (a);

  svm_fd = shm_open ((char *) shm_name, O_RDWR, 0777);

  if (svm_fd < 0)
    {
      perror ("svm_region_map(mmap open)");
      return (0);
    }
  vec_free (shm_name);

  rp = mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, svm_fd, 0);

  if (rp == (svm_region_t *) MAP_FAILED)
    {
      close (svm_fd);
      clib_warning ("mmap");
      return (0);
    }
  /*
   * We lost the footrace to create this region; make sure
   * the winner has crossed the finish line.
   */
  while (rp->version == 0 && deadman++ < 5)
    {
      sleep (1);
    }

  /*
   * <bleep>-ed?
   */
  if (rp->version == 0)
    {
      clib_warning ("rp->version %d not %d", rp->version, SVM_VERSION);
      munmap (rp, MMAP_PAGESIZE);
      return (0);
    }
  /* Remap now that the region has been placed */
  a->baseva = rp->virtual_base;
  a->size = rp->virtual_size;
  munmap (rp, MMAP_PAGESIZE);

  rp = (void *) mmap ((void *) a->baseva, a->size,
		      PROT_READ | PROT_WRITE,
		      MAP_SHARED | MAP_FIXED, svm_fd, 0);
  if ((uword) rp == (uword) MAP_FAILED)
    {
      clib_unix_warning ("mmap");
      return (0);
    }

  if ((uword) rp != rp->virtual_base)
    {
      clib_warning ("mmap botch");
    }

  if (pthread_mutex_trylock (&rp->mutex))
    {
      clib_warning ("rp->mutex LOCKED by pid %d, tag %d, cleared...",
		    rp->mutex_owner_pid, rp->mutex_owner_tag);
      memset (&rp->mutex, 0, sizeof (rp->mutex));

    }
  else
    {
      clib_warning ("mutex OK...\n");
      pthread_mutex_unlock (&rp->mutex);
    }

  return ((void *) rp);
}

/*
 * rnd_pagesize
 * Round to a pagesize multiple, presumably 4k works
 */
static unsigned int
rnd_pagesize (unsigned int size)
{
  unsigned int rv;

  rv = (size + (MMAP_PAGESIZE - 1)) & ~(MMAP_PAGESIZE - 1);
  return (rv);
}

#define MUTEX_DEBUG

always_inline void
region_lock (svm_region_t * rp, int tag)
{
  pthread_mutex_lock (&rp->mutex);
#ifdef MUTEX_DEBUG
  rp->mutex_owner_pid = getpid ();
  rp->mutex_owner_tag = tag;
#endif
}

always_inline void
region_unlock (svm_region_t * rp)
{
#ifdef MUTEX_DEBUG
  rp->mutex_owner_pid = 0;
  rp->mutex_owner_tag = 0;
#endif
  pthread_mutex_unlock (&rp->mutex);
}


static void *
svm_existing_region_map_nolock (void *root_arg, svm_map_region_args_t * a)
{
  svm_region_t *root_rp = root_arg;
  svm_main_region_t *mp;
  svm_region_t *rp;
  void *oldheap;
  uword *p;

  a->size += MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE;
  a->size = rnd_pagesize (a->size);

  region_lock (root_rp, 4);
  oldheap = svm_push_pvt_heap (root_rp);
  mp = root_rp->data_base;

  ASSERT (mp);

  p = hash_get_mem (mp->name_hash, a->name);

  if (p)
    {
      rp = svm_map_region_nolock (a);
      region_unlock (root_rp);
      svm_pop_heap (oldheap);
      return rp;
    }
  return 0;

}

static void
trace (char *chroot_path, char *name, int enable_disable)
{
  svm_map_region_args_t *a = 0;
  svm_region_t *db_rp;
  void *oldheap;

  vec_validate (a, 0);

  svm_region_init_chroot (chroot_path);

  a->name = name;
  a->size = 1 << 20;
  a->flags = SVM_FLAGS_MHEAP;

  db_rp = svm_region_find_or_create (a);

  ASSERT (db_rp);

  region_lock (db_rp, 20);

  oldheap = svm_push_data_heap (db_rp);

  mheap_trace (db_rp->data_heap, enable_disable);

  svm_pop_heap (oldheap);
  region_unlock (db_rp);

  svm_region_unmap ((void *) db_rp);
  svm_region_exit ();
  vec_free (a);
}



static void
subregion_repair (char *chroot_path)
{
  int i;
  svm_main_region_t *mp;
  svm_map_region_args_t a;
  svm_region_t *root_rp;
  svm_region_t *rp;
  svm_subregion_t *subp;
  u8 *name = 0;
  u8 **svm_names = 0;

  svm_region_init_chroot (chroot_path);
  root_rp = svm_get_root_rp ();

  pthread_mutex_lock (&root_rp->mutex);

  mp = root_rp->data_base;

  /*
   * Snapshoot names, can't hold root rp mutex across
   * find_or_create.
   */
  /* *INDENT-OFF* */
  pool_foreach (subp, mp->subregions, ({
        name = vec_dup (subp->subregion_name);
        vec_add1(svm_names, name);
      }));
  /* *INDENT-ON* */

  pthread_mutex_unlock (&root_rp->mutex);

  for (i = 0; i < vec_len (svm_names); i++)
    {
      memset (&a, 0, sizeof (a));
      a.root_path = chroot_path;
      a.name = (char *) svm_names[i];
      fformat (stdout, "Checking %s region...\n", a.name);
      rp = svm_existing_region_map_nolock (root_rp, &a);
      if (rp)
	{
	  svm_region_unmap (rp);
	  vec_free (svm_names[i]);
	}
    }
  vec_free (svm_names);
}

void
repair (char *chroot_path, int crash_root_region)
{
  svm_region_t *root_rp = 0;
  svm_map_region_args_t *a = 0;
  void *svm_map_region (svm_map_region_args_t * a);
  int svm_fd;
  u8 *shm_name;

  fformat (stdout, "our pid: %d\n", getpid ());

  vec_validate (a, 0);

  a->root_path = chroot_path;
  a->name = SVM_GLOBAL_REGION_NAME;
  a->baseva = SVM_GLOBAL_REGION_BASEVA;
  a->size = SVM_GLOBAL_REGION_SIZE;
  a->flags = SVM_FLAGS_NODATA;

  shm_name = shm_name_from_svm_map_region_args (a);

  svm_fd = shm_open ((char *) shm_name, O_RDWR, 0777);

  if (svm_fd < 0)
    {
      perror ("svm_region_map(mmap open)");
      goto out;
    }

  vec_free (shm_name);

  root_rp = mmap (0, MMAP_PAGESIZE,
		  PROT_READ | PROT_WRITE, MAP_SHARED, svm_fd, 0);

  if (root_rp == (svm_region_t *) MAP_FAILED)
    {
      close (svm_fd);
      clib_warning ("mmap");
      goto out;
    }

  /* Remap now that the region has been placed */
  clib_warning ("remap to 0x%x", root_rp->virtual_base);

  a->baseva = root_rp->virtual_base;
  a->size = root_rp->virtual_size;
  munmap (root_rp, MMAP_PAGESIZE);

  root_rp = (void *) mmap ((void *) a->baseva, a->size,
			   PROT_READ | PROT_WRITE,
			   MAP_SHARED | MAP_FIXED, svm_fd, 0);
  if ((uword) root_rp == (uword) MAP_FAILED)
    {
      clib_unix_warning ("mmap");
      goto out;
    }

  close (svm_fd);

  if ((uword) root_rp != root_rp->virtual_base)
    {
      clib_warning ("mmap botch");
      goto out;
    }

  if (pthread_mutex_trylock (&root_rp->mutex))
    {
      clib_warning ("root_rp->mutex LOCKED by pid %d, tag %d, cleared...",
		    root_rp->mutex_owner_pid, root_rp->mutex_owner_tag);
      memset (&root_rp->mutex, 0, sizeof (root_rp->mutex));
      goto out;
    }
  else
    {
      clib_warning ("root_rp->mutex OK...\n");
      pthread_mutex_unlock (&root_rp->mutex);
    }

out:
  vec_free (a);
  /*
   * Now that the root region is known to be OK,
   * fix broken subregions
   */
  subregion_repair (chroot_path);

  if (crash_root_region)
    {
      clib_warning ("Leaving root region locked on purpose...");
      pthread_mutex_lock (&root_rp->mutex);
      root_rp->mutex_owner_pid = getpid ();
      root_rp->mutex_owner_tag = 99;
    }
  svm_region_exit ();
}

int
main (int argc, char **argv)
{
  unformat_input_t input;
  int parsed = 0;
  char *name;
  char *chroot_path = 0;
  u8 *chroot_u8;

  unformat_init_command_line (&input, argv);

  while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (&input, "show-verbose"))
	{
	  show (chroot_path, 1);
	  parsed++;
	}
      else if (unformat (&input, "show"))
	{
	  show (chroot_path, 0);
	  parsed++;
	}
      else if (unformat (&input, "client-scan"))
	{
	  svm_client_scan (chroot_path);
	  parsed++;
	}
      else if (unformat (&input, "repair"))
	{
	  repair (chroot_path, 0 /* fix it */ );
	  parsed++;
	}
      else if (unformat (&input, "crash"))
	{
	  repair (chroot_path, 1 /* crash it */ );
	  parsed++;
	}
      else if (unformat (&input, "trace-on %s", &name))
	{
	  trace (chroot_path, name, 1);
	  parsed++;
	}
      else if (unformat (&input, "trace-off %s", &name))
	{
	  trace (chroot_path, name, 0);
	  parsed++;
	}
      else if (unformat (&input, "chroot %s", &chroot_u8))
	{
	  chroot_path = (char *) chroot_u8;
	}
      else
	{
	  break;
	}
    }

  unformat_free (&input);

  if (!parsed)
    {
      fformat (stdout,
	       "%s: show | show-verbose | client-scan | trace-on <region-name>\n",
	       argv[0]);
      fformat (stdout, "      trace-off <region-name>\n");
    }
  exit (0);
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
