예제 #1
0
파일: ext2.c 프로젝트: will-Do/libguestfs
int64_t
ext_minimum_size (const char *device)
{
    CLEANUP_FREE char *err = NULL, *out = NULL;
    CLEANUP_FREE_STRING_LIST char **lines = NULL;
    int r;
    size_t i;
    int64_t ret;
    long block_size;
    const char *pattern = "Estimated minimum size of the filesystem: ";

    r = command (&out, &err, str_resize2fs, "-P", "-f", device, NULL);
    if (r == -1) {
        reply_with_error ("%s", err);
        return -1;
    }

    lines = split_lines (out);
    if (lines == NULL)
        return -1;

#if __WORDSIZE == 64
#define XSTRTOD64 xstrtol
#else
#define XSTRTOD64 xstrtoll
#endif

    for (i = 0; lines[i] != NULL; ++i) {
        if (STRPREFIX (lines[i], pattern)) {
            if (XSTRTOD64 (lines[i] + strlen (pattern),
                           NULL, 10, &ret, NULL) != LONGINT_OK) {
                reply_with_error ("cannot parse minimum size");
                return -1;
            }
            if ((block_size = get_block_size (device)) == -1)
                return -1;
            if (verbose) {
                fprintf (stderr, "Minimum size in blocks: %" SCNd64 \
                         "\nBlock count: %ld\n", ret, block_size);
            }
            if (INT64_MAX / block_size < ret) {
                reply_with_error ("filesystem size too big: overflow");
                return -1;
            }
            return ret * block_size;
        }
    }

#undef XSTRTOD64

    reply_with_error ("minimum size not found. Check output format:\n%s", out);
    return -1;
}
예제 #2
0
int64_t
ntfs_minimum_size (const char *device)
{
  CLEANUP_FREE char *err = NULL, *out = NULL;
  CLEANUP_FREE_STRING_LIST char **lines = NULL;
  int r;
  size_t i;
  int64_t volume_size = 0;
  const char *size_pattern = "You might resize at ",
             *full_pattern = "Volume is full",
             *cluster_size_pattern = "Cluster size",
             *volume_size_pattern = "Current volume size:";
  int is_full = 0;
  int32_t cluster_size = 0;

  /* FS may be marked for check, so force ntfsresize */
  r = command (&out, &err, str_ntfsresize, "--info", "-ff", device, NULL);

  lines = split_lines (out);
  if (lines == NULL)
    return -1;

  if (verbose) {
    for (i = 0; lines[i] != NULL; ++i)
      fprintf (stderr, "ntfs_minimum_size: lines[%zu] = \"%s\"\n", i, lines[i]);
  }

#if __WORDSIZE == 64
#define XSTRTOD64 xstrtol
#else
#define XSTRTOD64 xstrtoll
#endif

  if (r == -1) {
    /* If volume is full, ntfsresize returns error. */
    for (i = 0; lines[i] != NULL; ++i) {
      if (strstr (lines[i], full_pattern))
        is_full = 1;
      else if (STRPREFIX (lines[i], cluster_size_pattern)) {
        if (sscanf (lines[i] + strlen (cluster_size_pattern),
                    "%*[ ]:%" SCNd32, &cluster_size) != 1) {
          reply_with_error ("cannot parse cluster size");
          return -1;
        }
      }
      else if (STRPREFIX (lines[i], volume_size_pattern)) {
        if (XSTRTOD64 (lines[i] + strlen (volume_size_pattern),
                       NULL, 10, &volume_size, NULL) != LONGINT_OK) {
          reply_with_error ("cannot parse volume size");
          return -1;
        }
      }
    }
    if (is_full) {
      if (cluster_size == 0) {
        reply_with_error ("bad cluster size");
        return -1;
      }
      /* In case of a full filesystem, we estimate minimum size
       * as volume size rounded up to cluster size.
       */
      return (volume_size + cluster_size - 1) / cluster_size * cluster_size;
    }

    reply_with_error ("%s", err);
    return -1;
  }

  for (i = 0; lines[i] != NULL; ++i) {
    if (STRPREFIX (lines[i], size_pattern)) {
      int64_t ret;
      if (XSTRTOD64 (lines[i] + strlen (size_pattern),
                     NULL, 10, &ret, NULL) != LONGINT_OK) {
        reply_with_error ("cannot parse minimum size");
        return -1;
      }
      return ret;
    }
  }

#undef XSTRTOD64

  reply_with_error ("minimum size not found. Check output format:\n%s", out);
  return -1;
}