]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- run background comparisons sequential
authorArvin Schnell <aschnell@suse.de>
Thu, 6 Sep 2012 12:09:10 +0000 (14:09 +0200)
committerArvin Schnell <aschnell@suse.de>
Thu, 6 Sep 2012 12:09:10 +0000 (14:09 +0200)
server/Background.cc [new file with mode: 0644]
server/Background.h [new file with mode: 0644]
server/Client.cc
server/Makefile.am
server/snapperd.cc
snapper/Makefile.am
snapper/Snapper.cc
snapper/Snapper.h
snapper/SnapperDefines.h
snapper/Snapshot.cc
snapper/Snapshot.h

diff --git a/server/Background.cc b/server/Background.cc
new file mode 100644 (file)
index 0000000..7220abc
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <snapper/Log.h>
+
+#include "Background.h"
+
+
+Backgrounds backgrounds;
+
+
+Backgrounds::Backgrounds()
+{
+}
+
+
+Backgrounds::~Backgrounds()
+{
+    thread.interrupt();
+    thread.join();
+}
+
+
+void
+Backgrounds::add_task(MetaSnapper* meta_snapper, Snapshots::const_iterator snapshot1,
+                     Snapshots::const_iterator snapshot2)
+{
+    if (thread.get_id() == boost::thread::id())
+       thread = boost::thread(boost::bind(&Backgrounds::worker, this));
+
+    boost::unique_lock<boost::mutex> lock(mutex);
+    tasks.push_back(Task(meta_snapper, snapshot1, snapshot2));
+    meta_snapper->inc_use_count();
+    lock.unlock();
+
+    condition.notify_one();
+}
+
+
+enum {
+    IOPRIO_CLASS_NONE,
+    IOPRIO_CLASS_RT,
+    IOPRIO_CLASS_BE,
+    IOPRIO_CLASS_IDLE,
+};
+
+enum {
+    IOPRIO_WHO_PROCESS = 1,
+    IOPRIO_WHO_PGRP,
+    IOPRIO_WHO_USER,
+};
+
+#define IOPRIO_CLASS_SHIFT (13)
+#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
+#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
+#define IOPRIO_PRIO_VALUE(ioclass, data) (((ioclass) << IOPRIO_CLASS_SHIFT) | data)
+
+
+void
+Backgrounds::worker()
+{
+    pid_t tid = syscall(SYS_gettid);
+
+    int priority = 20;
+    if (setpriority(PRIO_PROCESS, tid, priority) != 0)
+    {
+       y2war("failed to set priority errno:" << errno);
+    }
+
+    int ioclass = IOPRIO_CLASS_IDLE;
+    int data = 0;
+    if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, tid, IOPRIO_PRIO_VALUE(ioclass, data)) != 0)
+    {
+       y2war("failed to set io-priority errno:" << errno);
+    }
+
+    try
+    {
+       while (true)
+       {
+           boost::unique_lock<boost::mutex> lock(mutex);
+           while (tasks.empty())
+               condition.wait(lock);
+           Task task = tasks.front();
+           lock.unlock();
+
+           Snapper* snapper = task.meta_snapper->getSnapper();
+           Comparison comparison(snapper, task.snapshot1, task.snapshot2);
+           task.meta_snapper->dec_use_count();
+
+           lock.lock();
+           tasks.pop_front();
+           lock.unlock();
+       }
+    }
+    catch (const boost::thread_interrupted&)
+    {
+       y2deb("worker interrupted");
+    }
+}
diff --git a/server/Background.h b/server/Background.h
new file mode 100644 (file)
index 0000000..68591f6
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#ifndef SNAPPER_BACKGROUND_H
+#define SNAPPER_BACKGROUND_H
+
+
+#include <boost/thread.hpp>
+
+#include <snapper/Comparison.h>
+
+#include "MetaSnapper.h"
+
+
+using namespace std;
+using namespace snapper;
+
+
+class Backgrounds : private boost::noncopyable
+{
+
+public:
+
+    Backgrounds();
+    ~Backgrounds();
+
+    struct Task
+    {
+       Task(MetaSnapper* meta_snapper, Snapshots::const_iterator snapshot1,
+            Snapshots::const_iterator snapshot2)
+           : meta_snapper(meta_snapper), snapshot1(snapshot1), snapshot2(snapshot2) {}
+
+       MetaSnapper* meta_snapper;
+       Snapshots::const_iterator snapshot1;
+       Snapshots::const_iterator snapshot2;
+    };
+
+    typedef list<Task>::const_iterator const_iterator;
+
+    const_iterator begin() const { return tasks.begin(); }
+
+    const_iterator end() const { return tasks.end(); }
+
+    bool empty() const { return tasks.empty(); }
+
+    void add_task(MetaSnapper* meta_snapper, Snapshots::const_iterator snapshot1,
+                 Snapshots::const_iterator snapshot2);
+
+private:
+
+    void worker();
+
+    boost::condition_variable condition;
+    boost::mutex mutex;
+    boost::thread thread;
+    list<Task> tasks;
+
+};
+
+
+extern Backgrounds backgrounds;
+
+
+#endif
index 7208aa2d5952f92fed0fd6560d059804fd53ce52..4d319525c83af2738948067098ed94217e115a32 100644 (file)
@@ -29,6 +29,7 @@
 #include "Types.h"
 #include "Client.h"
 #include "MetaSnapper.h"
+#include "Background.h"
 
 
 boost::shared_mutex big_mutex;
@@ -753,7 +754,9 @@ Client::create_post_snapshot(DBus::Connection& conn, DBus::Message& msg)
     snap2->setUserdata(userdata);
     snap2->flushInfo();
 
-    // snapper->startBackgroundComparsion(snap1, snap2); // TODO
+    map<string, string>::const_iterator pos = it->config_info.raw.find("BACKGROUND_COMPARISON");
+    if (pos == it->config_info.raw.end() || pos->second == "yes")
+       backgrounds.add_task(&(*it), snap1, snap2);
 
     DBus::MessageMethodReturn reply(msg);
 
@@ -1035,6 +1038,14 @@ Client::debug(DBus::Connection& conn, DBus::Message& msg) const
        hoho << s.str();
     }
 
+    hoho << "backgrounds:";
+    for (Backgrounds::const_iterator it = backgrounds.begin(); it != backgrounds.end(); ++it)
+    {
+       std::ostringstream s;
+       s << "    name:'" << it->meta_snapper->configName() << "'";
+       hoho << s.str();
+    }
+
     hoho << "meta-snappers:";
     for (MetaSnappers::const_iterator it = meta_snappers.begin(); it != meta_snappers.end(); ++it)
     {
@@ -1208,13 +1219,10 @@ Client::worker()
        while (true)
        {
            boost::unique_lock<boost::mutex> lock(mutex);
-
            while (tasks.empty())
                condition.wait(lock);
-
            Task task = tasks.front();
            tasks.pop();
-
            lock.unlock();
 
            dispatch(task.conn, task.msg);
index e8ebf4308f2f875b3c5517abe1ad70341760e85e..8faab9355c76d02f6921164f812d588e12a575a6 100644 (file)
@@ -11,6 +11,7 @@ snapperd_SOURCES =                                    \
        snapperd.cc                                     \
        Client.cc               Client.h                \
        MetaSnapper.cc          MetaSnapper.h           \
+       Background.cc           Background.h            \
        Types.cc                Types.h
 
 snapperd_LDADD = ../snapper/libsnapper.la ../dbus/libdbus.la   \
index 524feeb8e88f95d0da0453ca1c21c3347d035d41..a71c4543f97d4637bfc9cb03f6f1c0a670972cdd 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "MetaSnapper.h"
 #include "Client.h"
+#include "Background.h"
 #include "Types.h"
 
 
@@ -148,7 +149,7 @@ MyMainLoop::periodic()
 
     clients.remove_zombies();
 
-    if (clients.empty())
+    if (clients.empty() && backgrounds.empty())
        set_idle_timeout(idle_time);
 
     for (MetaSnappers::iterator it = meta_snappers.begin(); it != meta_snappers.end(); ++it)
@@ -167,6 +168,9 @@ MyMainLoop::periodic_timeout()
     if (clients.has_zombies())
        return 1000;
 
+    if (!backgrounds.empty())
+       return 1000;
+
     for (MetaSnappers::const_iterator it = meta_snappers.begin(); it != meta_snappers.end(); ++it)
        if (it->is_loaded() && it->use_count() == 0)
            return 1000;
index 2f3452c3cee6490ba16ca56ee049171780975a9b..55bf74166f0a8fd8fe24816db6610a25488abae4 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile.am for snapper/snapper
 #
 
-AM_CXXFLAGS = -D_FILE_OFFSET_BITS=64 -DLIBDIR=\"$(libdir)\"
+AM_CXXFLAGS = -D_FILE_OFFSET_BITS=64
 
 INCLUDES = -I/usr/include/libxml2
 
index a15416479b5891ea834a9be36e0ec8f274645f97..32b47e4bd60636831288dcf44eb7146ec02cc43d 100644 (file)
@@ -123,16 +123,6 @@ namespace snapper
     }
 
 
-    // Directory that contains the per snapshot directory with info files.
-    // For btrfs e.g. "/.snapshots" or "/home/.snapshots".
-    // For ext4 e.g. "/.snapshots-info" or "/home/.snapshots-info".
-    string
-    Snapper::infosDir() const
-    {
-       return filesystem->infosDir();
-    }
-
-
     SDir
     Snapper::openSubvolumeDir() const
     {
@@ -182,44 +172,6 @@ namespace snapper
     }
 
 
-    void
-    Snapper::startBackgroundComparsion(Snapshots::const_iterator snapshot1,
-                                      Snapshots::const_iterator snapshot2)
-    {
-       if (snapshot1 == snapshots.end() || snapshot1->isCurrent())
-           throw IllegalSnapshotException();
-
-       if (snapshot2 == snapshots.end() || snapshot2->isCurrent())
-           throw IllegalSnapshotException();
-
-       bool background_comparison = true;
-       config->getValue("BACKGROUND_COMPARISON", background_comparison);
-       if (!background_comparison)
-           return;
-
-       y2mil("num1:" << snapshot1->getNum() << " num2:" << snapshot2->getNum());
-
-       if (!snapshot1->isCurrent())
-           snapshot1->mountFilesystemSnapshot();
-       if (!snapshot2->isCurrent())
-           snapshot2->mountFilesystemSnapshot();
-
-       bool invert = snapshot1->getNum() > snapshot2->getNum();
-
-       if (invert)
-           swap(snapshot1, snapshot2);
-
-       string dir1 = snapshot1->snapshotDir();
-       string dir2 = snapshot2->snapshotDir();
-
-       string output = snapshot2->infoDir() + "/filelist-" + decString(snapshot1->getNum()) +
-           ".txt";
-
-       SystemCmd(NICEBIN " -n 19 " IONICEBIN " -c 3 " COMPAREDIRSBIN " " + quote(dir1) + " " +
-                 quote(dir2) + " " + quote(output));
-    }
-
-
     ConfigInfo
     Snapper::getConfig(const string& config_name)
     {
index 579697e5830a883961872b2b9cdffde95fe6820f..c9476903c54f518be8226ceeb1ad38ed67c97cc0 100644 (file)
@@ -104,7 +104,6 @@ namespace snapper
        string configName() const { return config_name; }
 
        string subvolumeDir() const;
-       string infosDir() const;
 
 #ifndef SWIG
        SDir openSubvolumeDir() const;
@@ -122,9 +121,6 @@ namespace snapper
 
        void deleteSnapshot(Snapshots::iterator snapshot);
 
-       void startBackgroundComparsion(Snapshots::const_iterator snapshot1,
-                                      Snapshots::const_iterator snapshot2);
-
        const vector<string>& getIgnorePatterns() const { return ignore_patterns; }
 
        static ConfigInfo getConfig(const string& config_name);
index 3d453df903bf9e350a5d3e616c83e3c45f394d30..c060ad13b3d9137def6b4139fa1650ab55e37950 100644 (file)
 
 #define CHSNAPBIN "/sbin/chsnap"
 
-#define COMPAREDIRSBIN LIBDIR "/snapper/bin/compare-dirs"
-
-#define NICEBIN "/usr/bin/nice"
-#define IONICEBIN "/usr/bin/ionice"
-
 #define CPBIN "/bin/cp"
 #define TOUCHBIN "/usr/bin/touch"
 #define RMBIN "/bin/rm"
index 023ac8d0b81de2091419eb7f5b9a5b252e1143d5..a4a9ceb99d219e2a404d68ad4e890c86b07acd31 100644 (file)
@@ -69,20 +69,6 @@ namespace snapper
     }
 
 
-    // Directory where the info file is saved. Obviously not available for
-    // current.
-    // For btrfs e.g. "/.snapshots/1" or "/home/.snapshots/1".
-    // For ext4 e.g. "/.snapshots-info/1" or "/home/.snapshots-info/1".
-    string
-    Snapshot::infoDir() const
-    {
-       if (isCurrent())
-           throw IllegalSnapshotException();
-
-       return snapper->infosDir() + "/" + decString(num);
-    }
-
-
     // Directory containing the actual content of the snapshot.
     // For btrfs e.g. "/" or "/home" for current and "/.snapshots/1/snapshot"
     // or "/home/.snapshots/1/snapshot" otherwise.
index 969236cf0f54523fbb6a41ff1340ec9a0b46cdb3..e6cfdebf16b7376e498ee389e1ca0e0675e1dab0 100644 (file)
@@ -111,7 +111,6 @@ namespace snapper
 
        void flushInfo();
 
-       string infoDir() const;
        string snapshotDir() const;
 
 #ifndef SWIG