static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc)
{
- __do_close int fd = -EBADF;
FILE *f1;
struct stat fbuf;
void *buf = NULL;
char *del = NULL;
char path[PATH_MAX];
char newpath[PATH_MAX];
- int ret, n = 0, v = 0;
+ int fd, ret, n = 0, v = 0;
bool bret = false;
size_t len = 0, bytes = 0;
/* Here we know that we have or can use an lxc-snapshot file
* using the new format. */
if (inc) {
- fd = open(path, O_APPEND | O_RDWR | O_CLOEXEC);
- if (fd < 0)
+ f1 = fopen(path, "ae");
+ if (!f1)
goto out;
- ret = lxc_write_nointr(fd, newpath, strlen(newpath));
- if (ret < 0) {
+ if (fprintf(f1, "%s", newpath) < 0) {
ERROR("Error writing new snapshots entry");
+ ret = fclose(f1);
+ if (ret != 0)
+ SYSERROR("Error writing to or closing snapshots file");
+ goto out;
+ }
+
+ ret = fclose(f1);
+ if (ret != 0) {
+ SYSERROR("Error writing to or closing snapshots file");
goto out;
}
} else if (!inc) {
- fd = open(path, O_RDWR | O_CLOEXEC);
- if (fd < 0)
+ if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
goto out;
- if (fstat(fd, &fbuf) < 0)
+ if (fstat(fd, &fbuf) < 0) {
+ close(fd);
goto out;
+ }
if (fbuf.st_size != 0) {
buf = lxc_strmmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
SYSERROR("Failed to create mapping %s", path);
+ close(fd);
goto out;
}
lxc_strmunmap(buf, fbuf.st_size);
if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
SYSERROR("Failed to truncate file %s", path);
+ close(fd);
goto out;
}
}
+
+ close(fd);
}
/* If the lxc-snapshot file is empty, remove it. */
- if (fstat(fd, &fbuf) < 0)
+ if (stat(path, &fbuf) < 0)
goto out;
if (!fbuf.st_size) {
static int copy_file(const char *old, const char *new)
{
- __do_close int fd_from = -EBADF, fd_to = -EBADF;
+ int in, out;
ssize_t len, ret;
char buf[8096];
struct stat sbuf;
- fd_from = open(old, PROTECT_OPEN);
- if (fd_from < 0)
- return syserror("Error opening original file %s", old);
+ if (file_exists(new)) {
+ ERROR("copy destination %s exists", new);
+ return -1;
+ }
- ret = fstat(fd_from, &sbuf);
- if (ret < 0)
- return sysinfo("Error stat'ing %s", old);
+ ret = stat(old, &sbuf);
+ if (ret < 0) {
+ INFO("Error stat'ing %s", old);
+ return -1;
+ }
+
+ in = open(old, O_RDONLY);
+ if (in < 0) {
+ SYSERROR("Error opening original file %s", old);
+ return -1;
+ }
- fd_to = open(new, PROTECT_OPEN_W | O_CREAT | O_EXCL, 0644);
- if (fd_to < 0)
- return syserror("Error opening new file %s", new);
+ out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (out < 0) {
+ SYSERROR("Error opening new file %s", new);
+ close(in);
+ return -1;
+ }
for (;;) {
- len = lxc_read_nointr(fd_from, buf, 8096);
- if (len < 0)
- return syserror("Error reading old file %s", old);
+ len = lxc_read_nointr(in, buf, 8096);
+ if (len < 0) {
+ SYSERROR("Error reading old file %s", old);
+ goto err;
+ }
if (len == 0)
break;
- ret = lxc_write_nointr(fd_to, buf, len);
- if (ret < len)
- return syserror("Error: write to new file %s was interrupted", new);
+ ret = lxc_write_nointr(out, buf, len);
+ if (ret < len) { /* should we retry? */
+ SYSERROR("Error: write to new file %s was interrupted", new);
+ goto err;
+ }
}
+ close(in);
+ close(out);
/* We set mode, but not owner/group. */
- ret = fchmod(fd_to, sbuf.st_mode);
- if (ret < 0)
- return syserror("Error setting mode on %s", new);
+ ret = chmod(new, sbuf.st_mode);
+ if (ret) {
+ SYSERROR("Error setting mode on %s", new);
+ return -1;
+ }
return 0;
+
+err:
+ close(in);
+ close(out);
+ return -1;
}
static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)