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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Kevin Wolf
						Kevin Wolf