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