if (arg_copy_locale && arg_root) {
mkdir_parents(etc_localeconf, 0755);
- r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644);
+ r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0);
if (r != -ENOENT) {
if (r < 0)
return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf);
return 0;
}
- r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644);
+ r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644, 0);
if (r < 0) {
log_warning_errno(r, "Failed to copy /etc/resolv.conf to %s: %m", where);
return r;
}
-int copy_file(const char *from, const char *to, int flags, mode_t mode) {
+int copy_file(const char *from, const char *to, int flags, mode_t mode, int chattr_flags) {
int fdt, r;
assert(from);
return -errno;
}
+ if (chattr_flags != 0)
+ (void) chattr_fd(fdt, true, chattr_flags);
+
r = copy_file_fd(from, fdt, true);
if (r < 0) {
close(fdt);
return 0;
}
-int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace) {
+int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, int chattr_flags) {
_cleanup_free_ char *t;
int r;
if (r < 0)
return r;
- r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode);
+ r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags);
if (r < 0)
return r;
#include <sys/types.h>
int copy_file_fd(const char *from, int to, bool try_reflink);
-int copy_file(const char *from, const char *to, int flags, mode_t mode);
-int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace);
+int copy_file(const char *from, const char *to, int flags, mode_t mode, int chattr_flags);
+int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, int chattr_flags);
int copy_tree(const char *from, const char *to, bool merge);
int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
int copy_directory_fd(int dirfd, const char *to, bool merge);
***/
#include <sys/statfs.h>
+#include <linux/fs.h>
#include <fcntl.h>
#include "strv.h"
case IMAGE_GPT:
new_path = strappenda("/var/lib/container/", new_name, ".gpt");
- r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, false);
+ r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, false, FS_NOCOW_FL);
break;
default:
if (chmod(i->path, (st.st_mode & 0444) | (b ? 0000 : 0200)) < 0)
return -errno;
+
+ /* If the images is now read-only, it's a good time to
+ * defrag it, given that no write patterns will
+ * fragment it again. */
+ if (b)
+ (void) btrfs_defrag(i->path);
break;
}
return r;
}
- r = copy_file(original_path, t, 0, 0644);
+ r = copy_file(original_path, t, 0, 0644, 0);
if (r == -ENOENT) {
r = touch(t);
if (r < 0) {
assert_se(write_string_file(fn, "foo bar bar bar foo") == 0);
- assert_se(copy_file(fn, fn_copy, 0, 0644) == 0);
+ assert_se(copy_file(fn, fn_copy, 0, 0644, 0) == 0);
assert_se(read_full_file(fn_copy, &buf, &sz) == 0);
assert_se(streq(buf, "foo bar bar bar foo\n"));