mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 11:39:53 +00:00
block: Include details on permission errors in message
Instead of just telling that there was some conflict, we can be specific and tell which permissions were in conflict and which way the conflict is. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Acked-by: Fam Zheng <famz@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
b541155587
commit
d083319fe0
67
block.c
67
block.c
@ -1462,6 +1462,43 @@ static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
|
||||
*shared_perm = cumulative_shared_perms;
|
||||
}
|
||||
|
||||
static char *bdrv_child_user_desc(BdrvChild *c)
|
||||
{
|
||||
if (c->role->get_parent_desc) {
|
||||
return c->role->get_parent_desc(c);
|
||||
}
|
||||
|
||||
return g_strdup("another user");
|
||||
}
|
||||
|
||||
static char *bdrv_perm_names(uint64_t perm)
|
||||
{
|
||||
struct perm_name {
|
||||
uint64_t perm;
|
||||
const char *name;
|
||||
} permissions[] = {
|
||||
{ BLK_PERM_CONSISTENT_READ, "consistent read" },
|
||||
{ BLK_PERM_WRITE, "write" },
|
||||
{ BLK_PERM_WRITE_UNCHANGED, "write unchanged" },
|
||||
{ BLK_PERM_RESIZE, "resize" },
|
||||
{ BLK_PERM_GRAPH_MOD, "change children" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
char *result = g_strdup("");
|
||||
struct perm_name *p;
|
||||
|
||||
for (p = permissions; p->name; p++) {
|
||||
if (perm & p->perm) {
|
||||
char *old = result;
|
||||
result = g_strdup_printf("%s%s%s", old, *old ? ", " : "", p->name);
|
||||
g_free(old);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether a new reference to @bs can be added if the new user requires
|
||||
* @new_used_perm/@new_shared_perm as its permissions. If @ignore_child is set,
|
||||
@ -1486,17 +1523,25 @@ static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((new_used_perm & c->shared_perm) != new_used_perm ||
|
||||
(c->perm & new_shared_perm) != c->perm)
|
||||
{
|
||||
const char *user = NULL;
|
||||
if (c->role->get_name) {
|
||||
user = c->role->get_name(c);
|
||||
if (user && !*user) {
|
||||
user = NULL;
|
||||
}
|
||||
}
|
||||
error_setg(errp, "Conflicts with %s", user ?: "another operation");
|
||||
if ((new_used_perm & c->shared_perm) != new_used_perm) {
|
||||
char *user = bdrv_child_user_desc(c);
|
||||
char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
|
||||
error_setg(errp, "Conflicts with use by %s as '%s', which does not "
|
||||
"allow '%s' on %s",
|
||||
user, c->name, perm_names, bdrv_get_node_name(c->bs));
|
||||
g_free(user);
|
||||
g_free(perm_names);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if ((c->perm & new_shared_perm) != c->perm) {
|
||||
char *user = bdrv_child_user_desc(c);
|
||||
char *perm_names = bdrv_perm_names(c->perm & ~new_shared_perm);
|
||||
error_setg(errp, "Conflicts with use by %s as '%s', which uses "
|
||||
"'%s' on %s",
|
||||
user, c->name, perm_names, bdrv_get_node_name(c->bs));
|
||||
g_free(user);
|
||||
g_free(perm_names);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user