[systemd-commits] 4 commits - TODO src/import src/journal src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jan 7 16:36:17 PST 2015


 TODO                       |    4 ++--
 src/import/import-gpt.c    |   11 ++++++++++-
 src/journal/journal-file.c |   30 +++++++++++++++++++++++++++---
 src/journal/journalctl.c   |   12 ++++--------
 src/shared/util.c          |   36 ++++++++++++++++++++++++++++++++++++
 src/shared/util.h          |    3 +++
 6 files changed, 82 insertions(+), 14 deletions(-)

New commits:
commit 07289967bc8fc32fc2cc65e8946da70e2853d290
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 8 01:28:15 2015 +0100

    update TODO

diff --git a/TODO b/TODO
index 16395e4..df59baf 100644
--- a/TODO
+++ b/TODO
@@ -45,9 +45,9 @@ Release 219 preparations:
 
 Features:
 
-* "machinectl list-images" should show os-release data
+* nspawn: don't change superblock mount options from nspawn for cgroup hierarchies
 
-* should we set nocow chattr attribute on journal files by default? does this have any drawbacks?
+* "machinectl list-images" should show os-release data
 
 * nspawn: when start a container "foobar" look for its configuration in a file "foobar.nspawn" in /etc/systemd/nspawn/ as well as next to the actualy directory or image to boot
 

commit d61b600dde1f267a408440011aa980e0ed44bea6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 8 01:27:13 2015 +0100

    util: make it easy to initialize the crtime from the current time in fd_setcrtime()

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index c20af5d..c1b5404 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2623,7 +2623,7 @@ int journal_file_open(
                  * attributes are not supported we'll just skip this,
                  * and rely solely on mtime/atime/ctime of the file. */
 
-                fd_setcrtime(f->fd, now(CLOCK_REALTIME));
+                fd_setcrtime(f->fd, 0);
 
 #ifdef HAVE_GCRYPT
                 /* Try to load the FSPRG state, and if we can't, then
diff --git a/src/shared/util.c b/src/shared/util.c
index 88fd78e..7d753e4 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -7670,6 +7670,9 @@ int fd_setcrtime(int fd, usec_t usec) {
 
         assert(fd >= 0);
 
+        if (usec <= 0)
+                usec = now(CLOCK_REALTIME);
+
         le = htole64((uint64_t) usec);
         if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
                 return -errno;

commit dfd1520d3ab98cfa376f2d84ed1e7887d013720d
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 8 01:25:40 2015 +0100

    import: also set NOCOW for gpt disk images
    
    Given the write patterns on disk images, we better should turn COW off
    for them. In particular as the file systems used inside the disk images
    should do their own data integrity checks anyway and we don't need
    multiple layers of it.

diff --git a/src/import/import-gpt.c b/src/import/import-gpt.c
index a85ceee..d304a39 100644
--- a/src/import/import-gpt.c
+++ b/src/import/import-gpt.c
@@ -20,6 +20,7 @@
 ***/
 
 #include <sys/xattr.h>
+#include <linux/fs.h>
 #include <curl/curl.h>
 
 #include "hashmap.h"
@@ -165,7 +166,7 @@ static void gpt_import_file_success(GptImportFile *f) {
 
                         f->disk_fd = open(f->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
                         if (f->disk_fd < 0) {
-                                r = log_error_errno(errno, "Failed top open vendor image: %m");
+                                r = log_error_errno(errno, "Failed to open vendor image: %m");
                                 goto finish;
                         }
                 }
@@ -186,6 +187,14 @@ static void gpt_import_file_success(GptImportFile *f) {
                         goto finish;
                 }
 
+                /* Turn off COW writing. This should greatly improve
+                 * performance on COW file systems like btrfs, since it
+                 * reduces fragmentation caused by not allowing in-place
+                 * writes. */
+                r = chattr_fd(dfd, true, FS_NOCOW_FL);
+                if (r < 0)
+                        log_warning_errno(errno, "Failed to set file attributes on %s: %m", f->temp_path);
+
                 r = copy_bytes(f->disk_fd, dfd, (off_t) -1, true);
                 if (r < 0) {
                         log_error_errno(r, "Failed to make writable copy of image: %m");

commit 11689d2a021d95a8447d938180e0962cd9439763
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 8 01:22:29 2015 +0100

    journald: turn off COW for journal files on btrfs
    
    btrfs' COW logic results in heavily fragment journal files, which is
    detrimental for perfomance. Hence, turn off COW for journal files as we
    create them.
    
    Turning off COW comes at the cost of data integrity guarantees, but this
    should be acceptable, given that we do our own checksumming, and
    generally have a pretty conservative write pattern.
    
    Also see discussion on linux-btrfs:
    
    http://www.spinics.net/lists/linux-btrfs/msg41001.html

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index c9030c5..c20af5d 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -26,6 +26,7 @@
 #include <sys/statvfs.h>
 #include <fcntl.h>
 #include <stddef.h>
+#include <linux/fs.h>
 
 #include "btrfs-util.h"
 #include "journal-def.h"
@@ -141,8 +142,17 @@ void journal_file_close(JournalFile *f) {
         if (f->mmap && f->fd >= 0)
                 mmap_cache_close_fd(f->mmap, f->fd);
 
-        if (f->fd >= 0 && f->defrag_on_close)
-                btrfs_defrag_fd(f->fd);
+        if (f->fd >= 0 && f->defrag_on_close) {
+
+                /* Be friendly to btrfs: turn COW back on again now,
+                 * and defragment the file. We won't write to the file
+                 * ever again, hence remove all fragmentation, and
+                 * reenable all the good bits COW usually provides
+                 * (such as data checksumming). */
+
+                (void) chattr_fd(f->fd, false, FS_NOCOW_FL);
+                (void) btrfs_defrag_fd(f->fd);
+        }
 
         safe_close(f->fd);
         free(f->path);
@@ -2591,6 +2601,18 @@ int journal_file_open(
                 goto fail;
 
         if (f->last_stat.st_size == 0 && f->writable) {
+
+                /* Before we write anything, turn off COW logic. Given
+                 * our write pattern that is quite unfriendly to COW
+                 * file systems this should greatly improve
+                 * performance on COW file systems, such as btrfs, at
+                 * the expense of data integrity features (which
+                 * shouldn't be too bad, given that we do our own
+                 * checksumming). */
+                r = chattr_fd(f->fd, true, FS_NOCOW_FL);
+                if (r < 0)
+                        log_warning_errno(errno, "Failed to set file attributes: %m");
+
                 /* Let's attach the creation time to the journal file,
                  * so that the vacuuming code knows the age of this
                  * file even if the file might end up corrupted one
@@ -2808,6 +2830,8 @@ int journal_file_open_reliably(
 
         /* btrfs doesn't cope well with our write pattern and
          * fragments heavily. Let's defrag all files we rotate */
+
+        (void) chattr_path(p, false, FS_NOCOW_FL);
         (void) btrfs_defrag(p);
 
         log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 386e350..62931f1 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -1294,7 +1294,7 @@ static int setup_keys(void) {
         size_t mpk_size, seed_size, state_size, i;
         uint8_t *mpk, *seed, *state;
         ssize_t l;
-        int fd = -1, r, attr = 0;
+        int fd = -1, r;
         sd_id128_t machine, boot;
         char *p = NULL, *k = NULL;
         struct FSSHeader h;
@@ -1389,13 +1389,9 @@ static int setup_keys(void) {
 
         /* Enable secure remove, exclusion from dump, synchronous
          * writing and in-place updating */
-        if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
-                log_warning_errno(errno, "FS_IOC_GETFLAGS failed: %m");
-
-        attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
-
-        if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
-                log_warning_errno(errno, "FS_IOC_SETFLAGS failed: %m");
+        r = chattr_fd(fd, true, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL);
+        if (r < 0)
+                log_warning_errno(errno, "Failed to set file attributes: %m");
 
         zero(h);
         memcpy(h.signature, "KSHHRHLP", 8);
diff --git a/src/shared/util.c b/src/shared/util.c
index 6293e96..88fd78e 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -62,6 +62,7 @@
 #include <sys/xattr.h>
 #include <libgen.h>
 #include <sys/statvfs.h>
+#include <linux/fs.h>
 #undef basename
 
 #ifdef HAVE_SYS_AUXV_H
@@ -7740,3 +7741,35 @@ int same_fd(int a, int b) {
 
         return fa == fb;
 }
+
+int chattr_fd(int fd, bool b, int mask) {
+        int old_attr, new_attr;
+
+        assert(fd >= 0);
+
+        if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
+                return -errno;
+
+        if (b)
+                new_attr = old_attr | mask;
+        else
+                new_attr = old_attr & ~mask;
+
+        if (new_attr == old_attr)
+                return 0;
+
+        if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int chattr_path(const char *p, bool b, int mask) {
+        _cleanup_close_ int fd = -1;
+
+        fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0)
+                return -errno;
+
+        return chattr_fd(fd, b, mask);
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 4b7e12e..31103e9 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1071,3 +1071,6 @@ int path_getcrtime(const char *p, usec_t *usec);
 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags);
 
 int same_fd(int a, int b);
+
+int chattr_fd(int fd, bool b, int mask);
+int chattr_path(const char *p, bool b, int mask);



More information about the systemd-commits mailing list