369
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
370
int passed_args, int *chunk_size_calc_method,
371
uint32_t *chunk_size, thin_discards_t *discards,
351
int update_thin_pool_params(struct volume_group *vg,
352
unsigned attr, int passed_args, uint32_t data_extents,
353
uint64_t *pool_metadata_size,
354
int *chunk_size_calc_method, uint32_t *chunk_size,
355
thin_discards_t *discards, int *zero)
357
struct cmd_context *cmd = vg->cmd;
358
struct profile *profile = vg->profile;
359
uint32_t extent_size = vg->extent_size;
360
size_t estimate_chunk_size;
376
363
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
377
364
if (!(*chunk_size = find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, profile) * 2)) {
378
str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile);
365
if (!(str = find_config_tree_str(cmd, allocation_thin_pool_chunk_size_policy_CFG, profile))) {
366
log_error(INTERNAL_ERROR "Could not find configuration.");
379
369
if (!strcasecmp(str, "generic"))
380
370
*chunk_size_calc_method = THIN_CHUNK_SIZE_CALC_METHOD_GENERIC;
381
371
else if (!strcasecmp(str, "performance"))
405
399
if (!(passed_args & PASS_ARG_ZERO))
406
400
*zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
411
int update_thin_pool_params(struct volume_group *vg, unsigned attr,
413
uint32_t data_extents, uint32_t extent_size,
414
int *chunk_size_calc_method, uint32_t *chunk_size,
415
thin_discards_t *discards,
416
uint64_t *pool_metadata_size, int *zero)
418
size_t estimate_chunk_size;
419
struct cmd_context *cmd = vg->cmd;
421
if (!update_profilable_pool_params(cmd, vg->profile, passed_args,
422
chunk_size_calc_method, chunk_size,
426
402
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
427
403
(*chunk_size & (*chunk_size - 1))) {
428
404
log_error("Chunk size must be a power of 2 for this thin target version.");
460
435
if (*pool_metadata_size % extent_size)
461
436
*pool_metadata_size += extent_size - *pool_metadata_size % extent_size;
463
estimate_chunk_size = (uint64_t) data_extents * extent_size /
438
estimate_chunk_size = (uint64_t) data_extents * extent_size /
464
439
(*pool_metadata_size * (SECTOR_SIZE / UINT64_C(64)));
440
if (estimate_chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
441
estimate_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
442
else if (estimate_chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
443
estimate_chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
465
445
/* Check to eventually use bigger chunk size */
466
446
if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
467
447
*chunk_size = estimate_chunk_size;
469
if (*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE)
470
*chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
471
else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
472
*chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
474
log_verbose("Setting chunk size %s.",
475
display_size(cmd, *chunk_size));
448
log_verbose("Setting chunk size %s.", display_size(cmd, *chunk_size));
476
449
} else if (*chunk_size < estimate_chunk_size) {
477
450
/* Suggest bigger chunk size */
478
451
log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.",
483
if ((uint64_t) *chunk_size > (uint64_t) data_extents * extent_size) {
484
log_error("Chunk size is bigger then pool data size.");
488
456
if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
457
*pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
489
458
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
490
459
log_warn("WARNING: Maximum supported pool metadata size is %s.",
491
display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE));
492
*pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
460
display_size(cmd, *pool_metadata_size));
493
461
} else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
462
*pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
494
463
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
495
464
log_warn("WARNING: Minimum supported pool metadata size is %s.",
496
display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE));
497
*pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
465
display_size(cmd, *pool_metadata_size));
500
log_verbose("Setting pool metadata size to %s.",
501
display_size(cmd, *pool_metadata_size));
535
500
return "unknown";
538
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
539
const char *name, uint32_t read_ahead,
540
uint32_t stripes, uint32_t stripe_size,
541
uint64_t size, alloc_policy_t alloc,
544
struct logical_volume *metadata_lv;
545
/* FIXME: Make lvm2api usable */
546
struct lvcreate_params lvc = {
547
.activate = CHANGE_ALY,
552
.permission = LVM_READ | LVM_WRITE,
554
.read_ahead = read_ahead,
555
.stripe_size = stripe_size,
557
.vg_name = pool_lv->vg->name,
561
dm_list_init(&lvc.tags);
563
if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
564
pool_lv->vg->extent_size)))
567
if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
570
/* FIXME: allocate properly space for metadata_lv */
572
if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc)))
578
static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg,
582
struct logical_volume *lv;
584
/* FIXME: Make lvm2api usable */
585
struct lvcreate_params lp = {
586
.activate = CHANGE_ALY,
587
.alloc = ALLOC_INHERIT,
591
.permission = LVM_READ | LVM_WRITE,
592
.pvh = pvh ? : &vg->pvs,
593
.read_ahead = DM_READ_AHEAD_AUTO,
600
dm_list_init(&lp.tags);
602
if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
605
/* FIXME: Maybe using silent mode ? */
606
if (!(lv = lv_create_single(vg, &lp)))
609
/* Spare LV should not be active */
610
if (!deactivate_lv_local(vg->cmd, lv)) {
611
log_error("Unable to deactivate pool metadata spare LV. "
612
"Manual intervention required.");
616
if (!vg_set_pool_metadata_spare(lv))
623
* Create/resize pool metadata spare LV
624
* Caller does vg_write(), vg_commit() with pool creation
625
* extents is 0, max size is determined
627
int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
628
struct dm_list *pvh, int poolmetadataspare)
630
struct logical_volume *lv = vg->pool_metadata_spare_lv;
631
uint32_t seg_mirrors;
632
struct lv_segment *seg;
633
const struct lv_list *lvl;
636
/* Find maximal size of metadata LV */
637
dm_list_iterate_items(lvl, &vg->lvs)
638
if (lv_is_thin_pool_metadata(lvl->lv) &&
639
(lvl->lv->le_count > extents))
640
extents = lvl->lv->le_count;
642
if (!poolmetadataspare) {
643
/* TODO: Not showing when lvm.conf would define 'n' ? */
644
if (DEFAULT_POOL_METADATA_SPARE && extents)
645
/* Warn if there would be any user */
646
log_warn("WARNING: recovery of pools without pool "
647
"metadata spare LV is not automated.");
652
if (!_alloc_pool_metadata_spare(vg, extents, pvh))
659
seg_mirrors = lv_mirror_count(lv);
661
/* Check spare LV is big enough and preserve segtype */
662
if ((lv->le_count < extents) && seg &&
663
!lv_extend(lv, seg->segtype,
664
seg->area_count / seg_mirrors,
668
extents - lv->le_count, NULL,
675
int vg_set_pool_metadata_spare(struct logical_volume *lv)
677
char new_name[NAME_LEN];
678
struct volume_group *vg = lv->vg;
680
if (vg->pool_metadata_spare_lv) {
681
if (vg->pool_metadata_spare_lv == lv)
683
if (!vg_remove_pool_metadata_spare(vg))
687
if (dm_snprintf(new_name, sizeof(new_name), "%s_pmspare", lv->name) < 0) {
688
log_error("Can't create pool metadata spare. Name of pool LV "
689
"%s is too long.", lv->name);
693
if (!lv_rename_update(vg->cmd, lv, new_name, 0))
697
lv->status |= POOL_METADATA_SPARE;
698
vg->pool_metadata_spare_lv = lv;
703
int vg_remove_pool_metadata_spare(struct volume_group *vg)
705
char new_name[NAME_LEN];
708
struct logical_volume *lv = vg->pool_metadata_spare_lv;
710
if (!(lv->status & POOL_METADATA_SPARE)) {
711
log_error(INTERNAL_ERROR "LV %s is not pool metadata spare.",
716
vg->pool_metadata_spare_lv = NULL;
717
lv->status &= ~POOL_METADATA_SPARE;
720
/* Cut off suffix _pmspare */
721
(void) dm_strncpy(new_name, lv->name, sizeof(new_name));
722
if (!(c = strchr(new_name, '_'))) {
723
log_error(INTERNAL_ERROR "LV %s has no suffix for pool metadata spare.",
729
/* If the name is in use, generate new lvol%d */
730
if (find_lv_in_vg(vg, new_name) &&
731
!generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
732
log_error("Failed to generate unique name for "
733
"pool metadata spare logical volume.");
737
log_print_unless_silent("Renaming existing pool metadata spare "
738
"logical volume \"%s/%s\" to \"%s/%s\".",
739
vg->name, lv->name, vg->name, new_name);
741
if (!lv_rename_update(vg->cmd, lv, new_name, 0))
744
/* To display default warning */
745
(void) handle_pool_metadata_spare(vg, 0, 0, 0);