int ploop_di_add_image(struct ploop_disk_images_data *di, const char *fname, const char *guid, const char *parent_guid) { int ret; char *top_guid; top_guid = strdup(guid); if (top_guid == NULL) return SYSEXIT_MALLOC; ret = ploop_add_image_entry(di, fname, guid); if (ret) { free(top_guid); return ret; } ret = ploop_add_snapshot_entry(di, guid, parent_guid, 0); if (ret) { free(top_guid); return ret; } ploop_log(3, "Adding snapshot %s", guid); free(di->top_guid); di->top_guid = top_guid; return 0; }
static int parse_xml(const char *basedir, xmlNode *root_node, struct ploop_disk_images_data *di) { xmlNode *cur_node, *node; char image[PATH_MAX]; const char *data = NULL; const char *file = NULL; const char *guid = NULL; const char *parent_guid = NULL; __u64 val; int is_preallocated = 0; int mode = PLOOP_EXPANDED_MODE; int n; cur_node = seek(root_node, "/Disk_Parameters"); ERR(cur_node, "/Disk_Parameters"); node = seek(cur_node, "Disk_size"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) == 0) di->size = val; } node = seek(cur_node, "Max_delta_size"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) == 0) di->max_delta_size = val; } node = seek(cur_node, "Cylinders"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) == 0) di->cylinders = (unsigned)val; } node = seek(cur_node, "Heads"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) == 0) di->heads = (unsigned)val; } node = seek(cur_node, "Sectors"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) == 0) di->sectors= (unsigned)val; } cur_node = seek(root_node, "/StorageData/Storage"); ERR(cur_node, "/StorageData/Storage"); for (n = 0; cur_node; cur_node = cur_node->next, n++) { if (cur_node->type != XML_ELEMENT_NODE) continue; if (n > 0) { ploop_err(0, "Invalid disk descriptor file format:" " splitted disk is not supported"); return -1; } node = seek(cur_node, "Blocksize"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val)) { ploop_err(0, "Invalid disk descriptor file format:" " Invalid Blocksize %s", data); return -1; } di->blocksize = (unsigned)val; } node = seek(cur_node, "Preallocated"); if (node != NULL) { data = get_element_txt(node); if (parse_ul(data, &val) != 0 || val > 1) { ploop_err(0, "Invalid disk descriptor file format:" " Invalid Preallocated tag"); return -1; } is_preallocated = val; } } cur_node = seek(root_node, "/StorageData/Storage/Image"); ERR(cur_node, "/StorageData/Storage/Image"); for (; cur_node; cur_node = cur_node->next) { if (cur_node->type != XML_ELEMENT_NODE) continue; guid = NULL; node = seek(cur_node, "GUID"); if (node != NULL) { guid = get_element_txt(node); if (guid == NULL) guid = ""; } ERR(guid, "GUID"); node = seek(cur_node, "Type"); if (node != NULL) { data = get_element_txt(node); if (data != NULL && !strcmp(data, "Plain")) mode = PLOOP_RAW_MODE; } file = NULL; node = seek(cur_node, "File"); if (node != NULL) { file = get_element_txt(node); if (file != NULL) { if (basedir[0] != 0 && file[0] != '/') snprintf(image, sizeof(image), "%s%s", basedir, file); else snprintf(image, sizeof(image), "%s", file); } } ERR(file, "File"); if (ploop_add_image_entry(di, image, guid)) return -1; } if (is_preallocated) { if (mode == PLOOP_RAW_MODE) { ploop_err(0, "Invalid disk descriptor file format:" " Preallocated is not compatible with Plain image"); return -1; } di->mode = PLOOP_EXPANDED_PREALLOCATED_MODE; } else { di->mode = mode; } cur_node = seek(root_node, "/Snapshots"); ERR(cur_node, "/Snapshots"); node = seek(cur_node, "TopGUID"); if (node != NULL) { data = get_element_txt(node); ERR(data, "TopGUID"); di->top_guid = strdup(data); } cur_node = seek(root_node, "/Snapshots/Shot"); if (cur_node != NULL) { for (; cur_node; cur_node = cur_node->next) { int temporary = 0; if (cur_node->type != XML_ELEMENT_NODE) continue; guid = NULL; node = seek(cur_node, "GUID"); if (node != NULL) guid = get_element_txt(node); ERR(guid, "Snapshots GUID"); parent_guid = NULL; node = seek(cur_node, "ParentGUID"); if (node != NULL) parent_guid = get_element_txt(node); ERR(parent_guid, "ParentGUID"); node = seek(cur_node, "Temporary"); if (node != NULL) temporary = 1; if (ploop_add_snapshot_entry(di, guid, parent_guid, temporary)) return -1; } } return 0; }