mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-09 17:18:56 +00:00
Merge pull request #2519 from 2xsec/bugfix
fix assignment of signed to bigger unsigned issue
This commit is contained in:
commit
d851c59308
@ -989,7 +989,8 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
|
|||||||
|
|
||||||
int lxc_allocate_ttys(struct lxc_conf *conf)
|
int lxc_allocate_ttys(struct lxc_conf *conf)
|
||||||
{
|
{
|
||||||
int i, ret;
|
size_t i;
|
||||||
|
int ret;
|
||||||
struct lxc_tty_info *ttys = &conf->ttys;
|
struct lxc_tty_info *ttys = &conf->ttys;
|
||||||
|
|
||||||
/* no tty in the configuration */
|
/* no tty in the configuration */
|
||||||
@ -1007,7 +1008,7 @@ int lxc_allocate_ttys(struct lxc_conf *conf)
|
|||||||
tty->slave = -EBADF;
|
tty->slave = -EBADF;
|
||||||
ret = openpty(&tty->master, &tty->slave, NULL, NULL, NULL);
|
ret = openpty(&tty->master, &tty->slave, NULL, NULL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to create tty %d", i);
|
SYSERROR("Failed to create tty %zu", i);
|
||||||
ttys->max = i;
|
ttys->max = i;
|
||||||
lxc_delete_tty(ttys);
|
lxc_delete_tty(ttys);
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
@ -1015,7 +1016,7 @@ int lxc_allocate_ttys(struct lxc_conf *conf)
|
|||||||
|
|
||||||
ret = ttyname_r(tty->slave, tty->name, sizeof(tty->name));
|
ret = ttyname_r(tty->slave, tty->name, sizeof(tty->name));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to retrieve name of tty %d slave", i);
|
SYSERROR("Failed to retrieve name of tty %zu slave", i);
|
||||||
ttys->max = i;
|
ttys->max = i;
|
||||||
lxc_delete_tty(ttys);
|
lxc_delete_tty(ttys);
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
@ -678,7 +678,7 @@ bool __criu_check_feature(uint64_t *features_to_check)
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
uint64_t current_bit = 0;
|
uint64_t current_bit = 0;
|
||||||
int ret;
|
int ret;
|
||||||
int features = *features_to_check;
|
uint64_t features = *features_to_check;
|
||||||
/* Feature checking is currently always like
|
/* Feature checking is currently always like
|
||||||
* criu check --feature <feature-name>
|
* criu check --feature <feature-name>
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +59,7 @@ lxc_log_define(btrfs, lxc);
|
|||||||
* simply return a.
|
* simply return a.
|
||||||
*/
|
*/
|
||||||
char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
||||||
int name_len)
|
u16 name_len)
|
||||||
{
|
{
|
||||||
struct btrfs_ioctl_ino_lookup_args args;
|
struct btrfs_ioctl_ino_lookup_args args;
|
||||||
int ret;
|
int ret;
|
||||||
@ -78,9 +78,9 @@ char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
|||||||
name);
|
name);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
} else
|
||||||
INFO("Got path for %llu %llu - %s\n",
|
INFO("Got path for %llu %llu - %s",
|
||||||
(unsigned long long) objid, (unsigned long long) dir_id,
|
(unsigned long long) objid, (unsigned long long) dir_id,
|
||||||
name);
|
name);
|
||||||
|
|
||||||
if (args.name[0]) {
|
if (args.name[0]) {
|
||||||
/*
|
/*
|
||||||
@ -97,7 +97,7 @@ char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
|||||||
|
|
||||||
retlen = strlcat(retpath, name, len);
|
retlen = strlcat(retpath, name, len);
|
||||||
if (retlen >= len) {
|
if (retlen >= len) {
|
||||||
ERROR("Failed to append name - %s\n", name);
|
ERROR("Failed to append name - %s", name);
|
||||||
free(retpath);
|
free(retpath);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
|||||||
|
|
||||||
retlen = strlcat(retpath, name, len);
|
retlen = strlcat(retpath, name, len);
|
||||||
if (retlen >= len) {
|
if (retlen >= len) {
|
||||||
ERROR("Failed to append name - %s\n", name);
|
ERROR("Failed to append name - %s", name);
|
||||||
free(retpath);
|
free(retpath);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -131,9 +131,10 @@ int btrfs_list_get_path_rootid(int fd, u64 *treeid)
|
|||||||
|
|
||||||
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSWARN("Warning: can't perform the search");
|
SYSWARN("Can't perform the search");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*treeid = args.treeid;
|
*treeid = args.treeid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -147,6 +148,7 @@ bool is_btrfs_fs(const char *path)
|
|||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sargs.space_slots = 0;
|
sargs.space_slots = 0;
|
||||||
sargs.total_spaces = 0;
|
sargs.total_spaces = 0;
|
||||||
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs);
|
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs);
|
||||||
@ -293,9 +295,10 @@ int btrfs_same_fs(const char *orig, const char *new)
|
|||||||
|
|
||||||
fd_orig = open(orig, O_RDONLY);
|
fd_orig = open(orig, O_RDONLY);
|
||||||
if (fd_orig < 0) {
|
if (fd_orig < 0) {
|
||||||
SYSERROR("Error opening original rootfs %s", orig);
|
SYSERROR("Failed to open original rootfs %s", orig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl(fd_orig, BTRFS_IOC_FS_INFO, &orig_args);
|
ret = ioctl(fd_orig, BTRFS_IOC_FS_INFO, &orig_args);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("BTRFS_IOC_FS_INFO %s", orig);
|
SYSERROR("BTRFS_IOC_FS_INFO %s", orig);
|
||||||
@ -304,10 +307,11 @@ int btrfs_same_fs(const char *orig, const char *new)
|
|||||||
|
|
||||||
fd_new = open(new, O_RDONLY);
|
fd_new = open(new, O_RDONLY);
|
||||||
if (fd_new < 0) {
|
if (fd_new < 0) {
|
||||||
SYSERROR("Error opening new container dir %s", new);
|
SYSERROR("Failed to open new container dir %s", new);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl(fd_new, BTRFS_IOC_FS_INFO, &new_args);
|
ret = ioctl(fd_new, BTRFS_IOC_FS_INFO, &new_args);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("BTRFS_IOC_FS_INFO %s", new);
|
SYSERROR("BTRFS_IOC_FS_INFO %s", new);
|
||||||
@ -318,12 +322,16 @@ int btrfs_same_fs(const char *orig, const char *new)
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (fd_new != -1)
|
if (fd_new != -1)
|
||||||
close(fd_new);
|
close(fd_new);
|
||||||
|
|
||||||
if (fd_orig != -1)
|
if (fd_orig != -1)
|
||||||
close(fd_orig);
|
close(fd_orig);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,12 +373,15 @@ int btrfs_snapshot(const char *orig, const char *new)
|
|||||||
out:
|
out:
|
||||||
if (fddst != -1)
|
if (fddst != -1)
|
||||||
close(fddst);
|
close(fddst);
|
||||||
|
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
free(newfull);
|
free(newfull);
|
||||||
|
|
||||||
if (saved_errno >= 0)
|
if (saved_errno >= 0)
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +394,7 @@ int btrfs_snapshot_wrapper(void *data)
|
|||||||
ERROR("Failed to setgid to 0");
|
ERROR("Failed to setgid to 0");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setgroups(0, NULL) < 0)
|
if (setgroups(0, NULL) < 0)
|
||||||
WARN("Failed to clear groups");
|
WARN("Failed to clear groups");
|
||||||
|
|
||||||
@ -461,6 +473,7 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
|
|||||||
/* rsync the contents from source to target */
|
/* rsync the contents from source to target */
|
||||||
data.orig = orig;
|
data.orig = orig;
|
||||||
data.new = new;
|
data.new = new;
|
||||||
|
|
||||||
if (am_guest_unpriv()) {
|
if (am_guest_unpriv()) {
|
||||||
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
|
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
|
||||||
&data, "lxc_storage_rsync_exec_wrapper");
|
&data, "lxc_storage_rsync_exec_wrapper");
|
||||||
@ -514,7 +527,7 @@ bool btrfs_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
|
|||||||
ret = btrfs_snapshot(orig->src, new->dest);
|
ret = btrfs_snapshot(orig->src, new->dest);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to create btrfs snapshot \"%s\" from \"%s\"",
|
SYSERROR("Failed to create btrfs snapshot \"%s\" from \"%s\"",
|
||||||
new->dest, orig->dest);
|
new->dest, orig->dest);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,13 +543,13 @@ static int btrfs_do_destroy_subvol(const char *path)
|
|||||||
char *p, *newfull = strdup(path);
|
char *p, *newfull = strdup(path);
|
||||||
|
|
||||||
if (!newfull) {
|
if (!newfull) {
|
||||||
ERROR("Error: out of memory");
|
ERROR("Out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = strrchr(newfull, '/');
|
p = strrchr(newfull, '/');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
ERROR("bad path: %s", path);
|
ERROR("Invalid path: %s", path);
|
||||||
free(newfull);
|
free(newfull);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -544,7 +557,7 @@ static int btrfs_do_destroy_subvol(const char *path)
|
|||||||
|
|
||||||
fd = open(newfull, O_RDONLY);
|
fd = open(newfull, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
SYSERROR("Error opening %s", newfull);
|
SYSERROR("Failed to open %s", newfull);
|
||||||
free(newfull);
|
free(newfull);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -558,7 +571,7 @@ static int btrfs_do_destroy_subvol(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
|
ret = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
|
||||||
INFO("btrfs: snapshot destroy ioctl returned %d for %s", ret, path);
|
INFO("IOCTL for destroying snapshot returned %d for %s", ret, path);
|
||||||
if (ret < 0 && errno == EPERM)
|
if (ret < 0 && errno == EPERM)
|
||||||
ERROR("Is the rootfs mounted with -o user_subvol_rm_allowed?");
|
ERROR("Is the rootfs mounted with -o user_subvol_rm_allowed?");
|
||||||
|
|
||||||
@ -570,12 +583,14 @@ static int btrfs_do_destroy_subvol(const char *path)
|
|||||||
static int get_btrfs_tree_idx(struct my_btrfs_tree *tree, u64 id)
|
static int get_btrfs_tree_idx(struct my_btrfs_tree *tree, u64 id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!tree)
|
if (!tree)
|
||||||
return -1;
|
return -1;
|
||||||
for (i = 0; i < tree->num; i++) {
|
|
||||||
|
for (i = 0; i < tree->num; i++)
|
||||||
if (tree->nodes[i].objid == id)
|
if (tree->nodes[i].objid == id)
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,11 +602,13 @@ static struct my_btrfs_tree *create_my_btrfs_tree(u64 id, const char *path,
|
|||||||
tree = malloc(sizeof(struct my_btrfs_tree));
|
tree = malloc(sizeof(struct my_btrfs_tree));
|
||||||
if (!tree)
|
if (!tree)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tree->nodes = malloc(sizeof(struct mytree_node));
|
tree->nodes = malloc(sizeof(struct mytree_node));
|
||||||
if (!tree->nodes) {
|
if (!tree->nodes) {
|
||||||
free(tree);
|
free(tree);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->num = 1;
|
tree->num = 1;
|
||||||
tree->nodes[0].dirname = NULL;
|
tree->nodes[0].dirname = NULL;
|
||||||
tree->nodes[0].name = strdup(path);
|
tree->nodes[0].name = strdup(path);
|
||||||
@ -600,13 +617,14 @@ static struct my_btrfs_tree *create_my_btrfs_tree(u64 id, const char *path,
|
|||||||
free(tree);
|
free(tree);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->nodes[0].parentid = 0;
|
tree->nodes[0].parentid = 0;
|
||||||
tree->nodes[0].objid = id;
|
tree->nodes[0].objid = id;
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool update_tree_node(struct mytree_node *n, u64 id, u64 parent,
|
static bool update_tree_node(struct mytree_node *n, u64 id, u64 parent,
|
||||||
char *name, int name_len, char *dirname)
|
char *name, u16 name_len, char *dirname)
|
||||||
{
|
{
|
||||||
if (id)
|
if (id)
|
||||||
n->objid = id;
|
n->objid = id;
|
||||||
@ -634,11 +652,12 @@ static bool update_tree_node(struct mytree_node *n, u64 id, u64 parent,
|
|||||||
|
|
||||||
(void)strlcpy(n->dirname, dirname, len + 1);
|
(void)strlcpy(n->dirname, dirname, len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool add_btrfs_tree_node(struct my_btrfs_tree *tree, u64 id, u64 parent,
|
static bool add_btrfs_tree_node(struct my_btrfs_tree *tree, u64 id, u64 parent,
|
||||||
char *name, int name_len, char *dirname)
|
char *name, u16 name_len, char *dirname)
|
||||||
{
|
{
|
||||||
struct mytree_node *tmp;
|
struct mytree_node *tmp;
|
||||||
|
|
||||||
@ -650,11 +669,14 @@ static bool add_btrfs_tree_node(struct my_btrfs_tree *tree, u64 id, u64 parent,
|
|||||||
tmp = realloc(tree->nodes, (tree->num+1) * sizeof(struct mytree_node));
|
tmp = realloc(tree->nodes, (tree->num+1) * sizeof(struct mytree_node));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tree->nodes = tmp;
|
tree->nodes = tmp;
|
||||||
memset(&tree->nodes[tree->num], 0, sizeof(struct mytree_node));
|
memset(&tree->nodes[tree->num], 0, sizeof(struct mytree_node));
|
||||||
|
|
||||||
if (!update_tree_node(&tree->nodes[tree->num], id, parent, name,
|
if (!update_tree_node(&tree->nodes[tree->num], id, parent, name,
|
||||||
name_len, dirname))
|
name_len, dirname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tree->num++;
|
tree->num++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -662,12 +684,15 @@ static bool add_btrfs_tree_node(struct my_btrfs_tree *tree, u64 id, u64 parent,
|
|||||||
static void free_btrfs_tree(struct my_btrfs_tree *tree)
|
static void free_btrfs_tree(struct my_btrfs_tree *tree)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!tree)
|
if (!tree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < tree->num; i++) {
|
for (i = 0; i < tree->num; i++) {
|
||||||
free(tree->nodes[i].name);
|
free(tree->nodes[i].name);
|
||||||
free(tree->nodes[i].dirname);
|
free(tree->nodes[i].dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tree->nodes);
|
free(tree->nodes);
|
||||||
free(tree);
|
free(tree);
|
||||||
}
|
}
|
||||||
@ -686,33 +711,39 @@ static bool do_remove_btrfs_children(struct my_btrfs_tree *tree, u64 root_id,
|
|||||||
for (i = 0; i < tree->num; i++) {
|
for (i = 0; i < tree->num; i++) {
|
||||||
if (tree->nodes[i].parentid == root_id) {
|
if (tree->nodes[i].parentid == root_id) {
|
||||||
if (!tree->nodes[i].dirname) {
|
if (!tree->nodes[i].dirname) {
|
||||||
WARN("Odd condition: child objid with no name under %s\n", path);
|
WARN("Odd condition: child objid with no name under %s", path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(path) + strlen(tree->nodes[i].dirname) + 2;
|
len = strlen(path) + strlen(tree->nodes[i].dirname) + 2;
|
||||||
newpath = malloc(len);
|
newpath = malloc(len);
|
||||||
if (!newpath) {
|
if (!newpath) {
|
||||||
ERROR("Out of memory");
|
ERROR("Out of memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = snprintf(newpath, len, "%s/%s", path, tree->nodes[i].dirname);
|
ret = snprintf(newpath, len, "%s/%s", path, tree->nodes[i].dirname);
|
||||||
if (ret < 0 || ret >= len) {
|
if (ret < 0 || ret >= len) {
|
||||||
free(newpath);
|
free(newpath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!do_remove_btrfs_children(tree, tree->nodes[i].objid, newpath)) {
|
if (!do_remove_btrfs_children(tree, tree->nodes[i].objid, newpath)) {
|
||||||
ERROR("Failed to prune %s\n", tree->nodes[i].name);
|
ERROR("Failed to prune %s", tree->nodes[i].name);
|
||||||
free(newpath);
|
free(newpath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btrfs_do_destroy_subvol(newpath) != 0) {
|
if (btrfs_do_destroy_subvol(newpath) != 0) {
|
||||||
ERROR("Failed to remove %s\n", newpath);
|
ERROR("Failed to remove %s", newpath);
|
||||||
free(newpath);
|
free(newpath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(newpath);
|
free(newpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,14 +758,14 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
struct my_btrfs_tree *tree;
|
struct my_btrfs_tree *tree;
|
||||||
int ret, e, i;
|
int ret, e, i;
|
||||||
unsigned long off = 0;
|
unsigned long off = 0;
|
||||||
int name_len;
|
u16 name_len;
|
||||||
char *name;
|
char *name;
|
||||||
char *tmppath;
|
char *tmppath;
|
||||||
u64 dir_id;
|
u64 dir_id;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ERROR("Failed to open %s\n", path);
|
ERROR("Failed to open %s", path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,16 +782,16 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
|
|
||||||
tree = create_my_btrfs_tree(root_id, path, strlen(path));
|
tree = create_my_btrfs_tree(root_id, path, strlen(path));
|
||||||
if (!tree) {
|
if (!tree) {
|
||||||
ERROR("Out of memory\n");
|
ERROR("Out of memory");
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walk all subvols looking for any under this id */
|
/* Walk all subvols looking for any under this id */
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
/* search in the tree of tree roots */
|
/* search in the tree of tree roots */
|
||||||
sk->tree_id = 1;
|
sk->tree_id = 1;
|
||||||
|
|
||||||
sk->max_type = BTRFS_ROOT_REF_KEY;
|
sk->max_type = BTRFS_ROOT_REF_KEY;
|
||||||
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
||||||
sk->min_objectid = 0;
|
sk->min_objectid = 0;
|
||||||
@ -777,13 +808,15 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
close(fd);
|
close(fd);
|
||||||
free_btrfs_tree(tree);
|
free_btrfs_tree(tree);
|
||||||
if (e == EPERM || e == EACCES) {
|
if (e == EPERM || e == EACCES) {
|
||||||
WARN("Warn: can't perform the search under %s. Will simply try removing", path);
|
WARN("Can't perform the search under %s. "
|
||||||
|
"Will simply try removing", path);
|
||||||
goto ignore_search;
|
goto ignore_search;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR("Error: can't perform the search under %s\n", path);
|
ERROR("Can't perform the search under %s", path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk->nr_items == 0)
|
if (sk->nr_items == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -791,6 +824,7 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
for (i = 0; i < sk->nr_items; i++) {
|
for (i = 0; i < sk->nr_items; i++) {
|
||||||
memcpy(&sh, args.buf + off, sizeof(sh));
|
memcpy(&sh, args.buf + off, sizeof(sh));
|
||||||
off += sizeof(sh);
|
off += sizeof(sh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A backref key with the name and dirid of the parent
|
* A backref key with the name and dirid of the parent
|
||||||
* comes followed by the reoot ref key which has the
|
* comes followed by the reoot ref key which has the
|
||||||
@ -803,6 +837,7 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
dir_id = btrfs_stack_root_ref_dirid(ref);
|
dir_id = btrfs_stack_root_ref_dirid(ref);
|
||||||
tmppath = get_btrfs_subvol_path(fd, sh.offset,
|
tmppath = get_btrfs_subvol_path(fd, sh.offset,
|
||||||
dir_id, name, name_len);
|
dir_id, name, name_len);
|
||||||
|
|
||||||
if (!add_btrfs_tree_node(tree, sh.objectid,
|
if (!add_btrfs_tree_node(tree, sh.objectid,
|
||||||
sh.offset, name,
|
sh.offset, name,
|
||||||
name_len, tmppath)) {
|
name_len, tmppath)) {
|
||||||
@ -812,8 +847,10 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tmppath);
|
free(tmppath);
|
||||||
}
|
}
|
||||||
|
|
||||||
off += sh.len;
|
off += sh.len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -824,8 +861,10 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
sk->min_type = sh.type;
|
sk->min_type = sh.type;
|
||||||
sk->min_offset = sh.offset;
|
sk->min_offset = sh.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk->nr_items = 4096;
|
sk->nr_items = 4096;
|
||||||
sk->min_offset++;
|
sk->min_offset++;
|
||||||
|
|
||||||
if (!sk->min_offset)
|
if (!sk->min_offset)
|
||||||
sk->min_type++;
|
sk->min_type++;
|
||||||
else
|
else
|
||||||
@ -834,23 +873,25 @@ static int btrfs_recursive_destroy(const char *path)
|
|||||||
if (sk->min_type > BTRFS_ROOT_BACKREF_KEY) {
|
if (sk->min_type > BTRFS_ROOT_BACKREF_KEY) {
|
||||||
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
sk->min_type = BTRFS_ROOT_ITEM_KEY;
|
||||||
sk->min_objectid++;
|
sk->min_objectid++;
|
||||||
} else
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (sk->min_objectid >= sk->max_objectid)
|
if (sk->min_objectid >= sk->max_objectid)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/* now actually remove them */
|
/* now actually remove them */
|
||||||
|
|
||||||
if (!do_remove_btrfs_children(tree, root_id, path)) {
|
if (!do_remove_btrfs_children(tree, root_id, path)) {
|
||||||
free_btrfs_tree(tree);
|
free_btrfs_tree(tree);
|
||||||
ERROR("failed pruning\n");
|
ERROR("Failed to prune");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_btrfs_tree(tree);
|
free_btrfs_tree(tree);
|
||||||
|
|
||||||
/* All child subvols have been removed, now remove this one */
|
/* All child subvols have been removed, now remove this one */
|
||||||
ignore_search:
|
ignore_search:
|
||||||
return btrfs_do_destroy_subvol(path);
|
return btrfs_do_destroy_subvol(path);
|
||||||
@ -879,9 +920,11 @@ int btrfs_create(struct lxc_storage *bdev, const char *dest, const char *n,
|
|||||||
int ret;
|
int ret;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
|
||||||
len = strlen(dest) + 1;
|
len = strlen(dest) + 1;
|
||||||
/* strlen("btrfs:") */
|
/* strlen("btrfs:") */
|
||||||
len += 6;
|
len += 6;
|
||||||
|
|
||||||
bdev->src = malloc(len);
|
bdev->src = malloc(len);
|
||||||
if (!bdev->src) {
|
if (!bdev->src) {
|
||||||
ERROR("Failed to allocate memory");
|
ERROR("Failed to allocate memory");
|
||||||
@ -901,9 +944,8 @@ int btrfs_create(struct lxc_storage *bdev, const char *dest, const char *n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = btrfs_subvolume_create(bdev->dest);
|
ret = btrfs_subvolume_create(bdev->dest);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
SYSERROR("Failed to create btrfs subvolume \"%s\"", bdev->dest);
|
SYSERROR("Failed to create btrfs subvolume \"%s\"", bdev->dest);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ extern int btrfs_mount(struct lxc_storage *bdev);
|
|||||||
extern int btrfs_umount(struct lxc_storage *bdev);
|
extern int btrfs_umount(struct lxc_storage *bdev);
|
||||||
|
|
||||||
extern char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
extern char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
|
||||||
int name_len);
|
u16 name_len);
|
||||||
extern int btrfs_list_get_path_rootid(int fd, u64 *treeid);
|
extern int btrfs_list_get_path_rootid(int fd, u64 *treeid);
|
||||||
extern bool is_btrfs_fs(const char *path);
|
extern bool is_btrfs_fs(const char *path);
|
||||||
extern int is_btrfs_subvol(const char *path);
|
extern int is_btrfs_subvol(const char *path);
|
||||||
|
Loading…
Reference in New Issue
Block a user