Esempio n. 1
0
/* Convert a non-canonical LV path like /dev/mapper/vg-lv or /dev/dm-0
 * to a canonical one.
 *
 * This is harder than it should be.  A LV device like /dev/VG/LV is
 * really a symlink to a device-mapper device like /dev/dm-0.  However
 * at the device-mapper (kernel) level, nothing is really known about
 * LVM (a userspace concept).  Therefore we use a convoluted method to
 * determine this, by listing out known LVs and checking whether the
 * rdev (major/minor) of the device we are passed matches any of them.
 *
 * Note use of 'stat' instead of 'lstat' so that symlinks are fully
 * resolved.
 *
 * Returns:
 *   1  =  conversion was successful, path is an LV
 *         '*ret' is set to the updated path if 'ret' is non-NULL.
 *   0  =  path is not an LV
 *  -1  =  error, reply_with_* has been called
 *
 */
int
lv_canonical (const char *device, char **ret)
{
  struct stat stat1, stat2;

  int r = stat (device, &stat1);
  if (r == -1) {
    reply_with_perror ("stat: %s", device);
    return -1;
  }

  char **lvs = do_lvs ();
  if (lvs == NULL)
    return -1;

  size_t i;
  for (i = 0; lvs[i] != NULL; ++i) {
    r = stat (lvs[i], &stat2);
    if (r == -1) {
      reply_with_perror ("stat: %s", lvs[i]);
      free_strings (lvs);
      return -1;
    }
    if (stat1.st_rdev == stat2.st_rdev) { /* found it */
      if (ret) {
        *ret = strdup (lvs[i]);
        if (*ret == NULL) {
          reply_with_perror ("strdup");
          free_strings (lvs);
          return -1;
        }
      }
      free_strings (lvs);
      return 1;
    }
  }

  /* not found */
  free_strings (lvs);
  return 0;
}
Esempio n. 2
0
/* Super-dangerous command used for testing.  It removes all
 * LVs, VGs and PVs permanently.
 */
int
do_lvm_remove_all (void)
{
  size_t i;
  int r;

  {
    /* Remove LVs. */
    CLEANUP_FREE_STRING_LIST char **xs = do_lvs ();
    if (xs == NULL)
      return -1;

    for (i = 0; xs[i] != NULL; ++i) {
      CLEANUP_FREE char *err = NULL;

      /* Deactivate the LV first.  On Ubuntu, lvremove '-f' option
       * does not remove active LVs reliably.
       */
      (void) command (NULL, NULL, str_lvm, "lvchange", "-an", xs[i], NULL);
      udev_settle ();

      r = command (NULL, &err, str_lvm, "lvremove", "-f", xs[i], NULL);
      if (r == -1) {
        reply_with_error ("lvremove: %s: %s", xs[i], err);
        return -1;
      }
    }
  }

  {
    /* Remove VGs. */
    CLEANUP_FREE_STRING_LIST char **xs = do_vgs ();
    if (xs == NULL)
      return -1;

    for (i = 0; xs[i] != NULL; ++i) {
      CLEANUP_FREE char *err = NULL;

      /* Deactivate the VG first, see note above. */
      (void) command (NULL, NULL, str_lvm, "vgchange", "-an", xs[i], NULL);
      udev_settle ();

      r = command (NULL, &err, str_lvm, "vgremove", "-f", xs[i], NULL);
      if (r == -1) {
        reply_with_error ("vgremove: %s: %s", xs[i], err);
        return -1;
      }
    }
  }

  {
    /* Remove PVs. */
    CLEANUP_FREE_STRING_LIST char **xs = do_pvs ();
    if (xs == NULL)
      return -1;

    for (i = 0; xs[i] != NULL; ++i) {
      CLEANUP_FREE char *err = NULL;

      r = command (NULL, &err, str_lvm, "pvremove", "-f", xs[i], NULL);
      if (r == -1) {
        reply_with_error ("pvremove: %s: %s", xs[i], err);
        return -1;
      }
    }
  }

  udev_settle ();

  /* There, that was easy, sorry about your data. */
  return 0;
}
Esempio n. 3
0
/* Super-dangerous command used for testing.  It removes all
 * LVs, VGs and PVs permanently.
 */
int
do_lvm_remove_all (void)
{
  char **xs;
  int i, r;
  char *err;

  /* Remove LVs. */
  xs = do_lvs ();
  if (xs == NULL)
    return -1;

  for (i = 0; xs[i] != NULL; ++i) {
    /* Deactivate the LV first.  On Ubuntu, lvremove '-f' option
     * does not remove active LVs reliably.
     */
    (void) command (NULL, NULL, "lvm", "lvchange", "-an", xs[i], NULL);
    udev_settle ();

    r = command (NULL, &err, "lvm", "lvremove", "-f", xs[i], NULL);
    if (r == -1) {
      reply_with_error ("lvremove: %s: %s", xs[i], err);
      free (err);
      free_strings (xs);
      return -1;
    }
    free (err);
  }
  free_strings (xs);

  /* Remove VGs. */
  xs = do_vgs ();
  if (xs == NULL)
    return -1;

  for (i = 0; xs[i] != NULL; ++i) {
    /* Deactivate the VG first, see note above. */
    (void) command (NULL, NULL, "lvm", "vgchange", "-an", xs[i], NULL);
    udev_settle ();

    r = command (NULL, &err, "lvm", "vgremove", "-f", xs[i], NULL);
    if (r == -1) {
      reply_with_error ("vgremove: %s: %s", xs[i], err);
      free (err);
      free_strings (xs);
      return -1;
    }
    free (err);
  }
  free_strings (xs);

  /* Remove PVs. */
  xs = do_pvs ();
  if (xs == NULL)
    return -1;

  for (i = 0; xs[i] != NULL; ++i) {
    r = command (NULL, &err, "lvm", "pvremove", "-f", xs[i], NULL);
    if (r == -1) {
      reply_with_error ("pvremove: %s: %s", xs[i], err);
      free (err);
      free_strings (xs);
      return -1;
    }
    free (err);
  }
  free_strings (xs);

  udev_settle ();

  /* There, that was easy, sorry about your data. */
  return 0;
}