]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/logformat.c
metadump/restore: don't use errno after fwrite/fread failures
[thirdparty/xfsprogs-dev.git] / db / logformat.c
CommitLineData
c7a8ea47
BF
1/*
2 * Copyright (c) 2015 Red Hat, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "libxfs.h"
20#include "command.h"
21#include "init.h"
22#include "output.h"
23#include "libxlog.h"
24
25#define MAX_LSUNIT 256 * 1024 /* max log buf. size */
26
27static int
28logformat_f(int argc, char **argv)
29{
30 xfs_daddr_t head_blk;
31 xfs_daddr_t tail_blk;
32 int logversion;
33 int lsunit = -1;
34 int cycle = -1;
35 int error;
36 int c;
37
38 logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1;
39
40 while ((c = getopt(argc, argv, "c:s:")) != EOF) {
41 switch (c) {
42 case 'c':
43 cycle = strtol(optarg, NULL, 0);
44 if (cycle == 0) {
45 dbprintf("invalid cycle\n");
46 return -1;
47 }
48 break;
49 case 's':
50 lsunit = strtol(optarg, NULL, 0);
51 /*
52 * The log stripe unit must be block aligned and no
53 * larger than 256k.
54 */
55 if (lsunit > 1 &&
56 (lsunit % mp->m_sb.sb_blocksize ||
57 (logversion == 2 && lsunit > MAX_LSUNIT))) {
58 dbprintf("invalid log stripe unit\n");
59 return -1;
60 }
61 break;
62 default:
63 dbprintf("invalid option\n");
64 return -1;
65 }
66 }
67
68 /*
69 * Check whether the log is dirty. This also determines the current log
70 * cycle if we have to use it by default below.
71 */
72 memset(mp->m_log, 0, sizeof(struct xlog));
73 mp->m_log->l_mp = mp;
74 mp->m_log->l_dev = mp->m_logdev_targp;
75 mp->m_log->l_logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
76 mp->m_log->l_logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
77 mp->m_log->l_sectBBsize = BBSIZE;
78 if (xfs_sb_version_hassector(&mp->m_sb))
79 mp->m_log->l_sectBBsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);
80 mp->m_log->l_sectBBsize = BTOBB(mp->m_log->l_sectBBsize);
81
82 error = xlog_find_tail(mp->m_log, &head_blk, &tail_blk);
83 if (error) {
84 dbprintf("could not find log head/tail\n");
85 return -1;
86 }
87 if (head_blk != tail_blk) {
88 dbprintf(_(
89 "The log is dirty. Please mount to replay the log.\n"));
90 return -1;
91 }
92
93 /*
94 * Use the current cycle and/or log stripe unit if either is not
95 * provided by the user.
96 */
97 if (cycle < 0)
98 cycle = mp->m_log->l_curr_cycle;
99 if (lsunit < 0)
100 lsunit = mp->m_sb.sb_logsunit;
101
102 dbprintf("Formatting the log to cycle %d, stripe unit %d bytes.\n",
103 cycle, lsunit);
e2f60652 104 error = -libxfs_log_clear(mp->m_logdev_targp, NULL,
c7a8ea47
BF
105 mp->m_log->l_logBBstart,
106 mp->m_log->l_logBBsize,
107 &mp->m_sb.sb_uuid, logversion, lsunit,
108 XLOG_FMT, cycle, false);
109 if (error) {
110 dbprintf("error formatting log - %d\n", error);
111 return error;
112 }
113
114 return 0;
115}
116
117static void
118logformat_help(void)
119{
120 dbprintf(_(
121"\n"
122" The 'logformat' command reformats (clears) the log to the specified log\n"
123" cycle and log stripe unit. If the log cycle is not specified, the log is\n"
124" reformatted to the current cycle. If the log stripe unit is not specified,\n"
125" the stripe unit from the filesystem superblock is used.\n"
126"\n"
127 ));
128}
129
130static const struct cmdinfo logformat_cmd = {
131 .name = "logformat",
132 .altname = NULL,
133 .cfunc = logformat_f,
134 .argmin = 0,
135 .argmax = 4,
136 .canpush = 0,
137 .args = N_("[-c cycle] [-s sunit]"),
138 .oneline = N_("reformat the log"),
139 .help = logformat_help,
140};
141
142void
143logformat_init(void)
144{
145 if (!expert_mode)
146 return;
147
148 add_command(&logformat_cmd);
149}
ad9ac929
DW
150
151static void
152print_logres(
153 int i,
154 struct xfs_trans_res *res)
155{
156 dbprintf(_("type %d logres %u logcount %d flags 0x%x\n"),
157 i, res->tr_logres, res->tr_logcount, res->tr_logflags);
158}
159
160int
161logres_f(
162 int argc,
163 char **argv)
164{
165 struct xfs_trans_res resv;
166 struct xfs_trans_res *res;
167 struct xfs_trans_res *end_res;
168 int i;
169
170 res = (struct xfs_trans_res *)M_RES(mp);
171 end_res = (struct xfs_trans_res *)(M_RES(mp) + 1);
172 for (i = 0; res < end_res; i++, res++)
173 print_logres(i, res);
174 libxfs_log_get_max_trans_res(mp, &resv);
175 print_logres(-1, &resv);
176
177 return 0;
178}
179
180static void
181logres_help(void)
182{
183 dbprintf(_(
184"\n"
185" The 'logres' command prints information about all log reservation types.\n"
186" This includes the reservation space, the intended transaction roll count,\n"
187" and the reservation flags, if any.\n"
188"\n"
189 ));
190}
191
192static const struct cmdinfo logres_cmd = {
193 .name = "logres",
194 .altname = NULL,
195 .cfunc = logres_f,
196 .argmin = 0,
197 .argmax = 0,
198 .canpush = 0,
199 .args = NULL,
200 .oneline = N_("dump log reservations"),
201 .help = logres_help,
202};
203
204void
205logres_init(void)
206{
207 add_command(&logres_cmd);
208}