// initialize or reload cache variables void init_le_to_pe() { void *handle; int r; if(pv_segments) le_to_pe_exit(); vg_pe_sizes = NULL; vg_pe_sizes_len = 0; lvm2_log_fn(parse_pvs_segments); handle = lvm2_init(); lvm2_log_level(handle, 1); r = lvm2_run(handle, "pvs --noheadings --segments -o+lv_name," "seg_start_pe,segtype"); // if (r) // fprintf(stderr, "command failed\n"); sort_segments(pv_segments, pv_segments_num); lvm2_log_fn(parse_vgs_pe_size); r = lvm2_run(handle, "vgs -o vg_name,vg_extent_size --noheadings"); lvm2_exit(handle); return; }
int lvm2_run(void *handle, const char *cmdline) { int argc, ret, oneoff = 0; char *args[MAX_ARGS], **argv, *cmdcopy = NULL; struct cmd_context *cmd; argv = args; if (!handle) { oneoff = 1; if (!(handle = lvm2_init())) { log_error("Handle initialisation failed."); return ECMD_FAILED; } } cmd = (struct cmd_context *) handle; cmd->argv = argv; if (!(cmdcopy = dm_strdup(cmdline))) { log_error("Cmdline copy failed."); ret = ECMD_FAILED; goto out; } if (lvm_split(cmdcopy, &argc, argv, MAX_ARGS) == MAX_ARGS) { log_error("Too many arguments. Limit is %d.", MAX_ARGS); ret = EINVALID_CMD_LINE; goto out; } if (!argc) { log_error("No command supplied"); ret = EINVALID_CMD_LINE; goto out; } /* FIXME Temporary - move to libdevmapper */ ret = ECMD_PROCESSED; if (!strcmp(cmdline, "_memlock_inc")) memlock_inc_daemon(cmd); else if (!strcmp(cmdline, "_memlock_dec")) memlock_dec_daemon(cmd); else ret = lvm_run_command(cmd, argc, argv); out: dm_free(cmdcopy); if (oneoff) lvm2_exit(handle); return ret; }
/** destroy program_params */ void free_program_params(struct program_params *pp) { if(!pp) return; if(pp->conf_file_path) free(pp->conf_file_path); cfg_free(pp->cfg); if (pp->lvm2_handle) lvm2_exit(pp->lvm2_handle); le_to_pe_exit(pp); free(pp); }
int main(int argc, char **argv) { void *handle; int r; lvm2_log_fn(test_log_fn); handle = lvm2_init(); lvm2_log_level(handle, 1); r = lvm2_run(handle, "vgs --noheadings vg1"); /* More commands here */ lvm2_exit(handle); return r; }
int main(int argc, char **argv) { if (argc != 4) { fprintf(stderr, "Tool to defragment LogicalVolume on selected PhysicalVolume\n"); fprintf(stderr, "Usage: lvmdefrag VolumeGroup LogicalVolume PhysicalVolume\n"); return EXIT_FAILURE; } char *vg_name = argv[1]; char *lv_name = argv[2]; char *pv_name = argv[3]; struct program_params pp = { .lvm2_handle = NULL }; init_le_to_pe(&pp); struct le_info first_le; first_le = get_first_LE_info(vg_name, lv_name, pv_name); for(size_t i=0; i < pv_segments_num; i ++) if( !strcmp(pv_segments[i].lv_name, lv_name) && !strcmp(pv_segments[i].vg_name, vg_name) && !strcmp(pv_segments[i].pv_name, pv_name)) { long int optimal_pos; optimal_pos = first_le.pe + pv_segments[i].lv_start - first_le.le; if (pv_segments[i].pv_start == optimal_pos) continue; struct le_info optimal; long int move_extent = 0; for (long int j=optimal_pos; j < optimal_pos + pv_segments[i].pv_length; j++) { optimal = get_PE_allocation(vg_name, pv_name, j); if (optimal.dev == NULL) { printf("# Optimal position for LE %li-%li on %s is after end of " "the device\n", pv_segments[i].lv_start, pv_segments[i].lv_start + pv_segments[i].pv_length, pv_name); break; } else if (strcmp(optimal.lv_name, "free")) { printf("# Optimal position for LE %li-%li is used by %s LE %li\n", pv_segments[i].lv_start, pv_segments[i].lv_start + pv_segments[i].pv_length, optimal.lv_name, optimal.le); break; } move_extent++; } if (move_extent) { printf("pvmove -i1 --alloc anywhere %s:%li-%li %s:%li-%li # LE %li (size: %li)\n", pv_name, pv_segments[i].pv_start, pv_segments[i].pv_start + move_extent - 1, pv_name, optimal_pos, optimal_pos + move_extent - 1, pv_segments[i].lv_start, move_extent); } } le_to_pe_exit(&pp); lvm2_exit(pp.lvm2_handle); return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct program_params pp = { .lvm2_handle = NULL }; init_le_to_pe(&pp); if (argc != 4) { printf("Usage: %s VolumeGroupName LogicalVolumeName" " LogicalVolumeExtent\n", argv[0]); le_to_pe_exit(&pp); return 1; } for(int i=0; i < pv_segments_num; i++) if(!strcmp(pv_segments[i].lv_name, argv[1])) printf("%s %li-%li (%li-%li)\n", pv_segments[i].pv_name, pv_segments[i].pv_start, pv_segments[i].pv_start+pv_segments[i].pv_length, pv_segments[i].lv_start, pv_segments[i].lv_start+pv_segments[i].pv_length); if (argc <= 2) return 0; struct pv_info *pv_info; pv_info = LE_to_PE(argv[1], argv[2], atoi(argv[3])); if (pv_info) printf("LE no %i of %s-%s is at: %s:%li\n", atoi(argv[3]), argv[1], argv[2], pv_info->pv_name, pv_info->start_seg); else printf("no LE found\n"); printf("vg: %s, extent size: %lu bytes\n", argv[1], get_pe_size(argv[1])); long int free_extents = get_free_extent_number(argv[1], pv_info->pv_name); printf("vg: %s, pv: %s, free space: %lue (%luB)\n", argv[1], pv_info->pv_name, free_extents, free_extents * get_pe_size(argv[1])); long int used_extents = get_used_space_on_pv(argv[1], argv[2], pv_info->pv_name); printf("Space used by lv %s on pv %s: %lue (%luB)\n", argv[2], pv_info->pv_name, used_extents, used_extents * get_pe_size(argv[1])); struct le_info le_inf; le_inf = get_first_LE_info(argv[1], argv[2], pv_info->pv_name); printf("First LE on %s is %li at PE %li\n", le_inf.dev, le_inf.le, le_inf.pe); long int optimal_pe = le_inf.pe + atoi(argv[3]) - le_inf.le; printf("Optimal position for LE %i is at %s:%li\n", atoi(argv[3]), le_inf.dev, optimal_pe); printf("%s:%li is ", le_inf.dev, optimal_pe); if (optimal_pe == pv_info->start_seg) { printf("allocated correctly\n"); } else { struct le_info optimal; optimal = get_PE_allocation(argv[1], pv_info->pv_name, optimal_pe); if (optimal.dev == NULL) printf("after the end of the device\n"); else if (!strcmp(optimal.lv_name, "free")) printf("free\n"); else printf("allocated to %s, LE: %li\n", optimal.lv_name, optimal.le); } pv_info_free(pv_info); le_to_pe_exit(&pp); lvm2_exit(pp.lvm2_handle); return 0; }