Skip to content

Commit

Permalink
Implement deletion and fix creation without a mount point
Browse files Browse the repository at this point in the history
  • Loading branch information
jelly committed Nov 17, 2023
1 parent 33d2f6d commit ca756b1
Show file tree
Hide file tree
Showing 5 changed files with 388 additions and 56 deletions.
63 changes: 63 additions & 0 deletions pkg/storaged/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,50 @@ function is_multipath_master(block) {
return false;
}

export function btrfs_poll() {
if (!client.uuids_btrfs_subvols)
client.uuids_btrfs_subvols = { };
if (!client.uuids_btrfs_volume)
return;

const uuids_subvols = { };
return Promise.all(Object.keys(client.uuids_btrfs_volume).map(uuid => {
const block = client.uuids_btrfs_blocks[uuid][0];
const block_fsys = client.blocks_fsys[block.path];
const mp = block_fsys.MountPoints[0];
if (mp) {
return cockpit.spawn(["btrfs", "subvolume", "list", "-ap", utils.decode_filename(mp)],
{ superuser: true, err: "message" })
.then(output => {
const subvols = [{ pathname: "/", id: 5 }];
for (const line of output.split("\n")) {
const m = line.match(/ID (\d+).*parent (\d+).*path (<FS_TREE>\/)?(.*)/);
if (m)
subvols.push({ pathname: m[4], id: Number(m[1]) });
}
uuids_subvols[uuid] = subvols;
});
} else {
uuids_subvols[uuid] = null;
return Promise.resolve();
}
}))
.then(() => {
// deep-equal?
if (JSON.stringify(client.uuids_btrfs_subvols) != JSON.stringify(uuids_subvols)) {
console.log("SUBVOLS", uuids_subvols);
client.uuids_btrfs_subvols = uuids_subvols;
client.update();
}
});
}

function btrfs_start_polling() {
window.setInterval(btrfs_poll, 5000);
client.uuids_btrfs_subvols = { };
btrfs_poll();
}

function update_indices() {
let path, block, mdraid, vgroup, pvol, lvol, pool, blockdev, fsys, part, i;

Expand Down Expand Up @@ -547,15 +591,31 @@ function update_indices() {

// UDisks API does provide a btrfs volume abstraction so we keep track of
// volume's by uuid in an object. uuid => [org.freedesktop.UDisks2.Filesystem.BTRFS]
const old_uuids = client.uuids_btrfs_volume;
let need_poll = false;
client.uuids_btrfs_volume = { };
client.uuids_btrfs_blocks = { };
for (const p in client.blocks_fsys_btrfs) {
const bfs = client.blocks_fsys_btrfs[p];
const uuid = bfs.data.uuid;
const block_fsys = client.blocks_fsys[p];
if ((block_fsys && block_fsys.MountPoints.length > 0) || !client.uuids_btrfs_volume[uuid]) {
client.uuids_btrfs_volume[uuid] = bfs;
if (!old_uuids || !old_uuids[uuid])
need_poll = true;
}
if (!client.uuids_btrfs_blocks[uuid])
client.uuids_btrfs_blocks[uuid] = [];
client.uuids_btrfs_blocks[uuid].push(client.blocks[p]);
}

if (need_poll) {
console.log('polling btrfs');
btrfs_poll();
}

console.log("uuids_btrfs_blocks", client.uuids_btrfs_blocks);
console.log("uuids_btrfs_subvolumes", client.uuids_btrfs_volumes);

client.blocks_cleartext = { };
for (path in client.blocks) {
Expand Down Expand Up @@ -628,6 +688,7 @@ client.update = (first_time) => {
if (client.ready) {
update_indices();
client.path_warnings = find_warnings(client);
console.log('create pages');
create_pages();
client.dispatchEvent("changed");
}
Expand Down Expand Up @@ -657,6 +718,8 @@ function init_model(callback) {
client.features.iscsi = (client.manager_iscsi.valid &&
client.manager_iscsi.SessionsSupported !== false);
client.features.btrfs = client.manager_btrfs.valid;
if (client.features.btrfs)
btrfs_start_polling();
});
}, function(error) {
console.warn("Can't enable storaged modules", error.toString());
Expand Down
42 changes: 26 additions & 16 deletions pkg/storaged/fsys-tab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,18 @@ import client from "./client.js";

const _ = cockpit.gettext;

export function is_mounted(client, block) {
export function is_mounted(client, block, subvol) {
const block_fsys = client.blocks_fsys[block.path];
const mounted_at = block_fsys ? block_fsys.MountPoints : [];
const config = block.Configuration.find(c => c[0] == "fstab");
if (config && config[1].dir.v) {
let dir = utils.decode_filename(config[1].dir.v);
if (dir[0] != "/")
dir = "/" + dir;
const [, dir] = get_fstab_config(block, false, subvol);
if (dir) {
return mounted_at.map(utils.decode_filename).indexOf(dir) >= 0;
} else
return null;
}

export function get_fstab_config(block, also_child_config) {
return get_fstab_config_with_client(client, block, also_child_config);
export function get_fstab_config(block, also_child_config, subvol) {
return get_fstab_config_with_client(client, block, also_child_config, subvol);
}

function find_blocks_for_mount_point(client, mount_point, self) {
Expand Down Expand Up @@ -155,9 +152,9 @@ export function check_mismounted_fsys(client, path, enter_warning) {
enter_warning(path, { warning: "mismounted-fsys", type, other: other_mounts[0] });
}

export function mounting_dialog(client, block, mode, forced_options) {
export function mounting_dialog(client, block, mode, forced_options, subvol) {
const block_fsys = client.blocks_fsys[block.path];
const [old_config, old_dir, old_opts, old_parents] = get_fstab_config(block, true);
const [old_config, old_dir, old_opts, old_parents] = get_fstab_config(block, true, subvol);
const options = old_config ? old_opts : initial_tab_options(client, block, true);

const split_options = parse_options(options);
Expand All @@ -169,9 +166,13 @@ export function mounting_dialog(client, block, mode, forced_options) {
if (forced_options)
for (const opt of forced_options)
extract_option(split_options, opt);
if (subvol) {
extract_option(split_options, "subvol=" + subvol.pathname);
extract_option(split_options, "subvolid=" + subvol.id);
}
const extra_options = unparse_options(split_options);

const is_filesystem_mounted = is_mounted(client, block);
const is_filesystem_mounted = is_mounted(client, block, subvol);

function maybe_update_config(new_dir, new_opts, passphrase, passphrase_type) {
let new_config = null;
Expand Down Expand Up @@ -385,6 +386,8 @@ export function mounting_dialog(client, block, mode, forced_options) {
opts.push("_netdev");
if (forced_options)
opts = opts.concat(forced_options);
if (subvol)
opts.push("subvol=" + subvol.pathname);
if (extra_options)
opts = opts.concat(extra_options);
return (maybe_set_crypto_options(null, false, null, null)
Expand Down Expand Up @@ -431,6 +434,8 @@ export function mounting_dialog(client, block, mode, forced_options) {
opts.push("_netdev");
if (forced_options)
opts = opts.concat(forced_options);
if (subvol)
opts.push("subvol=" + subvol.pathname);
if (vals.mount_options.extra !== false)
opts = opts.concat(parse_options(vals.mount_options.extra));
return (maybe_update_config(vals.mount_point, unparse_options(opts),
Expand Down Expand Up @@ -473,6 +478,7 @@ export class FilesystemTab extends React.Component {
render() {
const self = this;
const block = self.props.block;
const subvol = self.props.subvol;
const forced_options = self.props.forced_options;
const is_locked = block && block.IdUsage == 'crypto';
const block_fsys = block && self.props.client.blocks_fsys[block.path];
Expand All @@ -499,8 +505,8 @@ export class FilesystemTab extends React.Component {
});
}

const is_filesystem_mounted = is_mounted(self.props.client, block);
const [old_config, old_dir, old_opts, old_parents] = get_fstab_config(block, true);
const is_filesystem_mounted = is_mounted(self.props.client, block, subvol);
const [old_config, old_dir, old_opts, old_parents] = get_fstab_config(block, true, subvol);
const split_options = parse_options(old_opts);
extract_option(split_options, "noauto");
const opt_ro = extract_option(split_options, "ro");
Expand All @@ -511,6 +517,10 @@ export class FilesystemTab extends React.Component {
if (forced_options)
for (const opt of forced_options)
extract_option(split_options, opt);
if (subvol) {
extract_option(split_options, "subvol=" + subvol.pathname);
extract_option(split_options, "subvolid=" + subvol.id);
}

let mount_point_text = null;
if (old_dir) {
Expand Down Expand Up @@ -621,7 +631,7 @@ export class FilesystemTab extends React.Component {

function do_mount() {
if (crypto_backing == block)
mounting_dialog(client, block, "mount", forced_options);
mounting_dialog(client, block, "mount", forced_options, subvol);
else
return client.mount_at(block, old_dir);
}
Expand Down Expand Up @@ -695,7 +705,7 @@ export class FilesystemTab extends React.Component {
return (
<div>
<DescriptionList className="pf-m-horizontal-on-sm">
{ !stratis_fsys &&
{ !(stratis_fsys || subvol) &&
<DescriptionListGroup>
<DescriptionListTerm>{_("Name")}</DescriptionListTerm>
<DescriptionListDescription>
Expand All @@ -718,7 +728,7 @@ export class FilesystemTab extends React.Component {
<FlexItem>{ mount_point_text }</FlexItem>
<FlexItem>
<StorageLink onClick={() => mounting_dialog(self.props.client, block, "update",
forced_options)}>
forced_options, subvol)}>
{_("edit")}
</StorageLink>
</FlexItem>
Expand Down
1 change: 1 addition & 0 deletions pkg/storaged/pages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export function get_page_from_location(location) {

export function navigate_away_from_page(page) {
const loc = cockpit.location;
console.log('navigate away');
if (page.parent && JSON.stringify(loc.path) == JSON.stringify(page.location))
loc.go(page.parent.location);
}
Expand Down
Loading

0 comments on commit ca756b1

Please sign in to comment.