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; }
static int tapdisk_vbd_add_local_cache(td_vbd_t *vbd) { td_image_t *cache, *parent; int err; parent = tapdisk_vbd_first_image(vbd); if (tapdisk_vbd_is_last_image(vbd, parent)) { DPRINTF("Single-image chain, nothing to cache"); return 0; } cache = tapdisk_image_allocate(parent->name, DISK_TYPE_LCACHE, parent->flags); if (!cache) return -ENOMEM; /* try to load existing cache */ err = td_load(cache); if (!err) goto done; cache->driver = tapdisk_driver_allocate(cache->type, cache->name, cache->flags); if (!cache->driver) { err = -ENOMEM; goto fail; } cache->driver->info = parent->driver->info; /* try to open new cache */ err = td_open(cache); if (!err) goto done; fail: tapdisk_image_free(cache); return err; done: /* insert cache right above leaf image */ list_add(&cache->next, &parent->next); DPRINTF("Added local_cache driver\n"); return 0; }
static int tapdisk_vbd_add_dirty_log(td_vbd_t *vbd) { int err; td_driver_t *driver; td_image_t *log, *parent; driver = NULL; log = NULL; parent = tapdisk_vbd_first_image(vbd); log = tapdisk_image_allocate(parent->name, DISK_TYPE_LOG, parent->flags); if (!log) return -ENOMEM; driver = tapdisk_driver_allocate(log->type, log->name, log->flags); if (!driver) { err = -ENOMEM; goto fail; } driver->info = parent->driver->info; log->driver = driver; err = td_open(log); if (err) goto fail; tapdisk_vbd_add_image(vbd, log); return 0; fail: tapdisk_image_free(log); return err; }