/* 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; }
/* 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; }