Add the new logformat command to format the log to a specified log cycle and/or log stripe unit. This command is primarily for testing purposes and is only available in expert mode. Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- db/Makefile | 4 +- db/command.c | 2 + db/logformat.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ db/logformat.h | 19 ++++++++ 4 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 db/logformat.c create mode 100644 db/logformat.h diff --git a/db/Makefile b/db/Makefile index fb01bdd..8260da3 100644 --- a/db/Makefile +++ b/db/Makefile @@ -11,8 +11,8 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ btblock.h bmroot.h check.h command.h convert.h debug.h \ dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ - io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ - text.h type.h write.h attrset.h symlink.h + io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \ + sig.h strvec.h text.h type.h write.h attrset.h symlink.h CFILES = $(HFILES:.h=.c) LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh diff --git a/db/command.c b/db/command.c index 2189e00..3c17a1e 100644 --- a/db/command.c +++ b/db/command.c @@ -40,6 +40,7 @@ #include "inode.h" #include "input.h" #include "io.h" +#include "logformat.h" #include "metadump.h" #include "output.h" #include "print.h" @@ -131,6 +132,7 @@ init_commands(void) hash_init(); inode_init(); input_init(); + logformat_init(); io_init(); metadump_init(); output_init(); diff --git a/db/logformat.c b/db/logformat.c new file mode 100644 index 0000000..254f33d --- /dev/null +++ b/db/logformat.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libxfs.h" +#include "command.h" +#include "init.h" +#include "output.h" +#include "libxlog.h" + +#define MAX_LSUNIT 256 * 1024 /* max log buf. size */ + +static int +logformat_f(int argc, char **argv) +{ + xfs_daddr_t head_blk; + xfs_daddr_t tail_blk; + int logversion; + int lsunit = -1; + int cycle = -1; + int error; + int c; + + logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1; + + while ((c = getopt(argc, argv, "c:s:")) != EOF) { + switch (c) { + case 'c': + cycle = strtol(optarg, NULL, 0); + if (cycle == 0) { + dbprintf("invalid cycle\n"); + return -1; + } + break; + case 's': + lsunit = strtol(optarg, NULL, 0); + /* + * The log stripe unit must be block aligned and no + * larger than 256k. + */ + if (lsunit > 1 && + (lsunit % mp->m_sb.sb_blocksize || + (logversion == 2 && lsunit > MAX_LSUNIT))) { + dbprintf("invalid log stripe unit\n"); + return -1; + } + break; + default: + dbprintf("invalid option\n"); + return -1; + } + } + + /* + * Check whether the log is dirty. This also determines the current log + * cycle if we have to use it by default below. + */ + memset(mp->m_log, 0, sizeof(struct xlog)); + mp->m_log->l_mp = mp; + mp->m_log->l_dev = mp->m_logdev_targp; + mp->m_log->l_logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + mp->m_log->l_logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + mp->m_log->l_sectBBsize = BBSIZE; + if (xfs_sb_version_hassector(&mp->m_sb)) + mp->m_log->l_sectBBsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); + mp->m_log->l_sectBBsize = BTOBB(mp->m_log->l_sectBBsize); + + error = xlog_find_tail(mp->m_log, &head_blk, &tail_blk); + if (error) { + dbprintf("could not find log head/tail\n"); + return -1; + } + if (head_blk != tail_blk) { + dbprintf(_( + "The log is dirty. Please mount to replay the log.\n")); + return -1; + } + + /* + * Use the current cycle and/or log stripe unit if either is not + * provided by the user. + */ + if (cycle < 0) + cycle = mp->m_log->l_curr_cycle; + if (lsunit < 0) + lsunit = mp->m_sb.sb_logsunit; + + dbprintf("Formatting the log to cycle %d, stripe unit %d bytes.\n", + cycle, lsunit); + error = libxfs_log_clear(mp->m_logdev_targp, NULL, + mp->m_log->l_logBBstart, + mp->m_log->l_logBBsize, + &mp->m_sb.sb_uuid, logversion, lsunit, + XLOG_FMT, cycle, false); + if (error) { + dbprintf("error formatting log - %d\n", error); + return error; + } + + return 0; +} + +static void +logformat_help(void) +{ + dbprintf(_( +"\n" +" The 'logformat' command reformats (clears) the log to the specified log\n" +" cycle and log stripe unit. If the log cycle is not specified, the log is\n" +" reformatted to the current cycle. If the log stripe unit is not specified,\n" +" the stripe unit from the filesystem superblock is used.\n" +"\n" + )); +} + +static const struct cmdinfo logformat_cmd = { + .name = "logformat", + .altname = NULL, + .cfunc = logformat_f, + .argmin = 0, + .argmax = 4, + .canpush = 0, + .args = N_("[-c cycle] [-s sunit]"), + .oneline = N_("reformat the log"), + .help = logformat_help, +}; + +void +logformat_init(void) +{ + if (!expert_mode) + return; + + add_command(&logformat_cmd); +} diff --git a/db/logformat.h b/db/logformat.h new file mode 100644 index 0000000..f9763ee --- /dev/null +++ b/db/logformat.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +void logformat_init(void); -- 2.1.0 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs