block: Allow JSON filenames
If the filename given to bdrv_open() is prefixed with "json:", parse the rest as a JSON object and merge the result into the options QDict. If there are conflicts, the options QDict takes precedence. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									8a5eb36a1c
								
							
						
					
					
						commit
						4993f7ea7e
					
				
							
								
								
									
										41
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								block.c
									
									
									
									
									
								
							@ -1274,6 +1274,33 @@ out:
 | 
				
			|||||||
    g_free(tmp_filename);
 | 
					    g_free(tmp_filename);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static QDict *parse_json_filename(const char *filename, Error **errp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QObject *options_obj;
 | 
				
			||||||
 | 
					    QDict *options;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = strstart(filename, "json:", &filename);
 | 
				
			||||||
 | 
					    assert(ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options_obj = qobject_from_json(filename);
 | 
				
			||||||
 | 
					    if (!options_obj) {
 | 
				
			||||||
 | 
					        error_setg(errp, "Could not parse the JSON options");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (qobject_type(options_obj) != QTYPE_QDICT) {
 | 
				
			||||||
 | 
					        qobject_decref(options_obj);
 | 
				
			||||||
 | 
					        error_setg(errp, "Invalid JSON object given");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = qobject_to_qdict(options_obj);
 | 
				
			||||||
 | 
					    qdict_flatten(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return options;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Opens a disk image (raw, qcow2, vmdk, ...)
 | 
					 * Opens a disk image (raw, qcow2, vmdk, ...)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -1337,6 +1364,20 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
 | 
				
			|||||||
        options = qdict_new();
 | 
					        options = qdict_new();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (filename && g_str_has_prefix(filename, "json:")) {
 | 
				
			||||||
 | 
					        QDict *json_options = parse_json_filename(filename, &local_err);
 | 
				
			||||||
 | 
					        if (local_err) {
 | 
				
			||||||
 | 
					            ret = -EINVAL;
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Options given in the filename have lower priority than options
 | 
				
			||||||
 | 
					         * specified directly */
 | 
				
			||||||
 | 
					        qdict_join(options, json_options, false);
 | 
				
			||||||
 | 
					        QDECREF(json_options);
 | 
				
			||||||
 | 
					        filename = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bs->options = options;
 | 
					    bs->options = options;
 | 
				
			||||||
    options = qdict_clone_shallow(options);
 | 
					    options = qdict_clone_shallow(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user