diff --git a/old_unused/chroot.sh b/old_unused/chroot.sh index 416e511..bb88a19 100644 --- a/old_unused/chroot.sh +++ b/old_unused/chroot.sh @@ -546,14 +546,10 @@ function create_swapfile { fi echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n" btrfs subvolume create /var/swap - truncate -s 0 /var/swap/swapfile - chattr +C /var/swap/swapfile - chmod 600 /var/swap/swapfile - dd if=/dev/zero of=/var/swap/swapfile bs=100M count="$((${swap_size} * 10))" status=progress + btrfs filesystem mkswapfile /var/swap/swapfile --size "${swap_size}"G mkswap --label SwapFile /var/swap/swapfile swapon /var/swap/swapfile - gcc -O2 "$HOME"/btrfs_map_physical.c -o "$HOME"/btrfs_map_physical - RESUME_OFFSET=$(($("$HOME"/btrfs_map_physical /var/swap/swapfile | awk -F " " 'FNR == 2 {print $NF}') / $(getconf PAGESIZE))) + RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r /var/swap/swapfile) if [[ $bootloader =~ $regex_EFISTUB ]]; then sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook elif [[ $bootloader =~ $regex_GRUB2 ]]; then diff --git a/vli.sh b/vli.sh index 39a1901..4fbefb3 100755 --- a/vli.sh +++ b/vli.sh @@ -86,10 +86,6 @@ function kill_script { rm -f "$HOME"/chroot.sh fi - if [[ -f "$HOME"/btrfs_map_physical.c ]]; then - rm -f "$HOME"/btrfs_map_physical.c - fi - echo -e -n "\n${GREEN_LIGHT}Everything's done, quitting.${NORMAL}\n\n" exit 1 @@ -679,14 +675,10 @@ function create_swapfile { fi echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n" btrfs subvolume create /var/swap - truncate -s 0 /var/swap/swapfile - chattr +C /var/swap/swapfile - chmod 600 /var/swap/swapfile - dd if=/dev/zero of=/var/swap/swapfile bs=100M count="$((${swap_size} * 10))" status=progress + btrfs filesystem mkswapfile /var/swap/swapfile --size "${swap_size}"G mkswap --label SwapFile /var/swap/swapfile swapon /var/swap/swapfile - gcc -O2 "$HOME"/btrfs_map_physical.c -o "$HOME"/btrfs_map_physical - RESUME_OFFSET=$(($("$HOME"/btrfs_map_physical /var/swap/swapfile | awk -F " " 'FNR == 2 {print $NF}') / $(getconf PAGESIZE))) + RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r /var/swap/swapfile) if [[ $bootloader =~ $regex_EFISTUB ]]; then sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook elif [[ $bootloader =~ $regex_GRUB2 ]]; then @@ -1415,571 +1407,6 @@ EndOfChrootScript } -function create_btrfs_map_physical_c { - - if [[ -f "$HOME"/btrfs_map_physical.c ]]; then - rm -f "$HOME"/btrfs_map_physical.c - fi - - cat >>"$HOME"/btrfs_map_physical.c <<'EndOfProgram' -// SPDX-FileCopyrightText: Omar Sandoval -// SPDX-License-Identifier: MIT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define le16_to_cpu __le16_to_cpu -#define le32_to_cpu __le32_to_cpu -#define le64_to_cpu __le64_to_cpu - -static const char *progname = "btrfs_map_physical"; - -static void usage(bool error) -{ - fprintf(error ? stderr : stdout, - "usage: %s [OPTION]... PATH\n" - "\n" - "Map the logical and physical extents of a file on Btrfs\n\n" - "Pipe this to `column -ts $'\\t'` for prettier output.\n" - "\n" - "Btrfs represents a range of data in a file with a \"file extent\". Each\n" - "file extent refers to a subset of an \"extent\". Each extent has a\n" - "location in the logical address space of the filesystem belonging to a\n" - "\"chunk\". Each chunk maps has a profile (i.e., RAID level) and maps to\n" - "one or more physical locations, or \"stripes\", on disk. The extent may be\n" - "\"encoded\" on disk (currently this means compressed, but in the future it\n" - "may also be encrypted).\n" - "\n" - "An explanation of each printed field and its corresponding on-disk data\n" - "structure is provided below:\n" - "\n" - "FILE OFFSET Offset in the file where the file extent starts\n" - " [(struct btrfs_key).offset]\n" - "FILE SIZE Size of the file extent\n" - " [(struct btrfs_file_extent_item).num_bytes for most\n" - " extents, (struct btrfs_file_extent_item).ram_bytes\n" - " for inline extents]\n" - "EXTENT OFFSET Offset from the beginning of the unencoded extent\n" - " where the file extent starts\n" - " [(struct btrfs_file_extent_item).offset]\n" - "EXTENT TYPE Type of the extent (inline, preallocated, etc.)\n" - " [(struct btrfs_file_extent_item).type];\n" - " how it is encoded\n" - " [(struct btrfs_file_extent_item){compression,\n" - " encryption,other_encoding}];\n" - " and its data profile\n" - " [(struct btrfs_chunk).type]\n" - "LOGICAL SIZE Size of the unencoded extent\n" - " [(struct btrfs_file_extent_item).ram_bytes]\n" - "LOGICAL OFFSET Location of the extent in the filesystem's logical\n" - " address space\n" - " [(struct btrfs_file_extent_offset).disk_bytenr]\n" - "PHYSICAL SIZE Size of the encoded extent on disk\n" - " [(struct btrfs_file_extent_offset).disk_num_bytes]\n" - "DEVID ID of the device containing the extent\n" - " [(struct btrfs_stripe).devid]\n" - "PHYSICAL OFFSET Location of the extent on the device\n" - " [calculated from (struct btrfs_stripe).offset]\n" - "\n" - "FILE SIZE is rounded up to the sector size of the filesystem.\n" - "\n" - "Inline extents are stored with the metadata of the filesystem; this tool\n" - "does not have the ability to determine their location.\n" - "\n" - "Gaps in a file are represented with a hole file extent unless the\n" - "filesystem was formatted with the \"no-holes\" option.\n" - "\n" - "If the file extent was truncated, hole punched, cloned, or deduped,\n" - "EXTENT OFFSET may be non-zero and LOGICAL SIZE may be different from\n" - "FILE SIZE.\n" - "\n" - "Options:\n" - " -h, --help display this help message and exit\n", - progname); - exit(error ? EXIT_FAILURE : EXIT_SUCCESS); -} - -struct stripe { - uint64_t devid; - uint64_t offset; -}; - -struct chunk { - uint64_t offset; - uint64_t length; - uint64_t stripe_len; - uint64_t type; - struct stripe *stripes; - size_t num_stripes; - size_t sub_stripes; -}; - -struct chunk_tree { - struct chunk *chunks; - size_t num_chunks; -}; - -static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks) -{ - struct btrfs_ioctl_search_args search = { - .key = { - .tree_id = BTRFS_CHUNK_TREE_OBJECTID, - .min_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID, - .min_type = BTRFS_CHUNK_ITEM_KEY, - .min_offset = 0, - .max_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID, - .max_type = BTRFS_CHUNK_ITEM_KEY, - .max_offset = UINT64_MAX, - .min_transid = 0, - .max_transid = UINT64_MAX, - .nr_items = 0, - }, - }; - size_t items_pos = 0, buf_off = 0; - size_t capacity = 0; - int ret; - - *chunks = NULL; - *num_chunks = 0; - for (;;) { - const struct btrfs_ioctl_search_header *header; - const struct btrfs_chunk *item; - struct chunk *chunk; - size_t i; - - if (items_pos >= search.key.nr_items) { - search.key.nr_items = 4096; - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &search); - if (ret == -1) { - perror("BTRFS_IOC_TREE_SEARCH"); - return -1; - } - items_pos = 0; - buf_off = 0; - - if (search.key.nr_items == 0) - break; - } - - header = (struct btrfs_ioctl_search_header *)(search.buf + buf_off); - if (header->type != BTRFS_CHUNK_ITEM_KEY) - goto next; - - item = (void *)(header + 1); - if (*num_chunks >= capacity) { - struct chunk *tmp; - - if (capacity == 0) - capacity = 1; - else - capacity *= 2; - tmp = realloc(*chunks, capacity * sizeof(**chunks)); - if (!tmp) { - perror("realloc"); - return -1; - } - *chunks = tmp; - } - - chunk = &(*chunks)[*num_chunks]; - chunk->offset = header->offset; - chunk->length = le64_to_cpu(item->length); - chunk->stripe_len = le64_to_cpu(item->stripe_len); - chunk->type = le64_to_cpu(item->type); - chunk->num_stripes = le16_to_cpu(item->num_stripes); - chunk->sub_stripes = le16_to_cpu(item->sub_stripes); - chunk->stripes = calloc(chunk->num_stripes, - sizeof(*chunk->stripes)); - if (!chunk->stripes) { - perror("calloc"); - return -1; - } - (*num_chunks)++; - - for (i = 0; i < chunk->num_stripes; i++) { - const struct btrfs_stripe *stripe; - - stripe = &item->stripe + i; - chunk->stripes[i].devid = le64_to_cpu(stripe->devid); - chunk->stripes[i].offset = le64_to_cpu(stripe->offset); - } - -next: - items_pos++; - buf_off += sizeof(*header) + header->len; - if (header->offset == UINT64_MAX) - break; - else - search.key.min_offset = header->offset + 1; - } - return 0; -} - -static struct chunk *find_chunk(struct chunk *chunks, size_t num_chunks, - uint64_t logical) -{ - size_t lo, hi; - - if (!num_chunks) - return NULL; - - lo = 0; - hi = num_chunks - 1; - while (lo <= hi) { - size_t mid = lo + (hi - lo) / 2; - - if (logical < chunks[mid].offset) - hi = mid - 1; - else if (logical >= chunks[mid].offset + chunks[mid].length) - lo = mid + 1; - else - return &chunks[mid]; - } - return NULL; -} - -static int print_extents(int fd, struct chunk *chunks, size_t num_chunks) -{ - struct btrfs_ioctl_search_args search = { - .key = { - .min_type = BTRFS_EXTENT_DATA_KEY, - .max_type = BTRFS_EXTENT_DATA_KEY, - .min_offset = 0, - .max_offset = UINT64_MAX, - .min_transid = 0, - .max_transid = UINT64_MAX, - .nr_items = 0, - }, - }; - struct btrfs_ioctl_ino_lookup_args args = { - .treeid = 0, - .objectid = BTRFS_FIRST_FREE_OBJECTID, - }; - size_t items_pos = 0, buf_off = 0; - struct stat st; - int ret; - - puts("FILE OFFSET\tFILE SIZE\tEXTENT OFFSET\tEXTENT TYPE\tLOGICAL SIZE\tLOGICAL OFFSET\tPHYSICAL SIZE\tDEVID\tPHYSICAL OFFSET"); - - ret = fstat(fd, &st); - if (ret == -1) { - perror("fstat"); - return -1; - } - - ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args); - if (ret == -1) { - perror("BTRFS_IOC_INO_LOOKUP"); - return -1; - } - - search.key.tree_id = args.treeid; - search.key.min_objectid = search.key.max_objectid = st.st_ino; - for (;;) { - const struct btrfs_ioctl_search_header *header; - const struct btrfs_file_extent_item *item; - uint8_t type; - /* Initialize to silence GCC. */ - uint64_t file_offset = 0; - uint64_t file_size = 0; - uint64_t extent_offset = 0; - uint64_t logical_size = 0; - uint64_t logical_offset = 0; - uint64_t physical_size = 0; - struct chunk *chunk = NULL; - - if (items_pos >= search.key.nr_items) { - search.key.nr_items = 4096; - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &search); - if (ret == -1) { - perror("BTRFS_IOC_TREE_SEARCH"); - return -1; - } - items_pos = 0; - buf_off = 0; - - if (search.key.nr_items == 0) - break; - } - - header = (struct btrfs_ioctl_search_header *)(search.buf + buf_off); - if (header->type != BTRFS_EXTENT_DATA_KEY) - goto next; - - item = (void *)(header + 1); - - type = item->type; - file_offset = header->offset; - if (type == BTRFS_FILE_EXTENT_INLINE) { - file_size = logical_size = le64_to_cpu(item->ram_bytes); - extent_offset = 0; - physical_size = (header->len - - offsetof(struct btrfs_file_extent_item, - disk_bytenr)); - } else if (type == BTRFS_FILE_EXTENT_REG || - type == BTRFS_FILE_EXTENT_PREALLOC) { - file_size = le64_to_cpu(item->num_bytes); - extent_offset = le64_to_cpu(item->offset); - logical_size = le64_to_cpu(item->ram_bytes); - logical_offset = le64_to_cpu(item->disk_bytenr); - physical_size = le64_to_cpu(item->disk_num_bytes); - if (logical_offset) { - chunk = find_chunk(chunks, num_chunks, - logical_offset); - if (!chunk) { - printf("\n"); - fprintf(stderr, - "could not find chunk containing %" PRIu64 "\n", - logical_offset); - return -1; - } - } - } - - printf("%" PRIu64 "\t", file_offset); - if (type == BTRFS_FILE_EXTENT_INLINE || - type == BTRFS_FILE_EXTENT_REG || - type == BTRFS_FILE_EXTENT_PREALLOC) { - printf("%" PRIu64 "\t%" PRIu64 "\t", file_size, - extent_offset); - } else { - printf("\t\t"); - } - - switch (type) { - case BTRFS_FILE_EXTENT_INLINE: - printf("inline"); - break; - case BTRFS_FILE_EXTENT_REG: - if (logical_offset) - printf("regular"); - else - printf("hole"); - break; - case BTRFS_FILE_EXTENT_PREALLOC: - printf("prealloc"); - break; - default: - printf("type%u", type); - break; - } - switch (item->compression) { - case 0: - break; - case 1: - printf(",compression=zlib"); - break; - case 2: - printf(",compression=lzo"); - break; - case 3: - printf(",compression=zstd"); - break; - default: - printf(",compression=%u", item->compression); - break; - } - if (item->encryption) - printf(",encryption=%u", item->encryption); - if (item->other_encoding) { - printf(",other_encoding=%u", - le16_to_cpu(item->other_encoding)); - } - if (chunk) { - switch (chunk->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) { - case 0: - break; - case BTRFS_BLOCK_GROUP_RAID0: - printf(",raid0"); - break; - case BTRFS_BLOCK_GROUP_RAID1: - printf(",raid1"); - break; - case BTRFS_BLOCK_GROUP_DUP: - printf(",dup"); - break; - case BTRFS_BLOCK_GROUP_RAID10: - printf(",raid10"); - break; - case BTRFS_BLOCK_GROUP_RAID5: - printf(",raid5"); - break; - case BTRFS_BLOCK_GROUP_RAID6: - printf(",raid6"); - break; - default: - printf(",profile%" PRIu64, - (uint64_t)(chunk->type & - BTRFS_BLOCK_GROUP_PROFILE_MASK)); - break; - } - } - printf("\t"); - - if (type == BTRFS_FILE_EXTENT_INLINE || - type == BTRFS_FILE_EXTENT_REG || - type == BTRFS_FILE_EXTENT_PREALLOC) - printf("%" PRIu64 "\t", logical_size); - else - printf("\t"); - - if (type == BTRFS_FILE_EXTENT_REG || - type == BTRFS_FILE_EXTENT_PREALLOC) - printf("%" PRIu64 "\t", logical_offset); - else - printf("\t"); - - if (type == BTRFS_FILE_EXTENT_INLINE || - type == BTRFS_FILE_EXTENT_REG || - type == BTRFS_FILE_EXTENT_PREALLOC) - printf("%" PRIu64 "\t", physical_size); - else - printf("\t"); - - if (chunk) { - uint64_t offset, stripe_nr, stripe_offset; - size_t stripe_index, num_stripes; - size_t i; - - offset = logical_offset - chunk->offset; - stripe_nr = offset / chunk->stripe_len; - stripe_offset = offset - stripe_nr * chunk->stripe_len; - switch (chunk->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) { - case 0: - case BTRFS_BLOCK_GROUP_RAID0: - stripe_index = stripe_nr % chunk->num_stripes; - stripe_nr /= chunk->num_stripes; - num_stripes = 1; - break; - case BTRFS_BLOCK_GROUP_RAID1: - case BTRFS_BLOCK_GROUP_DUP: - stripe_index = 0; - num_stripes = chunk->num_stripes; - break; - case BTRFS_BLOCK_GROUP_RAID10: { - size_t factor; - - factor = chunk->num_stripes / chunk->sub_stripes; - stripe_index = (stripe_nr % factor * - chunk->sub_stripes); - stripe_nr /= factor; - num_stripes = chunk->sub_stripes; - break; - } - case BTRFS_BLOCK_GROUP_RAID5: - case BTRFS_BLOCK_GROUP_RAID6: { - size_t nr_parity_stripes, nr_data_stripes; - - if (chunk->type & BTRFS_BLOCK_GROUP_RAID6) - nr_parity_stripes = 2; - else - nr_parity_stripes = 1; - nr_data_stripes = (chunk->num_stripes - - nr_parity_stripes); - stripe_index = stripe_nr % nr_data_stripes; - stripe_nr /= nr_data_stripes; - stripe_index = ((stripe_nr + stripe_index) % - chunk->num_stripes); - num_stripes = 1; - break; - } - default: - num_stripes = 0; - break; - } - - for (i = 0; i < num_stripes; i++) { - if (i != 0) - printf("\n\t\t\t\t\t\t\t"); - printf("%" PRIu64 "\t%" PRIu64, - chunk->stripes[stripe_index].devid, - chunk->stripes[stripe_index].offset + - stripe_nr * chunk->stripe_len + - stripe_offset); - stripe_index++; - } - } - printf("\n"); - -next: - items_pos++; - buf_off += sizeof(*header) + header->len; - if (header->offset == UINT64_MAX) - break; - else - search.key.min_offset = header->offset + 1; - } - return 0; -} - -int main(int argc, char **argv) -{ - struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - }; - int fd, ret; - struct chunk *chunks; - size_t num_chunks, i; - - if (argv[0]) - progname = argv[0]; - - for (;;) { - int c; - - c = getopt_long(argc, argv, "h", long_options, NULL); - if (c == -1) - break; - - switch (c) { - case 'h': - usage(false); - default: - usage(true); - } - } - if (optind != argc - 1) - usage(true); - - fd = open(argv[optind], O_RDONLY); - if (fd == -1) { - perror("open"); - return EXIT_FAILURE; - } - - ret = read_chunk_tree(fd, &chunks, &num_chunks); - if (ret == -1) - goto out; - - ret = print_extents(fd, chunks, num_chunks); -out: - for (i = 0; i < num_chunks; i++) - free(chunks[i].stripes); - free(chunks); - close(fd); - return ret ? EXIT_FAILURE : EXIT_SUCCESS; -} -EndOfProgram - - if [[ ! -f "$HOME"/btrfs_map_physical.c ]]; then - echo -e -n "Please run this script again to be sure that $HOME/btrfs_map_physical.c is created too." - exit 1 - fi - -} - function intro { clear @@ -3020,7 +2447,6 @@ function format_create_install_system { echo -e -n "\nChrooting...\n\n" press_any_key_to_continue cp "$HOME"/chroot.sh /mnt/root/ - cp "$HOME"/btrfs_map_physical.c /mnt/root/ BTRFS_OPT="$BTRFS_OPT" boot_partition="$boot_partition" encryption_yn="$encryption_yn" luks_ot="$luks_ot" root_partition="$root_partition" \ encrypted_name="$encrypted_name" lvm_yn="$lvm_yn" vg_name="$vg_name" lv_root_name="$lv_root_name" user_drive="$user_drive" final_drive="$final_drive" \ @@ -3033,8 +2459,6 @@ function format_create_install_system { header_fcis echo -e -n "\nCleaning...\n" rm -f /mnt/root/chroot.sh - rm -f /mnt/root/btrfs_map_physical.c - rm -f /mnt/root/btrfs_map_physical echo -e -n "\nUnmounting partitions...\n\n" if findmnt /mnt &>/dev/null; then