-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
storage: Grow Stratis blockdevs #19079
Changes from all commits
c3da802
06cd6cf
b8e978c
2df3b91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ import { | |
dialog_open, TextInput, SizeSlider, BlockingMessage, TeardownMessage, | ||
init_active_usage_processes | ||
} from "./dialog.jsx"; | ||
import { std_reply } from "./stratis-utils.js"; | ||
|
||
const _ = cockpit.gettext; | ||
|
||
|
@@ -56,6 +57,7 @@ function lvol_and_fsys_resize(client, lvol, size, offline, passphrase) { | |
let fsys; | ||
let crypto_overhead; | ||
let vdo; | ||
let stratis_bdev; | ||
const orig_size = lvol.Size; | ||
|
||
const block = client.lvols_block[lvol.path]; | ||
|
@@ -69,13 +71,15 @@ function lvol_and_fsys_resize(client, lvol, size, offline, passphrase) { | |
return; | ||
fsys = client.blocks_fsys[cleartext.path]; | ||
vdo = client.legacy_vdo_overlay.find_by_backing_block(cleartext); | ||
stratis_bdev = client.blocks_stratis_blockdev[cleartext.path]; | ||
if (crypto.MetadataSize !== undefined) | ||
crypto_overhead = crypto.MetadataSize; | ||
else | ||
crypto_overhead = block.Size - cleartext.Size; | ||
} else { | ||
fsys = client.blocks_fsys[block.path]; | ||
vdo = client.legacy_vdo_overlay.find_by_backing_block(block); | ||
stratis_bdev = client.blocks_stratis_blockdev[block.path]; | ||
crypto_overhead = 0; | ||
} | ||
|
||
|
@@ -110,6 +114,15 @@ function lvol_and_fsys_resize(client, lvol, size, offline, passphrase) { | |
return Promise.reject(_("VDO backing devices can not be made smaller")); | ||
else | ||
return Promise.resolve(); | ||
} else if (stratis_bdev) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This added line is not executed by any test. Details |
||
const delta = size - crypto_overhead - Number(stratis_bdev.TotalPhysicalSize); | ||
if (delta > 0) { | ||
const pool = client.stratis_pools[stratis_bdev.Pool]; | ||
return pool.GrowPhysicalDevice(stratis_bdev.Uuid).then(std_reply); | ||
} else if (delta < 0) | ||
return Promise.reject(_("Stratis blockdevs can not be made smaller")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This added line is not executed by any test. Details |
||
else | ||
return Promise.resolve(); | ||
} else if (size < orig_size) { | ||
// This shouldn't happen. But if it does, continuing is harmful, so we throw an error. | ||
return Promise.reject(_("Unrecognized data can not be made smaller here.")); | ||
|
@@ -185,6 +198,13 @@ function get_resize_info(client, block, to_fit) { | |
grow_excuse = cockpit.format(_("$0 filesystems can not be made larger."), | ||
block.IdType); | ||
} | ||
} else if (client.blocks_stratis_blockdev[block.path] && client.features.stratis_grow_blockdevs) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do understand this one -- on Fedora 38, the stratis_grow_blockdevs flag is always True, so it complains about not exercising the "false" path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This added line is not executed by any test. Details |
||
info = { | ||
can_shrink: false, | ||
can_grow: true, | ||
grow_needs_unmount: false | ||
}; | ||
shrink_excuse = _("Stratis blockdevs can not be made smaller"); | ||
} else if (block.IdUsage == 'raid') { | ||
info = { }; | ||
shrink_excuse = grow_excuse = _("Physical volumes can not be resized here."); | ||
|
@@ -331,6 +351,10 @@ function lvol_shrink(client, lvol, info, to_fit) { | |
if (vdo) | ||
shrink_size = vdo.physical_size + crypto_overhead; | ||
|
||
const stratis_bdev = client.blocks_stratis_blockdev[content_path]; | ||
if (stratis_bdev) | ||
shrink_size = Number(stratis_bdev.TotalPhysicalSize) + crypto_overhead; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could try to get this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. |
||
|
||
if (shrink_size === undefined) { | ||
console.warn("Couldn't determine size to shrink to."); | ||
return; | ||
|
@@ -400,11 +424,11 @@ export class BlockVolTab extends React.Component { | |
} | ||
|
||
function shrink() { | ||
lvol_shrink(client, lvol, info, unused_space); | ||
return lvol_shrink(client, lvol, info, unused_space); | ||
} | ||
|
||
function grow() { | ||
lvol_grow(client, lvol, info, unused_space); | ||
return lvol_grow(client, lvol, info, unused_space); | ||
} | ||
|
||
return ( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import cockpit from "cockpit"; | ||
import React from "react"; | ||
|
||
import { Alert } from "@patternfly/react-core/dist/esm/components/Alert/index.js"; | ||
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core/dist/esm/components/Card/index.js'; | ||
import { DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js"; | ||
import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js"; | ||
|
@@ -57,6 +58,17 @@ const _ = cockpit.gettext; | |
|
||
const fsys_min_size = 512 * 1024 * 1024; | ||
|
||
export function check_stratis_warnings(client, enter_warning) { | ||
if (!client.features.stratis_grow_blockdevs) | ||
return; | ||
|
||
for (const p in client.stratis_pools) { | ||
const blockdevs = client.stratis_pool_blockdevs[p] || []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The safety fallback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This added line is not executed by any test. Details |
||
if (blockdevs.some(bd => bd.NewPhysicalSize[0] && Number(bd.NewPhysicalSize[1]) > Number(bd.TotalPhysicalSize))) | ||
enter_warning(p, { warning: "unused-blockdevs" }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's that magic string? It's not in main, and it doesn't appear anywhere else in this patch. Do you perhaps mean "unused-space"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The exact string doesn't matter, this is just to get a warning triangle next to the pool in the "Devices" panel on the Overview. |
||
} | ||
} | ||
|
||
function teardown_block(block) { | ||
return for_each_async(block.Configuration, c => block.RemoveConfigurationItem(c, {})); | ||
} | ||
|
@@ -621,9 +633,28 @@ export const StratisPoolDetails = ({ client, pool }) => { | |
pool.ClevisInfo[0] && // pool has consistent clevis config | ||
(!pool.ClevisInfo[1][0] || pool.ClevisInfo[1][1][0] == "tang")); // not bound or bound to "tang" | ||
const tang_url = can_tang && pool.ClevisInfo[1][0] ? JSON.parse(pool.ClevisInfo[1][1][1]).url : null; | ||
const blockdevs = client.stratis_pool_blockdevs[pool.path] || []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. safety fallback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For such belt-and-suspenders code paths you could add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This added line is not executed by any test. Details |
||
const managed_fsys_sizes = client.features.stratis_managed_fsys_sizes && !pool.Overprovisioning; | ||
const stats = client.stratis_pool_stats[pool.path]; | ||
|
||
function grow_blockdevs() { | ||
return for_each_async(blockdevs, bd => pool.GrowPhysicalDevice(bd.Uuid)); | ||
} | ||
|
||
let alert = null; | ||
if (client.features.stratis_grow_blockdevs && | ||
blockdevs.some(bd => bd.NewPhysicalSize[0] && Number(bd.NewPhysicalSize[1]) > Number(bd.TotalPhysicalSize))) { | ||
alert = (<Alert key="unused-space" | ||
isInline | ||
variant="warning" | ||
title={_("This pool does not use all the space on its block devices.")}> | ||
{_("Some block devices of this pool have grown in size after the pool was created. The pool can be safely grown to use the newly available space.")} | ||
<div className="storage_alert_action_buttons"> | ||
<StorageButton onClick={grow_blockdevs}>{_("Grow the pool to take all space")}</StorageButton> | ||
</div> | ||
</Alert>); | ||
} | ||
|
||
function add_passphrase() { | ||
dialog_open({ | ||
Title: _("Add passphrase"), | ||
|
@@ -863,6 +894,7 @@ export const StratisPoolDetails = ({ client, pool }) => { | |
</Card>); | ||
|
||
return <StdDetailsLayout client={client} | ||
alerts={[alert]} | ||
header={header} | ||
sidebar={sidebar} | ||
content={content} />; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage of
if
statements is weird. The lines after theif
(the consequent) are executed, so I don't know how theif
itself is not executed. We might want filter them all out, like we do withelse
lines.