From a7fbbf9124b6aa19f01624c958de1a7b21573d87 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 26 Jun 2008 04:07:57 +0000 Subject: [PATCH] HAMMER Utilities: Sync with 59A * Add mirror-read, mirror-write, and status directives. --- sbin/hammer/Makefile | 4 +- sbin/hammer/cmd_mirror.c | 252 +++++++++++++++++++++++++++ sbin/hammer/cmd_pseudofs.c | 3 +- sbin/hammer/cmd_reblock.c | 8 +- sbin/hammer/cmd_show.c | 14 +- sbin/hammer/cmd_softprune.c | 12 +- sbin/hammer/{cmd_pseudofs.c => cmd_status.c} | 11 +- sbin/hammer/cycle.c | 10 +- sbin/hammer/hammer.c | 21 ++- sbin/hammer/hammer.h | 10 +- sbin/hammer/hammer_util.h | 6 +- sbin/hammer/misc.c | 48 ++++- sbin/hammer/test_dupkey.c | 83 +++++++++ 13 files changed, 440 insertions(+), 42 deletions(-) create mode 100644 sbin/hammer/cmd_mirror.c copy sbin/hammer/{cmd_pseudofs.c => cmd_status.c} (87%) create mode 100644 sbin/hammer/test_dupkey.c diff --git a/sbin/hammer/Makefile b/sbin/hammer/Makefile index 046dfd6113..d1d24dd338 100644 --- a/sbin/hammer/Makefile +++ b/sbin/hammer/Makefile @@ -1,11 +1,11 @@ # -# $DragonFly: src/sbin/hammer/Makefile,v 1.16 2008/06/25 13:10:06 mneumann Exp $ +# $DragonFly: src/sbin/hammer/Makefile,v 1.17 2008/06/26 04:07:57 dillon Exp $ PROG= hammer SRCS= hammer.c ondisk.c blockmap.c cache.c misc.c cycle.c \ cmd_show.c cmd_softprune.c cmd_history.c \ cmd_blockmap.c cmd_reblock.c cmd_synctid.c cmd_stats.c \ - cmd_pseudofs.c cmd_snapshot.c + cmd_pseudofs.c cmd_snapshot.c cmd_mirror.c cmd_status.c MAN= hammer.8 CFLAGS+= -I${.CURDIR}/../../sys -DALIST_NO_DEBUG diff --git a/sbin/hammer/cmd_mirror.c b/sbin/hammer/cmd_mirror.c new file mode 100644 index 0000000000..5c3e5d224a --- /dev/null +++ b/sbin/hammer/cmd_mirror.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2008 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $DragonFly: src/sbin/hammer/cmd_mirror.c,v 1.1 2008/06/26 04:07:57 dillon Exp $ + */ + +#include "hammer.h" + +#define SERIALBUF_SIZE (512 * 1024) + +static int read_mrecords(int fd, char *buf, u_int size, + hammer_ioc_mrecord_t pickup); +static void mirror_usage(int code); + +void +hammer_cmd_mirror_read(char **av, int ac) +{ + struct hammer_ioc_mirror_rw mirror; + const char *filesystem; + char *buf = malloc(SERIALBUF_SIZE); + int fd; + hammer_tid_t tid; + + if (ac > 2) + mirror_usage(1); + filesystem = av[0]; + tid = 0; + if (ac == 2) + tid = strtoull(av[1], NULL, 0); + + bzero(&mirror, sizeof(mirror)); + hammer_key_beg_init(&mirror.key_beg); + hammer_key_end_init(&mirror.key_end); + + fd = open(filesystem, O_RDONLY); + if (fd < 0) + err(1, "Unable to open %s", filesystem); + + hammer_get_cycle(&mirror.key_beg); + + mirror.ubuf = buf; + mirror.size = SERIALBUF_SIZE; + mirror.tid_beg = tid; + mirror.tid_end = HAMMER_MAX_TID; + + do { + mirror.count = 0; + if (ioctl(fd, HAMMERIOC_MIRROR_READ, &mirror) < 0) { + fprintf(stderr, "Mirror-read %s failed: %s\n", + filesystem, strerror(errno)); + exit(1); + } + if (mirror.head.flags & HAMMER_IOC_HEAD_INTR) { + fprintf(stderr, + "Mirror-read %s interrupted by timer at" + " %016llx %08x\n", + filesystem, + mirror.key_cur.obj_id, + mirror.key_cur.localization); + if (CyclePath) + hammer_set_cycle(&mirror.key_cur); + exit(0); + } + mirror.key_beg = mirror.key_cur; + if (mirror.count) + write(1, mirror.ubuf, mirror.count); + } while (mirror.count != 0); + + if (CyclePath) + hammer_reset_cycle(); + fprintf(stderr, "Mirror-read %s succeeded\n", filesystem); +} + +void +hammer_cmd_mirror_write(char **av, int ac) +{ + struct hammer_ioc_mirror_rw mirror; + const char *filesystem; + char *buf = malloc(SERIALBUF_SIZE); + int fd; + struct hammer_ioc_mrecord pickup; + hammer_tid_t tid; + + if (ac > 2) + mirror_usage(1); + filesystem = av[0]; + tid = 0; + if (ac == 2) + tid = strtoull(av[1], NULL, 0); + + bzero(&mirror, sizeof(mirror)); + hammer_key_beg_init(&mirror.key_beg); + hammer_key_end_init(&mirror.key_end); + + fd = open(filesystem, O_RDONLY); + if (fd < 0) + err(1, "Unable to open %s", filesystem); + + mirror.ubuf = buf; + mirror.size = SERIALBUF_SIZE; + mirror.tid_beg = tid; + mirror.tid_end = HAMMER_MAX_TID; + + pickup.signature = 0; + + for (;;) { + mirror.count = 0; + mirror.size = read_mrecords(0, buf, SERIALBUF_SIZE, &pickup); + if (mirror.size <= 0) + break; + if (ioctl(fd, HAMMERIOC_MIRROR_WRITE, &mirror) < 0) { + fprintf(stderr, "Mirror-write %s failed: %s\n", + filesystem, strerror(errno)); + exit(1); + } + if (mirror.head.flags & HAMMER_IOC_HEAD_INTR) { + fprintf(stderr, + "Mirror-write %s interrupted by timer at" + " %016llx %08x\n", + filesystem, + mirror.key_cur.obj_id, + mirror.key_cur.localization); + exit(0); + } + mirror.key_beg = mirror.key_cur; + } + fprintf(stderr, "Mirror-write %s succeeded\n", filesystem); +} + +void +hammer_cmd_mirror_copy(char **av, int ac) +{ +} + +static int +read_mrecords(int fd, char *buf, u_int size, hammer_ioc_mrecord_t pickup) +{ + u_int count; + size_t n; + size_t i; + + count = 0; + while (size - count >= HAMMER_MREC_HEADSIZE) { + /* + * Cached the record header in case we run out of buffer + * space. + */ + if (pickup->signature == 0) { + for (n = 0; n < HAMMER_MREC_HEADSIZE; n += i) { + i = read(fd, (char *)pickup + n, + HAMMER_MREC_HEADSIZE - n); + if (i <= 0) + break; + } + if (n == 0) + break; + if (n != HAMMER_MREC_HEADSIZE) { + fprintf(stderr, "read_mrecords: short read on pipe\n"); + exit(1); + } + + if (pickup->signature != HAMMER_IOC_MIRROR_SIGNATURE) { + fprintf(stderr, "read_mrecords: malformed record on pipe, bad signature\n"); + exit(1); + } + if (pickup->rec_crc != crc32((char *)pickup + HAMMER_MREC_CRCOFF, HAMMER_MREC_HEADSIZE - HAMMER_MREC_CRCOFF)) { + fprintf(stderr, "read_mrecords: malformed record on pipe, bad crc\n"); + exit(1); + } + } + if (pickup->rec_size < HAMMER_MREC_HEADSIZE || + pickup->rec_size > HAMMER_MREC_HEADSIZE + HAMMER_XBUFSIZE) { + fprintf(stderr, "read_mrecords: malformed record on pipe, illegal rec_size\n"); + exit(1); + } + if (HAMMER_MREC_HEADSIZE + pickup->leaf.data_len > pickup->rec_size) { + fprintf(stderr, "read_mrecords: malformed record on pipe, illegal element data_len\n"); + exit(1); + } + + /* + * Stop if we have insufficient space for the record and data. + */ + if (size - count < pickup->rec_size) + break; + + /* + * Read the remainder and clear the pickup signature. + */ + bcopy(pickup, buf + count, HAMMER_MREC_HEADSIZE); + pickup->signature = 0; + for (n = HAMMER_MREC_HEADSIZE; n < pickup->rec_size; n += i) { + i = read(fd, buf + count + n, pickup->rec_size - n); + if (i <= 0) + break; + } + if (n != pickup->rec_size) { + fprintf(stderr, "read_mrecords: short read on pipe\n"); + exit(1); + } + if (pickup->leaf.data_len && pickup->leaf.data_offset) { + if (hammer_crc_test_leaf(buf + count + HAMMER_MREC_HEADSIZE, &pickup->leaf) == 0) { + fprintf(stderr, "read_mrecords: data_crc did not match data! obj=%016llx key=%016llx\n", pickup->leaf.base.obj_id, pickup->leaf.base.key); + fprintf(stderr, "continuing, but there are problems\n"); + } + } + + count += pickup->rec_size; + } + return(count); +} + +static void +mirror_usage(int code) +{ + fprintf(stderr, + "hammer mirror-read \n" + "hammer mirror-write \n" + "hammer mirror-copy [[user@]host:]fs [[user@]host:]fs\n" + ); + exit(code); +} diff --git a/sbin/hammer/cmd_pseudofs.c b/sbin/hammer/cmd_pseudofs.c index cdb8146706..c1a3f1ed58 100644 --- a/sbin/hammer/cmd_pseudofs.c +++ b/sbin/hammer/cmd_pseudofs.c @@ -31,11 +31,10 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_pseudofs.c,v 1.1 2008/06/23 07:37:54 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_pseudofs.c,v 1.2 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" -#include void hammer_cmd_pseudofs(char **av, int ac) diff --git a/sbin/hammer/cmd_reblock.c b/sbin/hammer/cmd_reblock.c index cd9e4ea79c..9e1f6be765 100644 --- a/sbin/hammer/cmd_reblock.c +++ b/sbin/hammer/cmd_reblock.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_reblock.c,v 1.8 2008/06/24 17:40:21 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_reblock.c,v 1.9 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" @@ -53,8 +53,7 @@ hammer_cmd_reblock(char **av, int ac, int flags) reblock.key_beg.localization = HAMMER_MIN_LOCALIZATION; reblock.key_beg.obj_id = HAMMER_MIN_OBJID; - hammer_get_cycle(&reblock.key_beg.obj_id, - &reblock.key_beg.localization); + hammer_get_cycle(&reblock.key_beg); reblock.key_end.localization = HAMMER_MAX_LOCALIZATION; reblock.key_end.obj_id = HAMMER_MAX_OBJID; @@ -105,8 +104,7 @@ hammer_cmd_reblock(char **av, int ac, int flags) reblock.key_cur.obj_id, reblock.key_cur.localization); if (CyclePath) { - hammer_set_cycle(reblock.key_cur.obj_id, - reblock.key_cur.localization); + hammer_set_cycle(&reblock.key_cur); } } else { if (CyclePath) diff --git a/sbin/hammer/cmd_show.c b/sbin/hammer/cmd_show.c index aef93d8edf..ecd6ea4585 100644 --- a/sbin/hammer/cmd_show.c +++ b/sbin/hammer/cmd_show.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_show.c,v 1.12 2008/05/18 01:49:41 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_show.c,v 1.13 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" @@ -93,13 +93,16 @@ print_btree_node(hammer_off_t node_offset, int depth, int spike, badc = 'B'; if (spike == 0) { - printf("%c NODE %016llx count=%d parent=%016llx " - "type=%c depth=%d fill=", + printf("%c NODE %016llx cnt=%d p=%016llx " + "type=%c depth=%d", badc, node_offset, node->count, node->parent, (node->type ? node->type : '?'), depth); - if (VerboseOpt) + printf(" mirror %016llx", node->mirror_tid); + if (VerboseOpt) { + printf(" fill="); print_bigblock_fill(node_offset); + } printf(" {\n"); maxcount = (node->type == HAMMER_BTREE_TYPE_INTERNAL) ? @@ -318,8 +321,9 @@ print_record(hammer_btree_elm_t elm) case HAMMER_RECTYPE_DIRENTRY: printf("\n%17s", ""); data_len -= HAMMER_ENTRY_NAME_OFF; - printf("dir-entry ino=%016llx name=\"%*.*s\"", + printf("dir-entry ino=%016llx lo=%08x name=\"%*.*s\"", data->entry.obj_id, + data->entry.localization, data_len, data_len, data->entry.name); break; case HAMMER_RECTYPE_FIX: diff --git a/sbin/hammer/cmd_softprune.c b/sbin/hammer/cmd_softprune.c index 298a78fac3..26c98ac945 100644 --- a/sbin/hammer/cmd_softprune.c +++ b/sbin/hammer/cmd_softprune.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_softprune.c,v 1.4 2008/06/24 17:40:21 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_softprune.c,v 1.5 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" @@ -81,8 +81,7 @@ hammer_cmd_softprune(char **av, int ac, int everything_opt) template.key_beg.obj_id = HAMMER_MIN_OBJID; template.key_end.localization = HAMMER_MAX_LOCALIZATION; template.key_end.obj_id = HAMMER_MAX_OBJID; - hammer_get_cycle(&template.key_end.obj_id, - &template.key_end.localization); + hammer_get_cycle(&template.key_end); template.stat_oldest_tid = HAMMER_MAX_TID; /* @@ -158,11 +157,8 @@ hammer_cmd_softprune(char **av, int ac, int everything_opt) scan->filesystem, scan->prune.key_cur.obj_id, scan->prune.key_cur.localization); - if (CyclePath) { - hammer_set_cycle( - scan->prune.key_cur.obj_id, - scan->prune.key_cur.localization); - } + if (CyclePath) + hammer_set_cycle(&scan->prune.key_cur); rcode = 0; } else { if (CyclePath) diff --git a/sbin/hammer/cmd_pseudofs.c b/sbin/hammer/cmd_status.c similarity index 87% copy from sbin/hammer/cmd_pseudofs.c copy to sbin/hammer/cmd_status.c index cdb8146706..40787a586f 100644 --- a/sbin/hammer/cmd_pseudofs.c +++ b/sbin/hammer/cmd_status.c @@ -31,28 +31,23 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cmd_pseudofs.c,v 1.1 2008/06/23 07:37:54 dillon Exp $ + * $DragonFly: src/sbin/hammer/cmd_status.c,v 1.1 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" -#include void -hammer_cmd_pseudofs(char **av, int ac) +hammer_cmd_status(char **av, int ac) { struct hammer_ioc_get_pseudofs pfs; int i; int fd; for (i = 0; i < ac; ++i) { - if (mknod(av[i], S_IFDIR|0777, 0) < 0) { - perror("mknod (create pseudofs):"); - exit(1); - } printf("%s\t", av[i]); fd = open(av[i], O_RDONLY); if (fd < 0 || ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) < 0) { - printf("Unable to verify pseudofs creation\n"); + printf("HAMMER ioctl failed\n"); } else { printf("Pseudo-fs #0x%08x\n", pfs.pseudoid); } diff --git a/sbin/hammer/cycle.c b/sbin/hammer/cycle.c index f6cb0c4635..3d5f0d4d01 100644 --- a/sbin/hammer/cycle.c +++ b/sbin/hammer/cycle.c @@ -31,18 +31,18 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/cycle.c,v 1.3 2008/05/18 01:49:41 dillon Exp $ + * $DragonFly: src/sbin/hammer/cycle.c,v 1.4 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" void -hammer_get_cycle(int64_t *obj_idp, uint32_t *localizationp) +hammer_get_cycle(hammer_base_elm_t base) { FILE *fp; if (CyclePath && (fp = fopen(CyclePath, "r")) != NULL) { - if (fscanf(fp, "%llx %x\n", obj_idp, localizationp) != 2) { + if (fscanf(fp, "%llx %x\n", &base->obj_id, &base->localization) != 2) { fprintf(stderr, "Warning: malformed cycle in %s\n", CyclePath); } @@ -51,12 +51,12 @@ hammer_get_cycle(int64_t *obj_idp, uint32_t *localizationp) } void -hammer_set_cycle(int64_t obj_id, uint32_t localization) +hammer_set_cycle(hammer_base_elm_t base) { FILE *fp; if ((fp = fopen(CyclePath, "w")) != NULL) { - fprintf(fp, "%016llx %08x\n", obj_id, localization); + fprintf(fp, "%016llx %08x\n", base->obj_id, base->localization); fclose(fp); } else { fprintf(stderr, "Warning: Unable to write to %s: %s\n", diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index 22be95f90c..58271b5890 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/hammer.c,v 1.26 2008/06/25 13:10:06 mneumann Exp $ + * $DragonFly: src/sbin/hammer/hammer.c,v 1.27 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" @@ -129,6 +129,10 @@ main(int ac, char **av) hammer_cmd_pseudofs(av + 1, ac - 1); exit(0); } + if (strcmp(av[0], "status") == 0) { + hammer_cmd_status(av + 1, ac - 1); + exit(0); + } if (strcmp(av[0], "prune") == 0) { hammer_cmd_softprune(av + 1, ac - 1, 0); exit(0); @@ -169,6 +173,17 @@ main(int ac, char **av) usage(1); exit(0); } + if (strncmp(av[0], "mirror", 6) == 0) { + if (strcmp(av[0], "mirror-read") == 0) + hammer_cmd_mirror_read(av + 1, ac - 1); + else if (strcmp(av[0], "mirror-write") == 0) + hammer_cmd_mirror_write(av + 1, ac - 1); + else if (strcmp(av[0], "mirror-copy") == 0) + hammer_cmd_mirror_copy(av + 1, ac - 1); + else + usage(1); + exit(0); + } uuid_name_lookup(&Hammer_FSType, "DragonFly HAMMER", &status); if (status != uuid_s_ok) { @@ -234,6 +249,10 @@ usage(int exit_code) "hammer snapshot []\n" "hammer bstats \n" "hammer iostats \n" + "hammer mirror-read \n" + "hammer mirror-write \n" + "hammer mirror-copy [[user@]host:]" + " [[user@]host:]\n" "hammer reblock[-btree/inodes/dirs/data] " " [pack%%]\n" "hammer pseudofs \n" diff --git a/sbin/hammer/hammer.h b/sbin/hammer/hammer.h index 379673cbff..7a69bd5c77 100644 --- a/sbin/hammer/hammer.h +++ b/sbin/hammer/hammer.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/hammer.h,v 1.18 2008/06/25 13:10:06 mneumann Exp $ + * $DragonFly: src/sbin/hammer/hammer.h,v 1.19 2008/06/26 04:07:57 dillon Exp $ */ #include @@ -69,13 +69,17 @@ void hammer_cmd_softprune(char **av, int ac, int everything_opt); void hammer_cmd_bstats(char **av, int ac); void hammer_cmd_iostats(char **av, int ac); void hammer_cmd_synctid(char **av, int ac); +void hammer_cmd_mirror_read(char **av, int ac); +void hammer_cmd_mirror_write(char **av, int ac); +void hammer_cmd_mirror_copy(char **av, int ac); void hammer_cmd_history(const char *offset_str, char **av, int ac); void hammer_cmd_blockmap(void); void hammer_cmd_reblock(char **av, int ac, int flags); void hammer_cmd_pseudofs(char **av, int ac); +void hammer_cmd_status(char **av, int ac); void hammer_cmd_snapshot(char **av, int ac); -void hammer_get_cycle(int64_t *obj_idp, uint32_t *localizationp); -void hammer_set_cycle(int64_t obj_id, uint32_t localization); +void hammer_get_cycle(hammer_base_elm_t base); +void hammer_set_cycle(hammer_base_elm_t base); void hammer_reset_cycle(void); diff --git a/sbin/hammer/hammer_util.h b/sbin/hammer/hammer_util.h index 71223dbecb..fb7b452ba3 100644 --- a/sbin/hammer/hammer_util.h +++ b/sbin/hammer/hammer_util.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/hammer_util.h,v 1.17 2008/06/17 04:03:38 dillon Exp $ + * $DragonFly: src/sbin/hammer/hammer_util.h,v 1.18 2008/06/26 04:07:57 dillon Exp $ */ #include @@ -131,7 +131,9 @@ void *alloc_data_element(hammer_off_t *offp, int32_t data_len, struct buffer_info **data_bufferp); int hammer_btree_cmp(hammer_base_elm_t key1, hammer_base_elm_t key2); - +void hammer_key_beg_init(hammer_base_elm_t base); +void hammer_key_end_init(hammer_base_elm_t base); +int hammer_crc_test_leaf(void *data, hammer_btree_leaf_elm_t leaf); void format_freemap(struct volume_info *root_vol, hammer_blockmap_t blockmap); int64_t initialize_freemap(struct volume_info *vol); diff --git a/sbin/hammer/misc.c b/sbin/hammer/misc.c index 5e1ab690fc..956cdc2a53 100644 --- a/sbin/hammer/misc.c +++ b/sbin/hammer/misc.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/hammer/misc.c,v 1.4 2008/06/14 01:44:11 dillon Exp $ + * $DragonFly: src/sbin/hammer/misc.c,v 1.5 2008/06/26 04:07:57 dillon Exp $ */ #include "hammer.h" @@ -84,3 +84,49 @@ hammer_btree_cmp(hammer_base_elm_t key1, hammer_base_elm_t key2) return(0); } +void +hammer_key_beg_init(hammer_base_elm_t base) +{ + bzero(base, sizeof(*base)); + + base->localization = HAMMER_MIN_LOCALIZATION; + base->obj_id = HAMMER_MIN_OBJID; + base->key = HAMMER_MIN_KEY; + base->create_tid = 1; + base->rec_type = HAMMER_MIN_RECTYPE; +} + +void +hammer_key_end_init(hammer_base_elm_t base) +{ + bzero(base, sizeof(*base)); + + base->localization = HAMMER_MAX_LOCALIZATION; + base->obj_id = HAMMER_MAX_OBJID; + base->key = HAMMER_MAX_KEY; + base->create_tid = HAMMER_MAX_TID; + base->rec_type = HAMMER_MAX_RECTYPE; +} + +int +hammer_crc_test_leaf(void *data, hammer_btree_leaf_elm_t leaf) +{ + hammer_crc_t crc; + + if (leaf->data_len == 0) { + crc = 0; + } else { + switch(leaf->base.rec_type) { + case HAMMER_RECTYPE_INODE: + if (leaf->data_len != sizeof(struct hammer_inode_data)) + return(0); + crc = crc32(data, HAMMER_INODE_CRCSIZE); + break; + default: + crc = crc32(data, leaf->data_len); + break; + } + } + return (leaf->data_crc == crc); +} + diff --git a/sbin/hammer/test_dupkey.c b/sbin/hammer/test_dupkey.c new file mode 100644 index 0000000000..56916f5fa2 --- /dev/null +++ b/sbin/hammer/test_dupkey.c @@ -0,0 +1,83 @@ +/* + * This is a really simple stupid standalone program which will find two + * filenames with the same CRC, used to test the directory iterator. + * + * cc -I /usr/src/sys test_dupkey.c /usr/src/sys/libkern/crc32.c -o test_dupkey + * + * $DragonFly: src/sbin/hammer/test_dupkey.c,v 1.1 2008/06/26 04:07:57 dillon Exp $ + */ + +#include +#include +#include +#include "hammer_util.h" + +static u_int32_t namekey(const char *name); +static void randomname(char *name); + +u_int32_t bitmap[0x80000000U / 32]; + +int +main(int ac, char **av) +{ + char name[32]; + u_int32_t key; + u_int32_t *ptr; + u_int32_t mask; + u_int32_t count; + u_int32_t saved; + + srandom(0); /* reproducable random sequence number */ + count = 0; + for (;;) { + randomname(name); + key = namekey(name); + ptr = &bitmap[key / 32]; + mask = 1 << (key & 31); + if (*ptr & mask) { + break; + } + *ptr |= mask; + ++count; + } + printf("duplicate found at count %d key %08x\n", count, key); + printf("'%s' and", name); + saved = key; + + srandom(0); + count = 0; + for (;;) { + randomname(name); + key = namekey(name); + if (saved == key) + break; + ++count; + } + printf(" '%s'\n", name); +} + +static +u_int32_t +namekey(const char *name) +{ + u_int32_t key; + + key = crc32(name, strlen(name)) & 0x7FFFFFFF; + if (key == 0) + key = 1; + return(key); +} + +static +void +randomname(char *name) +{ + int len = random() % 16 + 8; + int i; + + for (i = 0; i < len; ++i) + name[i] = random() % 26 + 'a'; + name[i] = 0; +} + + -- 2.11.4.GIT