Beispiel #1
0
/* Typical crazy output from the xfs_info command:
 *
 * meta-data=/dev/sda1              isize=256    agcount=4, agsize=6392 blks
 *          =                       sectsz=512   attr=2
 *[         =                       crc=0                                    ]
 * data     =                       bsize=4096   blocks=25568, imaxpct=25
 *          =                       sunit=0      swidth=0 blks
 * naming   =version 2              bsize=4096   ascii-ci=0
 * log      =internal               bsize=4096   blocks=1200, version=2
 *          =                       sectsz=512   sunit=0 blks, lazy-count=1
 * realtime =none                   extsz=4096   blocks=0, rtextents=0
 *
 * [...] line only appears in Fedora >= 21
 *
 * We may need to revisit this parsing code if the output changes
 * in future.
 */
static guestfs_int_xfsinfo *
parse_xfs_info (char **lines)
{
  guestfs_int_xfsinfo *ret;
  CLEANUP_FREE char *section = NULL; /* first column, eg "meta-data", "data" */
  char *p;
  size_t i;

  ret = malloc (sizeof *ret);
  if (ret == NULL) {
    reply_with_error ("malloc");
    return NULL;
  }

  /* Initialize fields to NULL or -1 so the caller can tell which fields
   * were updated in the code below.
   */
  ret->xfs_mntpoint = NULL;
  ret->xfs_inodesize = -1;
  ret->xfs_agcount = -1;
  ret->xfs_agsize = -1;
  ret->xfs_sectsize = -1;
  ret->xfs_attr = -1;
  ret->xfs_blocksize = -1;
  ret->xfs_datablocks = -1;
  ret->xfs_imaxpct = -1;
  ret->xfs_sunit = -1;
  ret->xfs_swidth = -1;
  ret->xfs_dirversion = -1;
  ret->xfs_dirblocksize = -1;
  ret->xfs_cimode = -1;
  ret->xfs_logname = NULL;
  ret->xfs_logblocksize = -1;
  ret->xfs_logblocks = -1;
  ret->xfs_logversion = -1;
  ret->xfs_logsectsize = -1;
  ret->xfs_logsunit = -1;
  ret->xfs_lazycount = -1;
  ret->xfs_rtname = NULL;
  ret->xfs_rtextsize = -1;
  ret->xfs_rtblocks = -1;
  ret->xfs_rtextents = -1;

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

    if (c_isalpha (lines[i][0])) {
      free (section);
      section = split_strdup (lines[i]);
      if (!section) goto error;

      if (verbose)
	fprintf (stderr, "xfs_info: new section %s\n", section);
    }

    if ((p = strstr (lines[i], "meta-data="))) {
      ret->xfs_mntpoint = split_strdup (p + 10);
      if (ret->xfs_mntpoint == NULL) goto error;
    }
    if ((p = strstr (lines[i], "isize="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 6);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_inodesize, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "agcount="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_agcount, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "agsize="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_agsize, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "sectsz="))) {
      if (section) {
	CLEANUP_FREE char *buf = split_strdup (p + 7);
	if (buf == NULL) goto error;
	if (STREQ (section, "meta-data")) {
	  if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
	    goto error;
	} else if (STREQ (section, "log")) {
	  if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
	    goto error;
	}
      }
    }
    if ((p = strstr (lines[i], "attr="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 5);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_attr, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "bsize="))) {
      if (section) {
	CLEANUP_FREE char *buf = split_strdup (p + 6);
	if (buf == NULL) goto error;
	if (STREQ (section, "data")) {
	  if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
	    goto error;
	} else if (STREQ (section, "naming")) {
	  if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
	    goto error;
	} else if (STREQ (section, "log")) {
	  if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
	    goto error;
	}
      }
    }
    if ((p = strstr (lines[i], "blocks="))) {
      if (section) {
	CLEANUP_FREE char *buf = split_strdup (p + 7);
	if (buf == NULL) goto error;
	if (STREQ (section, "data")) {
	  if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
	    goto error;
	} else if (STREQ (section, "log")) {
	  if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
	    goto error;
	} else if (STREQ (section, "realtime")) {
	  if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
	    goto error;
	}
      }
    }
    if ((p = strstr (lines[i], "imaxpct="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "sunit="))) {
      if (section) {
	CLEANUP_FREE char *buf = split_strdup (p + 6);
	if (buf == NULL) goto error;
	if (STREQ (section, "data")) {
	  if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
	    goto error;
	} else if (STREQ (section, "log")) {
	  if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
	    goto error;
	}
      }
    }
    if ((p = strstr (lines[i], "swidth="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_swidth, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "naming   =version "))) {
      CLEANUP_FREE char *buf = split_strdup (p + 18);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_dirversion, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "ascii-ci="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 9);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_cimode, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "log      ="))) {
      ret->xfs_logname = split_strdup (p + 10);
      if (ret->xfs_logname == NULL) goto error;
    }
    if ((p = strstr (lines[i], "version="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_logversion, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "lazy-count="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 11);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_lazycount, buf) == -1)
        goto error;
    }
    if ((p = strstr (lines[i], "realtime ="))) {
      ret->xfs_rtname = split_strdup (p + 10);
      if (ret->xfs_rtname == NULL) goto error;
    }
    if ((p = strstr (lines[i], "rtextents="))) {
      CLEANUP_FREE char *buf = split_strdup (p + 10);
      if (buf == NULL) goto error;
      if (parse_uint64 (&ret->xfs_rtextents, buf) == -1)
        goto error;
    }
  }

  if (ret->xfs_mntpoint == NULL) {
    ret->xfs_mntpoint = strdup ("");
    if (ret->xfs_mntpoint == NULL) goto error;
  }
  if (ret->xfs_logname == NULL) {
    ret->xfs_logname = strdup ("");
    if (ret->xfs_logname == NULL) goto error;
  }
  if (ret->xfs_rtname == NULL) {
    ret->xfs_rtname = strdup ("");
    if (ret->xfs_rtname == NULL) goto error;
  }

  return ret;

 error:
  free (ret->xfs_mntpoint);
  free (ret->xfs_logname);
  free (ret->xfs_rtname);
  free (ret);
  return NULL;
}
Beispiel #2
0
/* Typical crazy output from the xfs_info command:
 *
 * meta-data=/dev/sda1              isize=256    agcount=4, agsize=6392 blks
 *          =                       sectsz=512   attr=2
 * data     =                       bsize=4096   blocks=25568, imaxpct=25
 *          =                       sunit=0      swidth=0 blks
 * naming   =version 2              bsize=4096   ascii-ci=0
 * log      =internal               bsize=4096   blocks=1200, version=2
 *          =                       sectsz=512   sunit=0 blks, lazy-count=1
 * realtime =none                   extsz=4096   blocks=0, rtextents=0
 *
 * We may need to revisit this parsing code if the output changes
 * in future.
 */
static guestfs_int_xfsinfo *
parse_xfs_info (char **lines)
{
  guestfs_int_xfsinfo *ret;
  char *buf = NULL, *p;
  size_t i;

  ret = malloc (sizeof *ret);
  if (ret == NULL) {
    reply_with_error ("malloc");
    return NULL;
  }

  /* Initialize fields to NULL or -1 so the caller can tell which fields
   * were updated in the code below.
   */
  ret->xfs_mntpoint = NULL;
  ret->xfs_inodesize = -1;
  ret->xfs_agcount = -1;
  ret->xfs_agsize = -1;
  ret->xfs_sectsize = -1;
  ret->xfs_attr = -1;
  ret->xfs_blocksize = -1;
  ret->xfs_datablocks = -1;
  ret->xfs_imaxpct = -1;
  ret->xfs_sunit = -1;
  ret->xfs_swidth = -1;
  ret->xfs_dirversion = -1;
  ret->xfs_dirblocksize = -1;
  ret->xfs_cimode = -1;
  ret->xfs_logname = NULL;
  ret->xfs_logblocksize = -1;
  ret->xfs_logblocks = -1;
  ret->xfs_logversion = -1;
  ret->xfs_logsectsize = -1;
  ret->xfs_logsunit = -1;
  ret->xfs_lazycount = -1;
  ret->xfs_rtname = NULL;
  ret->xfs_rtextsize = -1;
  ret->xfs_rtblocks = -1;
  ret->xfs_rtextents = -1;

  for (i = 0; lines[i] != NULL; ++i) {
    if ((p = strstr (lines[i], "meta-data="))) {
      ret->xfs_mntpoint = split_strdup (p + 10);
      if (ret->xfs_mntpoint == NULL) goto error;
    }
    if ((p = strstr (lines[i], "isize="))) {
      buf = split_strdup (p + 6);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_inodesize, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "agcount="))) {
      buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_agcount, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "agsize="))) {
      buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_agsize, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "sectsz="))) {
      buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (i == 1) {
        if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 6) {
        if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
          goto error;
        free (buf);
      } else goto error;
    }
    if ((p = strstr (lines[i], "attr="))) {
      buf = split_strdup (p + 5);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_attr, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "bsize="))) {
      buf = split_strdup (p + 6);
      if (buf == NULL) goto error;
      if (i == 2) {
        if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 4) {
        if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 5) {
        if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
          goto error;
        free (buf);
      } else goto error;
    }
    if ((p = strstr (lines[i], "blocks="))) {
      buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (i == 2) {
        if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 5) {
        if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 7) {
        if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
          goto error;
        free (buf);
      } else goto error;
    }
    if ((p = strstr (lines[i], "imaxpct="))) {
      buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "sunit="))) {
      buf = split_strdup (p + 6);
      if (buf == NULL) goto error;
      if (i == 3) {
        if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
          goto error;
        free (buf);
      } else if (i == 6) {
        if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
          goto error;
        free (buf);
      } else goto error;
    }
    if ((p = strstr (lines[i], "swidth="))) {
      buf = split_strdup (p + 7);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_swidth, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "naming   =version "))) {
      buf = split_strdup (p + 18);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_dirversion, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "ascii-ci="))) {
      buf = split_strdup (p + 9);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_cimode, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "log      ="))) {
      ret->xfs_logname = split_strdup (p + 10);
      if (ret->xfs_logname == NULL) goto error;
    }
    if ((p = strstr (lines[i], "version="))) {
      buf = split_strdup (p + 8);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_logversion, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "lazy-count="))) {
      buf = split_strdup (p + 11);
      if (buf == NULL) goto error;
      if (parse_uint32 (&ret->xfs_lazycount, buf) == -1)
        goto error;
      free (buf);
    }
    if ((p = strstr (lines[i], "realtime ="))) {
      ret->xfs_rtname = split_strdup (p + 10);
      if (ret->xfs_rtname == NULL) goto error;
    }
    if ((p = strstr (lines[i], "rtextents="))) {
      buf = split_strdup (p + 10);
      if (buf == NULL) goto error;
      if (parse_uint64 (&ret->xfs_rtextents, buf) == -1)
        goto error;
      free (buf);
    }
  }

  if (ret->xfs_mntpoint == NULL) {
    ret->xfs_mntpoint = strdup ("");
    if (ret->xfs_mntpoint == NULL) goto error;
  }
  if (ret->xfs_logname == NULL) {
    ret->xfs_logname = strdup ("");
    if (ret->xfs_logname == NULL) goto error;
  }
  if (ret->xfs_rtname == NULL) {
    ret->xfs_rtname = strdup ("");
    if (ret->xfs_rtname == NULL) goto error;
  }

  return ret;

error:
  free (buf);
  free (ret->xfs_mntpoint);
  free (ret->xfs_logname);
  free (ret->xfs_rtname);
  free (ret);
  return NULL;
}