1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
9 * loggen: Generate log entries. Very much incomplete. The empty log
10 * record is a bit of a misnomer since we need to jump through
11 * hoops to get a log record that parses ok yet does nothing.
18 #include <xfs/libxfs.h>
19 #ifdef HAVE_XFS_XFS_LOG_FORMAT_H
20 #include <xfs/xfs_log_format.h>
21 #define XFS_TRANS_MAGIC XFS_TRANS_HEADER_MAGIC
22 #else /* HAVE_XFS_XFS_LOG_FORMAT_H */
23 #include <xfs/xfs_log.h>
24 #include <xfs/xfs_log_priv.h>
25 #endif /* HAVE_XFS_XFS_LOG_FORMAT_H */
27 #ifndef ASSIGN_ANY_LSN_DISK
28 #define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \
30 INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
31 INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
38 fprintf(stderr,"Usage: loggen\n"
39 " set up parameters before writing record(s):\n"
40 " -f f - set format\n"
44 " -C c - set tail cycle\n"
45 " -B b - set tail block\n"
46 " write log record(s):\n"
47 " -z n - write n zero block(s) (1BB)\n"
48 " -e n - write n empty record(s) (2BB)\n"
49 " -m n - write n unmount record(s) (2BB)\n"
51 " redirect stdout to external log partition, or pipe to\n"
52 " dd with appropriate parameters to stuff into internal log.\n"
61 int param_tail_cycle = 1;
62 int param_tail_block = 0;
63 int param_fmt = XLOG_FMT;
64 uuid_t param_uuid = {0};
67 loggen_alloc(int blocks)
69 if (!(buf=realloc(buf, blocks*BBSIZE))) {
70 fprintf(stderr,"failed to allocate %d block(s)\n", blocks);
73 memset(buf, 0, blocks*BBSIZE);
81 fprintf(stderr,"no buffer allocated\n");
85 if (fwrite(buf, BBSIZE, bufblocks, stdout) != bufblocks) {
93 loggen_zero(int count)
97 fprintf(stderr," *** zero block (1BB) x %d\n", count);
104 loggen_unmount(int count)
106 xlog_rec_header_t *head;
107 xlog_op_header_t *op;
108 /* the data section must be 32 bit size aligned */
112 uint32_t pad2; /* may as well make it 64 bits */
113 } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
117 fprintf(stderr," *** unmount record (2BB) x %d\n", count);
120 head = (xlog_rec_header_t *)buf;
121 op = (xlog_op_header_t *)(((char*)buf)+BBSIZE);
123 /* note that oh_tid actually contains the cycle number
124 * and the tid is stored in h_cycle_data[0] - that's the
125 * way things end up on disk.
128 head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
129 head->h_cycle = cpu_to_be32(param_cycle);
130 head->h_version = cpu_to_be32(1);
131 head->h_len = cpu_to_be32(20);
132 head->h_prev_block = cpu_to_be32(-1);
133 head->h_num_logops = cpu_to_be32(1);
134 head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0);
135 head->h_fmt = cpu_to_be32(param_fmt);
137 head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(param_tail_cycle,
140 memcpy(head->h_fs_uuid, param_uuid, sizeof(uuid_t));
142 /* now a log unmount op */
143 op->oh_tid = cpu_to_be32(param_cycle);
144 op->oh_len = cpu_to_be32(sizeof(magic));
145 op->oh_clientid = XFS_LOG;
146 op->oh_flags = XLOG_UNMOUNT_TRANS;
147 op->oh_res2 = cpu_to_be16(0);
149 /* and the data for this op */
151 memcpy(op+1, &magic, sizeof(magic));
154 head->h_lsn = cpu_to_be64(xlog_assign_lsn(param_cycle, param_block++));
161 loggen_empty(int count)
163 xlog_rec_header_t *head;
164 xlog_op_header_t *op1, *op2, *op3, *op4, *op5;
165 xfs_trans_header_t *trans;
166 xfs_buf_log_format_t blfs;
167 xfs_buf_log_format_t *blf;
173 fprintf(stderr," *** empty record (2BB) x %d\n", count);
177 head = (xlog_rec_header_t *)p; p+=BBSIZE;
178 op1 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
179 op2 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
180 trans = (xfs_trans_header_t *)p; p+=sizeof(xfs_trans_header_t);
181 op3 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
182 blf = (xfs_buf_log_format_t*)p; p+=sizeof(xfs_buf_log_format_t);
183 op4 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
184 data = (int *)p; p+=sizeof(int);
185 op5 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
187 /* note that oh_tid actually contains the cycle number
188 * and the tid is stored in h_cycle_data[0] - that's the
189 * way things end up on disk.
192 head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
193 head->h_cycle = cpu_to_be32(param_cycle);
194 head->h_version = cpu_to_be32(1);
195 head->h_len = cpu_to_be32(5*sizeof(xlog_op_header_t) +
196 sizeof(xfs_trans_header_t)+
197 sizeof(xfs_buf_log_format_t)+
199 head->h_prev_block = cpu_to_be32(-1);
200 head->h_num_logops = cpu_to_be32(5);
201 head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0);
202 head->h_fmt = cpu_to_be32(param_fmt);
204 head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(param_tail_cycle,
207 memcpy(head->h_fs_uuid, param_uuid, sizeof(uuid_t));
210 op1->oh_tid = cpu_to_be32(1);
211 op1->oh_len = cpu_to_be32(0);
212 op1->oh_clientid = XFS_TRANSACTION;
213 op1->oh_flags = XLOG_START_TRANS;
214 op1->oh_res2 = cpu_to_be16(0);
216 op2->oh_tid = cpu_to_be32(0xb0c0d0d0);
217 op2->oh_len = cpu_to_be32(sizeof(xfs_trans_header_t));
218 op2->oh_clientid = XFS_TRANSACTION;
220 op2->oh_res2 = cpu_to_be16(0);
221 /* dummy transaction - this stuff doesn't get endian converted */
222 trans->th_magic = XFS_TRANS_MAGIC;
223 trans->th_type = XFS_TRANS_DUMMY1;
225 trans->th_num_items = 1;
227 op3->oh_tid = cpu_to_be32(0xb0c0d0d0);
228 op3->oh_len = cpu_to_be32(sizeof(xfs_buf_log_format_t));
229 op3->oh_clientid = XFS_TRANSACTION;
231 op3->oh_res2 = cpu_to_be16(0);
232 /* an empty buffer too */
233 blfs.blf_type = XFS_LI_BUF;
235 #ifdef XFS_BLF_CANCEL
236 blfs.blf_flags = XFS_BLF_CANCEL;
238 blfs.blf_flags = XFS_BLI_CANCEL;
242 blfs.blf_map_size = 1;
243 blfs.blf_data_map[0]= 0;
244 memcpy(blf, &blfs, sizeof(blfs));
246 op4->oh_tid = cpu_to_be32(0xb0c0d0d0);
247 op4->oh_len = cpu_to_be32(sizeof(int));
248 op4->oh_clientid = XFS_TRANSACTION;
250 op4->oh_res2 = cpu_to_be16(0);
252 *data=*(int*)(char*)"FISH"; /* this won't get written (I hope) */
254 op5->oh_tid = cpu_to_be32(0xb0c0d0d0);
255 op5->oh_len = cpu_to_be32(0);
256 op5->oh_clientid = XFS_TRANSACTION;
257 op5->oh_flags = XLOG_COMMIT_TRANS;
258 op5->oh_res2 = cpu_to_be16(0);
261 head->h_lsn = cpu_to_be64(xlog_assign_lsn(param_cycle, param_block++));
268 main(int argc, char *argv[])
272 fprintf(stderr,"*** loggen\n");
276 while ((c = getopt(argc, argv, "f:u:c:b:C:B:z:e:m:")) != -1) {
279 param_fmt=atoi(optarg);
282 memset(param_uuid, atoi(optarg), sizeof(param_uuid));
285 param_cycle=atoi(optarg);
288 param_block=atoi(optarg);
291 param_tail_cycle=atoi(optarg);
294 param_tail_block=atoi(optarg);
298 loggen_zero(atoi(optarg));
301 loggen_empty(atoi(optarg));
304 loggen_unmount(atoi(optarg));
308 fprintf(stderr, "unknown option\n");