int tapdisk_image_open_chain(const char *desc, int flags, int prt_devnum, struct list_head *head) { const char *name; int type, err; type = tapdisk_disktype_parse_params(desc, &name); if (type >= 0) return __tapdisk_image_open_chain(type, name, flags, head, prt_devnum); err = type; if (err == -ENOENT && strlen(desc) >= 3) { switch (desc[2]) { case 'c': if (!strncmp(desc, "x-chain", strlen("x-chain"))) err = tapdisk_image_open_x_chain(name, head); break; } } return err; }
int tapdisk_parse_disk_type(const char *params, const char **_path, int *_type) { int type; type = tapdisk_disktype_parse_params(params, _path); if (type < 0) return type; *_type = type; return 0; }
int tapdisk_vbd_add_secondary(td_vbd_t *vbd) { td_image_t *leaf, *second = NULL; const char *path; int type, err; DPRINTF("Adding secondary image: %s\n", vbd->secondary_name); type = tapdisk_disktype_parse_params(vbd->secondary_name, &path); if (type < 0) return type; leaf = tapdisk_vbd_first_image(vbd); if (!leaf) { err = -EINVAL; goto fail; } err = tapdisk_image_open(type, path, leaf->flags, &second); if (err) goto fail; if (second->info.size != leaf->info.size) { EPRINTF("Secondary image size %"PRIu64" != image size %"PRIu64"\n", second->info.size, leaf->info.size); err = -EINVAL; goto fail; } vbd->secondary = second; leaf->flags |= TD_IGNORE_ENOSPC; if (td_flag_test(vbd->flags, TD_OPEN_STANDBY)) { DPRINTF("In standby mode\n"); vbd->secondary_mode = TD_VBD_SECONDARY_STANDBY; } else { DPRINTF("In mirror mode\n"); vbd->secondary_mode = TD_VBD_SECONDARY_MIRROR; /* we actually need this image to also be part of the chain, * since it may already contain data */ list_add(&second->next, &leaf->next); } DPRINTF("Added secondary image\n"); return 0; fail: if (second) tapdisk_image_close(second); return err; }