📄 dtutil.c
字号:
voidmySleep(unsigned int sleep_time){ if (micro_flag) { (void) usleep(sleep_time); } else { (void) sleep(sleep_time); } return;}/************************************************************************ * * * CalculateDumpSize() - Calculate the number of data bytes to dump. * * * * Description: * * For non-memory mapped files, we'll dump the pad bytes. These * * pad bytes do not exist for memory mapped files which are directly * * mapped to memory addresses. * * * * Inputs: size = The size of the buffer to dump. * * * * Outputs: Size of buffer to dump. * * * ************************************************************************/static size_tCalculateDumpSize (size_t size){ size_t dump_size = size; if (!mmap_flag) { dump_size += PADBUFR_SIZE; } if (dump_size > data_size) dump_size = data_size; return (dump_size);}/************************************************************************ * * * dump_buffer() Dump data buffer in hex bytes. * * * * Inputs: name = The buffer name being dumped. * * base = Base pointer of buffer to dump. * * ptr = Pointer into buffer being dumped. * * dump_size = The size of the buffer to dump. * * bufr_size = The maximum size of this buffer. * * expected = Boolean flag (True = Expected). * * * * Return Value: * * Void. * * * ************************************************************************/voiddump_buffer ( char *name, u_char *base, u_char *ptr, size_t dump_size, size_t bufr_size, bool expected ){ size_t i, limit, offset; u_int field_width = 16; u_char *bend = (base + bufr_size); u_char *bptr; /* * Since many requests do large transfers, limit data dumped. */ limit = (dump_size < dump_limit) ? dump_size : dump_limit; /* * Now to provide context, attempt to dump data on both sides of * the corrupted data, ensuring buffer limits are not exceeded. */ bptr = (ptr - (limit >> 1)); if (bptr < base) bptr = base; if ( (bptr + limit) > bend) { limit = (bend - bptr); /* Dump to end of buffer. */ } offset = (ptr - base); /* Offset to failing data. */ /* * NOTE: Rotate parameters are not displayed since we don't have * the base data address and can't use global due to AIO design. * [ if I get ambitious, I'll correct this in a future release. ] */ Fprintf ("The %scorrect data starts at address %#lx (marked by asterisk '*')\n", (expected) ? "" : "in", ptr); Fprintf ("Dumping %s Buffer (base = %#lx, offset = %u, limit = %u bytes):\n", name, base, offset, limit); LogMsg (efp, logLevelError, (PRT_NOIDENT | PRT_NOFLUSH), "\n"); for (i = 0; i < limit; i++, bptr++) { if ((i % field_width) == (size_t) 0) { if (i) fprintf (efp, "\n"); LogMsg (efp, logLevelError, (PRT_NOIDENT | PRT_NOFLUSH), "%#lx ", (u_long)bptr); } fprintf (efp, "%c%02x", (bptr == ptr) ? '*' : ' ', *bptr); } if (i) Fprint ("\n"); if (expected) { LogMsg (efp, logLevelError, (PRT_NOIDENT | PRT_NOFLUSH), "\n"); } (void)fflush(efp);}/************************************************************************ * * * fill_buffer() - Fill Buffer with a Data Pattern. * * * * Description: * * If a pattern_buffer exists, then this data is used to fill the * * buffer instead of the data pattern specified. * * * * Inputs: buffer = Pointer to buffer to fill. * * byte_count = Number of bytes to fill. * * pattern = Data pattern to fill buffer with. * * * * Return Value: * * Void. * * * ************************************************************************/voidfill_buffer ( u_char *buffer, size_t byte_count, u_int32 pattern){ register u_char *bptr = buffer; register u_char *pptr, *pend; register size_t bcount = byte_count; pptr = pattern_bufptr; pend = pattern_bufend; /* * Initialize the buffer with a data pattern. */ if ( !prefix_string ) { while (bcount--) { *bptr++ = *pptr++; if (pptr == pend) { pptr = pattern_buffer; } } } else { register size_t i; for (i = 0; i < bcount; ) { if ((i % lbdata_size) == 0) { size_t pcount = copy_prefix (bptr, (bcount - i)); i += pcount; bptr += pcount; continue; } *bptr++ = *pptr++; i++; if (pptr == pend) { pptr = pattern_buffer; } } } pattern_bufptr = pptr; return;}/************************************************************************ * * * init_buffer() - Initialize Buffer with a Data Pattern. * * * * Inputs: buffer = Pointer to buffer to init. * * count = Number of bytes to initialize. * * pattern = Data pattern to init buffer with. * * * * Return Value: * * Void. * * * ************************************************************************/voidinit_buffer ( u_char *buffer, size_t count, u_int32 pattern ){ register u_char *bptr; union { u_char pat[sizeof(u_int32)]; u_int32 pattern; } p; register size_t i; /* * Initialize the buffer with a data pattern. */ p.pattern = pattern; bptr = buffer; for (i = 0; i < count; i++) { *bptr++ = p.pat[i & (sizeof(u_int32) - 1)]; } return;}/************************************************************************ * * * init_lbdata() - Initialize Data Buffer with Logical Block Data. * * * * Description: * * This function takes the starting logical block address, and * * inserts it every logical block size bytes, overwriting the first 4 * * bytes of each logical block with its' address. * * * * Inputs: buffer = The data buffer to initialize. * * count = The data buffer size (in bytes). * * lba = The starting logical block address. * * lbsize = The logical block size (in bytes). * * * * Outputs: Returns the next lba to use. * * * ************************************************************************/u_int32init_lbdata ( u_char *buffer, size_t count, u_int32 lba, u_int32 lbsize ){ u_char *bptr = buffer; register ssize_t i; /* * Initialize the buffer with logical block data. */ if (prefix_string) { register size_t pcount = 0, scount = lbsize; /* * The lba is encoded after the prefix string. */ pcount = MIN(prefix_size, count); scount -= pcount; for (i = 0; (i+pcount+sizeof(lba)) < count; ) { bptr += pcount; htos (bptr, lba, sizeof(lba)); i += lbsize; bptr += scount; lba++; } } else { for (i = 0; (i+sizeof(lba)) < count; ) { htos (bptr, lba, sizeof(lba)); i += lbsize; bptr += lbsize; lba++; } } return (lba);}#if !defined(INLINE_FUNCS)/* * Calculate the starting logical block number. */u_int32make_lba( struct dinfo *dip, off_t pos ){ if (pos == (off_t) 0) { return ((u_int32) 0); } else { return (pos / lbdata_size); }}off_tmake_offset(struct dinfo *dip, u_int32 lba){ return ((off_t)(lba * lbdata_size));}/* * Calculate the starting lbdata block number. */u_int32make_lbdata( struct dinfo *dip, off_t pos ){ if (pos == (off_t) 0) { return ((u_int32) 0); } else { return (pos / lbdata_size); }}#endif /* !defined(INLINE_FUNCS) */u_int32winit_lbdata( struct dinfo *dip, off_t pos, u_char *buffer, size_t count, u_int32 lba, u_int32 lbsize ){ if (user_lbdata) { /* Using user defined lba, not file position! */ return (init_lbdata (buffer, count, lba, lbsize)); } else if (pos == (off_t) 0) { return (init_lbdata (buffer, count, (u_int32) 0, lbsize)); } else { return (init_lbdata (buffer, count, (pos / lbsize), lbsize)); }}/************************************************************************ * * * init_iotdata() - Initialize Data Buffer with IOT test pattern. * * * * Description: * * This function takes the starting logical block address, and * * inserts it every logical block size bytes. The data pattern used * * is the logical block with the constant 0x01010101 added every u_int. * * * * NOTE: The IOT pattern is stored in the pattern buffer, which * * is assumed to be page aligned, thus there are no alignment problems * * on Alpha/Mips. Remember, the data buffer may be unaligned :-) * * Note: Addition of prefix string changes this alignment assumption! * * * * This implementation does _not_ provide the "best" performance, * * but it does allow the normal 'dt' data flow to be mostly unaffected. * * * * Inputs: bcount = The data buffer size (in bytes). * * lba = The starting logical block address. * * lbsize = The logical block size (in bytes). * * * * Outputs: Returns the next lba to use. * * * ************************************************************************/u_int32init_iotdata ( size_t bcount, u_int32 lba, u_int32 lbsize ){ register size_t count = bcount; register u_int32 lba_pattern; int pcount = prefix_size; register int i; if (lbsize == 0) return (lba); pattern_bufptr = pattern_buffer; /* * If the prefix string is a multiple of an unsigned int, * we can initialize the buffer using 32-bit words, otherwise * we must do so a byte at a time which is slower (of course). * * Format: <prefix string><IOT pattern>... * */ if (prefix_string && (pcount & (sizeof(u_int32)-1)) ) { register u_char *bptr = pattern_buffer; /* * Initialize the buffer with the IOT test pattern. */ while ( ((ssize_t)count > 0) && (count >= sizeof(lba)) ) { lba_pattern = lba++; /* Start with logical block address. */ for (i = (lbsize - pcount); (i > 0); i -= sizeof(u_int32)) { int icount = MIN(i,sizeof(u_int32)); init_buffer(bptr, icount, lba_pattern); lba_pattern += 0x01010101; bptr += icount; } count -= lbsize; } } else { register int wperb; /* words per lbsize'ed buffer */ register u_int32 *bptr; wperb = (lbsize / sizeof(u_int32)); bptr = (u_int32 *)pattern_buffer; if (prefix_string) { /* * We leave room in each block for the prefix string. */ wperb -= (pcount / sizeof(u_int32)); count -= pcount; } bptr = (u_int32 *)pattern_buffer; pattern_bufptr = pattern_buffer; /* * Initialize the buffer with the IOT test pattern. */ while ( ((ssize_t)count > 0) && (count >= sizeof(lba)) ) { lba_pattern = lba++; /* Start with logical block address. */ for (i = 0; (i < wperb) && ((ssize_t)count > 0); i++) { *bptr++ = lba_pattern; lba_pattern += 0x01010101; count -= sizeof(u_int32); } } } return (lba);}/************************************************************************ * * * init_padbytes() - Initialize pad bytes at end of data buffer. * * * * Inputs: buffer = Pointer to start of data buffer. * * offset = Offset to where pad bytes start. * * pattern = Data pattern to init buffer with. * * * * Return Value: * * Void. * * * ************************************************************************/voidinit_padbytes ( u_char *buffer, size_t offset, u_int32 pattern ){ size_t i; u_char *bptr; union { u_char pat[sizeof(u_int32)]; u_int32 pattern; } p; p.pattern = pattern; bptr = buffer + offset; for (i = 0; i < PADBUFR_SIZE; i++) { *bptr++ = p.pat[i & (sizeof(u_int32) - 1)]; }}/* * copy_prefix() - Copy Prefix String to Buffer. * * Inputs: * buffer = Pointer to buffer to copy prefix. * bcount = Count of remaining buffer bytes. * * Implicit Inputs: * prefix_string = The prefix string. * prefix_size = The prefix size. * * Outputs: * buffer and bcount adjusted by the prefix size. * Returns number of prefix bytes copied. */size_tcopy_prefix( u_char *buffer, size_t bcount ){ size_t pcount; pcount = MIN(prefix_size, bcount); (void)memcpy(buffer, prefix_string, pcount); return (pcount);}/* * verify_prefix() - Verify Buffer with Prefix String. * * Inputs: * dip = The device information pointer. * buffer = Address of buffer to verify. * bcount = Count of remaining buffer bytes. * pcount = Pointer to return prefix count verified. * * Implicit Inputs: * prefix_string = The prefix string. * prefix_size = The prefix size. * * Outputs:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -