Revision b1b1d783 block.c
b/block.c | ||
---|---|---|
3123 | 3123 |
return -ENOTSUP; |
3124 | 3124 |
} |
3125 | 3125 |
|
3126 |
/* backing_file can either be relative, or absolute, or a protocol. If it is |
|
3127 |
* relative, it must be relative to the chain. So, passing in bs->filename |
|
3128 |
* from a BDS as backing_file should not be done, as that may be relative to |
|
3129 |
* the CWD rather than the chain. */ |
|
3126 | 3130 |
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, |
3127 | 3131 |
const char *backing_file) |
3128 | 3132 |
{ |
3129 |
if (!bs->drv) { |
|
3133 |
char *filename_full = NULL; |
|
3134 |
char *backing_file_full = NULL; |
|
3135 |
char *filename_tmp = NULL; |
|
3136 |
int is_protocol = 0; |
|
3137 |
BlockDriverState *curr_bs = NULL; |
|
3138 |
BlockDriverState *retval = NULL; |
|
3139 |
|
|
3140 |
if (!bs || !bs->drv || !backing_file) { |
|
3130 | 3141 |
return NULL; |
3131 | 3142 |
} |
3132 | 3143 |
|
3133 |
if (bs->backing_hd) { |
|
3134 |
if (strcmp(bs->backing_file, backing_file) == 0) { |
|
3135 |
return bs->backing_hd; |
|
3144 |
filename_full = g_malloc(PATH_MAX); |
|
3145 |
backing_file_full = g_malloc(PATH_MAX); |
|
3146 |
filename_tmp = g_malloc(PATH_MAX); |
|
3147 |
|
|
3148 |
is_protocol = path_has_protocol(backing_file); |
|
3149 |
|
|
3150 |
for (curr_bs = bs; curr_bs->backing_hd; curr_bs = curr_bs->backing_hd) { |
|
3151 |
|
|
3152 |
/* If either of the filename paths is actually a protocol, then |
|
3153 |
* compare unmodified paths; otherwise make paths relative */ |
|
3154 |
if (is_protocol || path_has_protocol(curr_bs->backing_file)) { |
|
3155 |
if (strcmp(backing_file, curr_bs->backing_file) == 0) { |
|
3156 |
retval = curr_bs->backing_hd; |
|
3157 |
break; |
|
3158 |
} |
|
3136 | 3159 |
} else { |
3137 |
return bdrv_find_backing_image(bs->backing_hd, backing_file); |
|
3160 |
/* If not an absolute filename path, make it relative to the current |
|
3161 |
* image's filename path */ |
|
3162 |
path_combine(filename_tmp, PATH_MAX, curr_bs->filename, |
|
3163 |
backing_file); |
|
3164 |
|
|
3165 |
/* We are going to compare absolute pathnames */ |
|
3166 |
if (!realpath(filename_tmp, filename_full)) { |
|
3167 |
continue; |
|
3168 |
} |
|
3169 |
|
|
3170 |
/* We need to make sure the backing filename we are comparing against |
|
3171 |
* is relative to the current image filename (or absolute) */ |
|
3172 |
path_combine(filename_tmp, PATH_MAX, curr_bs->filename, |
|
3173 |
curr_bs->backing_file); |
|
3174 |
|
|
3175 |
if (!realpath(filename_tmp, backing_file_full)) { |
|
3176 |
continue; |
|
3177 |
} |
|
3178 |
|
|
3179 |
if (strcmp(backing_file_full, filename_full) == 0) { |
|
3180 |
retval = curr_bs->backing_hd; |
|
3181 |
break; |
|
3182 |
} |
|
3138 | 3183 |
} |
3139 | 3184 |
} |
3140 | 3185 |
|
3141 |
return NULL; |
|
3186 |
g_free(filename_full); |
|
3187 |
g_free(backing_file_full); |
|
3188 |
g_free(filename_tmp); |
|
3189 |
return retval; |
|
3142 | 3190 |
} |
3143 | 3191 |
|
3144 | 3192 |
int bdrv_get_backing_file_depth(BlockDriverState *bs) |
Also available in: Unified diff