-
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: Don't allow mounting over other mounted filesystems #19388
Changes from all commits
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 |
---|---|---|
|
@@ -741,8 +741,34 @@ export function get_children(client, path) { | |
return children; | ||
} | ||
|
||
export function find_children_for_mount_point(client, mount_point, self) { | ||
const children = {}; | ||
|
||
function is_self(b) { | ||
return self && (b == self || client.blocks[b.CryptoBackingDevice] == self); | ||
} | ||
|
||
for (const p in client.blocks) { | ||
const b = client.blocks[p]; | ||
const fs = client.blocks_fsys[p]; | ||
|
||
if (is_self(b)) | ||
continue; | ||
|
||
if (fs) { | ||
for (const mp of fs.MountPoints) { | ||
const mpd = decode_filename(mp); | ||
if (mpd.length > mount_point.length && mpd.indexOf(mount_point) == 0 && mpd[mount_point.length] == "/") | ||
children[mpd] = b; | ||
} | ||
} | ||
} | ||
|
||
return children; | ||
} | ||
|
||
export function get_active_usage(client, path, top_action, child_action) { | ||
function get_usage(path, level) { | ||
function get_usage(usage, path, level) { | ||
const block = client.blocks[path]; | ||
const fsys = client.blocks_fsys[path]; | ||
const mdraid = block && client.mdraids[block.MDRaidMember]; | ||
|
@@ -752,7 +778,7 @@ export function get_active_usage(client, path, top_action, child_action) { | |
const stratis_blockdev = block && client.blocks_stratis_blockdev[path]; | ||
const stratis_pool = stratis_blockdev && client.stratis_pools[stratis_blockdev.Pool]; | ||
|
||
const usage = flatten(get_children_for_teardown(client, path).map(p => get_usage(p, level + 1))); | ||
get_children_for_teardown(client, path).map(p => get_usage(usage, p, level + 1)); | ||
|
||
function get_actions(teardown_action) { | ||
const actions = []; | ||
|
@@ -764,16 +790,34 @@ export function get_active_usage(client, path, top_action, child_action) { | |
return actions; | ||
} | ||
|
||
function enter_unmount(block, location, is_top) { | ||
for (const u of usage) { | ||
if (u.usage == 'mounted' && u.location == location) { | ||
if (is_top) { | ||
u.actions = get_actions(_("unmount")); | ||
u.set_noauto = false; | ||
Comment on lines
+795
to
+798
This comment was marked as resolved.
Sorry, something went wrong. |
||
} | ||
return; | ||
} | ||
} | ||
usage.push({ | ||
level, | ||
block, | ||
usage: 'mounted', | ||
location, | ||
set_noauto: !is_top, | ||
actions: is_top ? get_actions(_("unmount")) : [_("unmount")], | ||
blocking: false | ||
}); | ||
} | ||
|
||
if (fsys && fsys.MountPoints.length > 0) { | ||
fsys.MountPoints.forEach(mp => { | ||
usage.push({ | ||
level, | ||
usage: 'mounted', | ||
block, | ||
location: decode_filename(mp), | ||
actions: get_actions(_("unmount")), | ||
blocking: false, | ||
}); | ||
const mpd = decode_filename(mp); | ||
const children = find_children_for_mount_point(client, mpd, null); | ||
for (const c in children) | ||
enter_unmount(children[c], c, false); | ||
enter_unmount(block, mpd, true); | ||
}); | ||
} else if (mdraid) { | ||
const active_state = mdraid.ActiveDevices.find(as => as[0] == block.path); | ||
|
@@ -828,7 +872,8 @@ export function get_active_usage(client, path, top_action, child_action) { | |
return usage; | ||
} | ||
|
||
let usage = get_usage(path, 0); | ||
let usage = []; | ||
get_usage(usage, path, 0); | ||
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. Can't say I am super big fan of the indirection of filling in 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. Immutable data structures are overrated. :-) |
||
|
||
if (usage.length == 1 && usage[0].level == 0 && usage[0].usage == "none") | ||
usage = []; | ||
|
@@ -839,6 +884,37 @@ export function get_active_usage(client, path, top_action, child_action) { | |
return usage; | ||
} | ||
|
||
async function set_fsys_noauto(client, block, mount_point) { | ||
for (const conf of block.Configuration) { | ||
if (conf[0] == "fstab" && | ||
decode_filename(conf[1].dir.v) == mount_point) { | ||
const options = parse_options(get_block_mntopts(conf[1])); | ||
if (options.indexOf("noauto") >= 0) | ||
continue; | ||
options.push("noauto"); | ||
const new_conf = [ | ||
"fstab", | ||
Object.assign({ }, conf[1], | ||
{ | ||
opts: { | ||
t: 'ay', | ||
v: encode_filename(unparse_options(options)) | ||
} | ||
}) | ||
]; | ||
await block.UpdateConfigurationItem(conf, new_conf, { }); | ||
} | ||
} | ||
|
||
const crypto_backing = client.blocks[block.CryptoBackingDevice]; | ||
if (crypto_backing) { | ||
const crypto_backing_crypto = client.blocks_crypto[crypto_backing.path]; | ||
await set_crypto_auto_option(crypto_backing, false); | ||
if (crypto_backing_crypto) | ||
await crypto_backing_crypto.Lock({}); | ||
} | ||
} | ||
|
||
export function teardown_active_usage(client, usage) { | ||
// The code below is complicated by the fact that the last | ||
// physical volume of a volume group can not be removed | ||
|
@@ -849,10 +925,12 @@ export function teardown_active_usage(client, usage) { | |
// physical volumes here, and it is easiest to catch this | ||
// condition upfront by reshuffling the data structures. | ||
|
||
function unmount(mounteds) { | ||
return Promise.all(mounteds.map(m => { | ||
return client.unmount_at(m.location, m.users); | ||
})); | ||
async function unmount(mounteds) { | ||
for (const m of mounteds) { | ||
await client.unmount_at(m.location, m.users); | ||
if (m.set_noauto) | ||
jelly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
await set_fsys_noauto(client, m.block, m.location); | ||
} | ||
} | ||
|
||
function mdraid_remove(members) { | ||
|
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.
These 4 added lines are not executed by any test. Details