const char *vg;
const char *lv;
const char *thinpool;
+ const char *fstype;
/* snapshot specific arguments */
const char *source_lv;
return lvm_compare_lv_attr(path, 0, 't');
}
-int lvm_snapshot(const char *orig, const char *path, uint64_t size)
+static int lvm_snapshot_create_new_uuid_wrapper(void *data)
+{
+ struct lvcreate_args *args = data;
+
+ if (strcmp(args->fstype, "xfs") == 0)
+ execlp("xfs_admin", "xfs_admin", "-U", "generate", args->lv, (char *)NULL);
+
+ if (strcmp(args->fstype, "btrfs") == 0)
+ execlp("btrfstune", "btrfstune", "-f", "-u", args->lv, (char *)NULL);
+
+ return -1;
+}
+
+static int lvm_snapshot(struct lxc_storage *orig, const char *path, uint64_t size)
{
int ret;
- char *pathdup, *lv;
+ char *origsrc, *pathdup, *lv;
char sz[24];
+ char fstype[100];
char cmd_output[MAXPATHLEN];
+ char repairchar;
struct lvcreate_args cmd_args = {0};
ret = snprintf(sz, 24, "%" PRIu64 "b", size);
free(pathdup);
return -1;
}
+ repairchar = *lv;
*lv = '\0';
lv++;
TRACE("Parsed logical volume \"%s\"", lv);
* which case we cannot specify a size that's different from the
* original size.
*/
- ret = lvm_is_thin_volume(orig);
+ origsrc = lxc_storage_get_path(orig->src, "lvm");
+ ret = lvm_is_thin_volume(origsrc);
if (ret < 0) {
free(pathdup);
return -1;
} else if (ret) {
- cmd_args.thinpool = orig;
+ cmd_args.thinpool = origsrc;
}
cmd_args.lv = lv;
- cmd_args.source_lv = orig;
+ cmd_args.source_lv = origsrc;
cmd_args.size = sz;
TRACE("Creating new lvm snapshot \"%s\" of \"%s\" with size \"%s\"", lv,
- orig, sz);
+ origsrc, sz);
ret = run_command(cmd_output, sizeof(cmd_output),
lvm_snapshot_exec_wrapper, (void *)&cmd_args);
if (ret < 0) {
- ERROR("Failed to create logical volume \"%s\": %s", orig,
- cmd_output);
+ ERROR("Failed to create logical volume \"%s\": %s", lv, cmd_output);
+ free(pathdup);
+ return -1;
+ }
+
+ if (detect_fs(orig, fstype, 100) < 0) {
+ INFO("Failed to detect filesystem type for \"%s\"", origsrc);
+ free(pathdup);
+ return -1;
+ }
+
+ /* repair path */
+ lv--;
+ *lv = repairchar;
+ cmd_args.lv = pathdup;
+ cmd_args.fstype = fstype;
+ ret = run_command(cmd_output, sizeof(cmd_output),
+ lvm_snapshot_create_new_uuid_wrapper, (void *)&cmd_args);
+ if (ret < 0) {
+ ERROR("Failed to create new uuid for volume \"%s\": %s", pathdup, cmd_output);
free(pathdup);
return -1;
}
struct lxc_storage *new, uint64_t newsize)
{
int ret;
- char *newsrc, *origsrc;
+ char *newsrc;
uint64_t size = newsize;
if (is_blktype(orig)) {
size = DEFAULT_FS_SIZE;
}
- origsrc = lxc_storage_get_path(orig->src, "lvm");
newsrc = lxc_storage_get_path(new->src, "lvm");
- ret = lvm_snapshot(origsrc, newsrc, size);
+ ret = lvm_snapshot(orig, newsrc, size);
if (ret < 0) {
ERROR("Failed to create lvm \"%s\" snapshot of \"%s\"",
new->src, orig->src);
extern int lvm_compare_lv_attr(const char *path, int pos, const char expected);
extern int lvm_is_thin_volume(const char *path);
extern int lvm_is_thin_pool(const char *path);
-extern int lvm_snapshot(const char *orig, const char *path, uint64_t size);
extern int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const char *oldname, const char *cname,
const char *oldpath, const char *lxcpath, int snap,