* Read a block from a pool and print it out. The syntax of the * block descriptor is: * * pool:vdev_specifier:offset:[lsize/]psize[:flags] * * pool - The name of the pool you wish to read from * vdev_specifier - Which vdev (see comment for zdb_vdev_lookup) * offset - offset, in hex, in bytes * size - Amount of data to read, in hex, in bytes * flags -
| 7830 | * |
| 7831 | */ |
| 7832 | static void |
| 7833 | zdb_read_block(char *thing, spa_t *spa) |
| 7834 | { |
| 7835 | blkptr_t blk, *bp = &blk; |
| 7836 | dva_t *dva = bp->blk_dva; |
| 7837 | int flags = 0; |
| 7838 | uint64_t offset = 0, psize = 0, lsize = 0, blkptr_offset = 0; |
| 7839 | zio_t *zio; |
| 7840 | vdev_t *vd; |
| 7841 | abd_t *pabd; |
| 7842 | void *lbuf, *buf; |
| 7843 | char *s, *p, *dup, *vdev, *flagstr, *sizes; |
| 7844 | int i, error; |
| 7845 | boolean_t borrowed = B_FALSE, found = B_FALSE; |
| 7846 | |
| 7847 | dup = strdup(thing); |
| 7848 | s = strtok(dup, ":"); |
| 7849 | vdev = s ? s : ""; |
| 7850 | s = strtok(NULL, ":"); |
| 7851 | offset = strtoull(s ? s : "", NULL, 16); |
| 7852 | sizes = strtok(NULL, ":"); |
| 7853 | s = strtok(NULL, ":"); |
| 7854 | flagstr = strdup(s ? s : ""); |
| 7855 | |
| 7856 | s = NULL; |
| 7857 | if (!zdb_parse_block_sizes(sizes, &lsize, &psize)) |
| 7858 | s = "invalid size(s)"; |
| 7859 | if (!IS_P2ALIGNED(psize, DEV_BSIZE) || !IS_P2ALIGNED(lsize, DEV_BSIZE)) |
| 7860 | s = "size must be a multiple of sector size"; |
| 7861 | if (!IS_P2ALIGNED(offset, DEV_BSIZE)) |
| 7862 | s = "offset must be a multiple of sector size"; |
| 7863 | if (s) { |
| 7864 | (void) printf("Invalid block specifier: %s - %s\n", thing, s); |
| 7865 | goto done; |
| 7866 | } |
| 7867 | |
| 7868 | for (s = strtok(flagstr, ":"); s; s = strtok(NULL, ":")) { |
| 7869 | for (i = 0; i < strlen(flagstr); i++) { |
| 7870 | int bit = flagbits[(uchar_t)flagstr[i]]; |
| 7871 | |
| 7872 | if (bit == 0) { |
| 7873 | (void) printf("***Ignoring flag: %c\n", |
| 7874 | (uchar_t)flagstr[i]); |
| 7875 | continue; |
| 7876 | } |
| 7877 | found = B_TRUE; |
| 7878 | flags |= bit; |
| 7879 | |
| 7880 | p = &flagstr[i + 1]; |
| 7881 | if (*p != ':' && *p != '\0') { |
| 7882 | int j = 0, nextbit = flagbits[(uchar_t)*p]; |
| 7883 | char *end, offstr[8] = { 0 }; |
| 7884 | if ((bit == ZDB_FLAG_PRINT_BLKPTR) && |
| 7885 | (nextbit == 0)) { |
| 7886 | /* look ahead to isolate the offset */ |
| 7887 | while (nextbit == 0 && |
| 7888 | strchr(flagbitstr, *p) == NULL) { |
| 7889 | offstr[j] = *p; |
no test coverage detected