Unverified Commit f03e93fb by Serge Hallyn Committed by GitHub

Merge pull request #1922 from brauner/2017-11-13/generate_new_uuid_for_xfs_and_btrfs_snapshots

lvm: generate new UUID for xfs + btrfs filesystems
parents af73a0bf d59f08f3
...@@ -51,6 +51,7 @@ struct lvcreate_args { ...@@ -51,6 +51,7 @@ struct lvcreate_args {
const char *vg; const char *vg;
const char *lv; const char *lv;
const char *thinpool; const char *thinpool;
const char *fstype;
/* snapshot specific arguments */ /* snapshot specific arguments */
const char *source_lv; const char *source_lv;
...@@ -313,12 +314,27 @@ int lvm_is_thin_pool(const char *path) ...@@ -313,12 +314,27 @@ int lvm_is_thin_pool(const char *path)
return lvm_compare_lv_attr(path, 0, 't'); 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; int ret;
char *pathdup, *lv; char *origsrc, *pathdup, *lv;
char sz[24]; char sz[24];
char fstype[100];
char cmd_output[MAXPATHLEN]; char cmd_output[MAXPATHLEN];
char repairchar;
struct lvcreate_args cmd_args = {0}; struct lvcreate_args cmd_args = {0};
ret = snprintf(sz, 24, "%" PRIu64 "b", size); ret = snprintf(sz, 24, "%" PRIu64 "b", size);
...@@ -339,6 +355,7 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size) ...@@ -339,6 +355,7 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size)
free(pathdup); free(pathdup);
return -1; return -1;
} }
repairchar = *lv;
*lv = '\0'; *lv = '\0';
lv++; lv++;
TRACE("Parsed logical volume \"%s\"", lv); TRACE("Parsed logical volume \"%s\"", lv);
...@@ -347,24 +364,43 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size) ...@@ -347,24 +364,43 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size)
* which case we cannot specify a size that's different from the * which case we cannot specify a size that's different from the
* original size. * 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) { if (ret < 0) {
free(pathdup); free(pathdup);
return -1; return -1;
} else if (ret) { } else if (ret) {
cmd_args.thinpool = orig; cmd_args.thinpool = origsrc;
} }
cmd_args.lv = lv; cmd_args.lv = lv;
cmd_args.source_lv = orig; cmd_args.source_lv = origsrc;
cmd_args.size = sz; cmd_args.size = sz;
TRACE("Creating new lvm snapshot \"%s\" of \"%s\" with size \"%s\"", lv, TRACE("Creating new lvm snapshot \"%s\" of \"%s\" with size \"%s\"", lv,
orig, sz); origsrc, sz);
ret = run_command(cmd_output, sizeof(cmd_output), ret = run_command(cmd_output, sizeof(cmd_output),
lvm_snapshot_exec_wrapper, (void *)&cmd_args); lvm_snapshot_exec_wrapper, (void *)&cmd_args);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create logical volume \"%s\": %s", orig, ERROR("Failed to create logical volume \"%s\": %s", lv, cmd_output);
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); free(pathdup);
return -1; return -1;
} }
...@@ -524,7 +560,7 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig, ...@@ -524,7 +560,7 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
struct lxc_storage *new, uint64_t newsize) struct lxc_storage *new, uint64_t newsize)
{ {
int ret; int ret;
char *newsrc, *origsrc; char *newsrc;
uint64_t size = newsize; uint64_t size = newsize;
if (is_blktype(orig)) { if (is_blktype(orig)) {
...@@ -537,10 +573,9 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig, ...@@ -537,10 +573,9 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
size = DEFAULT_FS_SIZE; size = DEFAULT_FS_SIZE;
} }
origsrc = lxc_storage_get_path(orig->src, "lvm");
newsrc = lxc_storage_get_path(new->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) { if (ret < 0) {
ERROR("Failed to create lvm \"%s\" snapshot of \"%s\"", ERROR("Failed to create lvm \"%s\" snapshot of \"%s\"",
new->src, orig->src); new->src, orig->src);
......
...@@ -40,7 +40,6 @@ extern int lvm_umount(struct lxc_storage *bdev); ...@@ -40,7 +40,6 @@ extern int lvm_umount(struct lxc_storage *bdev);
extern int lvm_compare_lv_attr(const char *path, int pos, const char expected); 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_volume(const char *path);
extern int lvm_is_thin_pool(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, extern int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const char *oldname, const char *cname, const char *oldname, const char *cname,
const char *oldpath, const char *lxcpath, int snap, const char *oldpath, const char *lxcpath, int snap,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment