int ploop_di_remove_image(struct ploop_disk_images_data *di, const char *guid, int renew_top_uuid, char **fname) { int snap_id, image_id, nr_ch; struct ploop_image_data *image = NULL; struct ploop_snapshot_data *snapshot = NULL; snap_id = find_snapshot_by_guid(di, guid); if (snap_id == -1) { ploop_err(0, "Unable to find snapshot by uuid %s", guid); return SYSEXIT_PARAM; } snapshot = di->snapshots[snap_id]; image_id = find_image_idx_by_guid(di, guid); if (image_id == -1) { ploop_err(0, "Unable to find image by uuid %s", guid); return SYSEXIT_PARAM; } nr_ch = ploop_get_child_count_by_uuid(di, guid); if (nr_ch != 0) { ploop_err(0, "Unable to delete snapshot %s: " "it has %d child%s", guid, nr_ch, (nr_ch == 1) ? "" : "ren"); return SYSEXIT_PARAM; } if (guidcmp(snapshot->parent_guid, NONE_UUID) == 0) { ploop_err(0, "Unable to delete image %s: it is a base image", guid); return SYSEXIT_PARAM; } image = di->images[image_id]; if (fname != NULL) { *fname = strdup(image->file); if (*fname == NULL) return SYSEXIT_MALLOC; } ploop_log(3, "del snapshot %s", guid); // update top uuid if (renew_top_uuid && guidcmp(guid, di->top_guid) == 0) ploop_di_change_guid(di, snapshot->parent_guid, TOPDELTA_UUID); remove_data_from_array((void**)di->snapshots, di->nsnapshots, snap_id); di->nsnapshots--; remove_data_from_array((void**)di->images, di->nimages, image_id); di->nimages--; free_snapshot_data(snapshot); free_image_data(image); return 0; }
static int is_old_snapshot_format(struct ploop_disk_images_data *di) { if (di->top_guid != NULL && !guidcmp(di->top_guid, TOPDELTA_UUID)) return 0; ploop_err(0, "Snapshot is in old format"); return 1; }
void ploop_di_change_guid(struct ploop_disk_images_data *di, const char *guid, const char *new_guid) { int i; for (i = 0; i < di->nimages; i++) if (guidcmp(di->images[i]->guid, guid) == 0) strcpy(di->images[i]->guid, new_guid); for (i = 0; i < di->nsnapshots; i++) { if (guidcmp(di->snapshots[i]->guid, guid) == 0) strcpy(di->snapshots[i]->guid, new_guid); if (guidcmp(di->snapshots[i]->parent_guid, guid) == 0) strcpy(di->snapshots[i]->parent_guid, new_guid); } if (guidcmp(di->top_guid, guid) == 0) strcpy(di->top_guid, new_guid); }
int ploop_get_child_count_by_uuid(struct ploop_disk_images_data *di, const char *guid) { int i, n = 0; for (i = 0; i < di->nsnapshots; i++) if (guidcmp(di->snapshots[i]->parent_guid, guid) == 0) n++; return n; }
int find_image_idx_by_guid(struct ploop_disk_images_data *di, const char *guid) { int i; for (i = 0; i < di->nimages; i++) { if (!guidcmp(guid, di->images[i]->guid)) return i; } return -1; }
/** * efi_st_get_config_table() - get configuration table * * @guid: GUID of the configuration table * Return: pointer to configuration table or NULL */ static void *efi_st_get_config_table(const efi_guid_t *guid) { size_t i; for (i = 0; i < systab.nr_tables; i++) { if (!guidcmp(guid, &systemtab->tables[i].guid)) return systemtab->tables[i].table; } return NULL; }
char *ploop_find_parent_by_guid(struct ploop_disk_images_data *di, const char *guid) { int i; i = find_snapshot_by_guid(di, guid); if (i == -1) return NULL; if (guidcmp(di->snapshots[i]->parent_guid, NONE_UUID) == 0) return NULL; return di->snapshots[i]->parent_guid; }
int find_snapshot_by_guid(struct ploop_disk_images_data *di, const char *guid) { int i; if (guid == NULL) return -1; for (i = 0; i < di->nsnapshots; i++) if (guidcmp(di->snapshots[i]->guid, guid) == 0) return i; return -1; }
int ploop_get_child_by_uuid(struct ploop_disk_images_data *di, const char *guid, char **child_guid) { int i; for (i = 0; i < di->nsnapshots; i++) { if (guidcmp(di->snapshots[i]->parent_guid, guid) == 0) { *child_guid = di->snapshots[i]->guid; return 0; } } return -1; }
/** * get_guid_text - get string of protocol guid * @guid: Protocol guid * Return: String * * Return string for display to represent the protocol. */ static const char *get_guid_text(const efi_guid_t *guid) { int i; for (i = 0; i < ARRAY_SIZE(guid_list); i++) if (!guidcmp(&guid_list[i].guid, guid)) break; if (i != ARRAY_SIZE(guid_list)) return guid_list[i].text; else return NULL; }
/* Convert to new format with constant TopGUID */ static int convert_disk_descriptor(struct ploop_disk_images_data *di) { if (di->top_guid == NULL) { ploop_err(0, "Invalid DiskDescriptor.xml: TopGUID not found"); return -1; } if (!guidcmp(di->top_guid, TOPDELTA_UUID)) return 0; ploop_log(0, "DiskDescriptor.xml is in old format: converting"); if ((find_image_by_guid(di, TOPDELTA_UUID) != NULL) || (find_snapshot_by_guid(di, TOPDELTA_UUID) != -1)) { ploop_err(0, "Can't convert: %s is in use", TOPDELTA_UUID); return -1; } ploop_log(0, "Changing %s to %s", di->top_guid, TOPDELTA_UUID); ploop_di_change_guid(di, di->top_guid, TOPDELTA_UUID); return 0; }
int ploop_di_merge_image(struct ploop_disk_images_data *di, const char *guid, char **fname) { int i, snap_id, image_id, nr_ch; struct ploop_image_data *image = NULL; struct ploop_snapshot_data *snapshot = NULL; snap_id = find_snapshot_by_guid(di, guid); if (snap_id == -1) { ploop_err(0, "Unable to find snapshot by uuid %s", guid); return SYSEXIT_PARAM; } snapshot = di->snapshots[snap_id]; image_id = find_image_idx_by_guid(di, guid); if (image_id == -1) { ploop_err(0, "Unable to find image by uuid %s", guid); return SYSEXIT_PARAM; } nr_ch = ploop_get_child_count_by_uuid(di, snapshot->parent_guid); if (nr_ch > 1) { ploop_err(0, "Unable to merge snapshot %s: " "it has %d children", guid, nr_ch); return SYSEXIT_PARAM; } if (guidcmp(snapshot->parent_guid, NONE_UUID) == 0) { ploop_err(0, "Unable to merge image %s: it is a base image", guid); return SYSEXIT_PARAM; } image = di->images[image_id]; if (fname != NULL) { *fname = strdup(image->file); if (*fname == NULL) return SYSEXIT_MALLOC; } ploop_log(3, "merge snapshot %s -> %s", snapshot->guid, snapshot->parent_guid); /* Caller passed child_guid S2 to delete S1 (S1 <- S2 <- S3) (S2 <- S3) * so it has merge S2 to S1 and we should update all S1 referrences to S2 */ for (i = 0; i < di->nsnapshots; i++) { if (guidcmp(di->snapshots[i]->guid, snapshot->parent_guid) == 0) { strcpy(di->snapshots[i]->guid, guid); /* preserve temporary flag */ di->snapshots[i]->temporary = snapshot->temporary; } } for (i = 0; i < di->nimages; i++) if (guidcmp(di->images[i]->guid, snapshot->parent_guid) == 0) strcpy(di->images[i]->guid, guid); remove_data_from_array((void**)di->snapshots, di->nsnapshots, snap_id); di->nsnapshots--; remove_data_from_array((void**)di->images, di->nimages, image_id); di->nimages--; if (guidcmp(snapshot->guid, TOPDELTA_UUID) == 0) ploop_di_change_guid(di, snapshot->parent_guid, TOPDELTA_UUID); free_snapshot_data(snapshot); free_image_data(image); return 0; }
void asf_HeaderParse ( asf_header_t *hdr, uint8_t *p_header, int i_header ) { var_buffer_t buffer; guid_t guid; uint64_t i_size; hdr->i_file_size = 0; hdr->i_data_packets_count = 0; hdr->i_min_data_packet_size = 0; for( unsigned i = 0; i < 128; i++ ) { hdr->stream[i].i_cat = ASF_CODEC_TYPE_UNKNOWN; hdr->stream[i].i_selected = 0; hdr->stream[i].i_bitrate = -1; } var_buffer_initread( &buffer, p_header, i_header ); var_buffer_getguid( &buffer, &guid ); if( !guidcmp( &guid, &asf_object_header_guid ) ) { /* ERROR: */ } var_buffer_getmemory( &buffer, NULL, 30 - 16 ); for( ;; ) { var_buffer_getguid( &buffer, &guid ); i_size = var_buffer_get64( &buffer ); if( guidcmp( &guid, &asf_object_file_properties_guid ) ) { var_buffer_getmemory( &buffer, NULL, 16 ); hdr->i_file_size = var_buffer_get64( &buffer ); var_buffer_getmemory( &buffer, NULL, 8 ); hdr->i_data_packets_count = var_buffer_get64( &buffer ); var_buffer_getmemory( &buffer, NULL, 8+8+8+4); hdr->i_min_data_packet_size = var_buffer_get32( &buffer ); var_buffer_getmemory( &buffer, NULL, i_size - 24 - 16 - 8 - 8 - 8 - 8-8-8-4 - 4); } else if( guidcmp( &guid, &asf_object_header_extension_guid ) ) { /* Enter it */ var_buffer_getmemory( &buffer, NULL, 46 - 24 ); } else if( guidcmp( &guid, &asf_object_extended_stream_properties_guid ) ) { /* Grrrrrr */ int16_t i_count1, i_count2; int i_subsize; var_buffer_getmemory( &buffer, NULL, 84 - 24 ); i_count1 = var_buffer_get16( &buffer ); i_count2 = var_buffer_get16( &buffer ); i_subsize = 88; for( int i = 0; i < i_count1; i++ ) { int i_len; var_buffer_get16( &buffer ); i_len = var_buffer_get16( &buffer ); var_buffer_getmemory( &buffer, NULL, i_len ); i_subsize += 4 + i_len; } for( int i = 0; i < i_count2; i++ ) { int i_len; var_buffer_getmemory( &buffer, NULL, 16 + 2 ); i_len = var_buffer_get32( &buffer ); var_buffer_getmemory( &buffer, NULL, i_len ); i_subsize += 16 + 6 + i_len; } if( i_size - i_subsize <= 24 ) { var_buffer_getmemory( &buffer, NULL, i_size - i_subsize ); } /* It's a hack we just skip the first part of the object until * the embed stream properties if any (ugly, but whose fault ?) */ } else if( guidcmp( &guid, &asf_object_stream_properties_guid ) ) { int i_stream_id; guid_t stream_type; var_buffer_getguid( &buffer, &stream_type ); var_buffer_getmemory( &buffer, NULL, 32 ); i_stream_id = var_buffer_get8( &buffer ) & 0x7f; var_buffer_getmemory( &buffer, NULL, i_size - 24 - 32 - 16 - 1); if( guidcmp( &stream_type, &asf_object_stream_type_video ) ) { hdr->stream[i_stream_id].i_cat = ASF_CODEC_TYPE_VIDEO; } else if( guidcmp( &stream_type, &asf_object_stream_type_audio ) ) { hdr->stream[i_stream_id].i_cat = ASF_CODEC_TYPE_AUDIO; } else { hdr->stream[i_stream_id].i_cat = ASF_CODEC_TYPE_UNKNOWN; } } else if ( guidcmp( &guid, &asf_object_stream_bitrate_properties ) ) { int i_count; uint8_t i_stream_id; i_count = var_buffer_get16( &buffer ); i_size -= 2; while( i_count > 0 ) { i_stream_id = var_buffer_get16( &buffer )&0x7f; hdr->stream[i_stream_id].i_bitrate = var_buffer_get32( &buffer ); i_count--; i_size -= 6; } var_buffer_getmemory( &buffer, NULL, i_size - 24 ); } else { // skip unknown guid var_buffer_getmemory( &buffer, NULL, i_size - 24 ); } if( var_buffer_readempty( &buffer ) ) return; } }
static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; EFI_ENTRY("%p, %p, %p, %p", file, info_type, buffer_size, buffer); if (!guidcmp(info_type, &efi_file_info_guid)) { struct efi_file_info *info = buffer; char *filename = basename(fh); unsigned int required_size; loff_t file_size; /* check buffer size: */ required_size = sizeof(*info) + 2 * (strlen(filename) + 1); if (*buffer_size < required_size) { *buffer_size = required_size; ret = EFI_BUFFER_TOO_SMALL; goto error; } if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } if (fs_size(fh->path, &file_size)) { ret = EFI_DEVICE_ERROR; goto error; } memset(info, 0, required_size); info->size = required_size; info->file_size = file_size; info->physical_size = file_size; if (fh->isdir) info->attribute |= EFI_FILE_DIRECTORY; ascii2unicode((u16 *)info->file_name, filename); } else if (!guidcmp(info_type, &efi_file_system_info_guid)) { struct efi_file_system_info *info = buffer; disk_partition_t part; efi_uintn_t required_size; int r; if (fh->fs->part >= 1) r = part_get_info(fh->fs->desc, fh->fs->part, &part); else r = part_get_info_whole_disk(fh->fs->desc, &part); if (r < 0) { ret = EFI_DEVICE_ERROR; goto error; } required_size = sizeof(info) + 2 * (strlen((const char *)part.name) + 1); if (*buffer_size < required_size) { *buffer_size = required_size; ret = EFI_BUFFER_TOO_SMALL; goto error; } memset(info, 0, required_size); info->size = required_size; info->read_only = true; info->volume_size = part.size * part.blksz; info->free_space = 0; info->block_size = part.blksz; /* * TODO: The volume label is not available in U-Boot. * Use the partition name as substitute. */ ascii2unicode((u16 *)info->volume_label, (const char *)part.name); } else { ret = EFI_UNSUPPORTED; } error: return EFI_EXIT(ret); }