From: Arvin Schnell Date: Thu, 6 Sep 2012 12:09:10 +0000 (+0200) Subject: - run background comparisons sequential X-Git-Tag: v0.1.3~108 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=cc590b3b63b055b5933710f4485d02e73ceeb65b;p=thirdparty%2Fsnapper.git - run background comparisons sequential --- diff --git a/server/Background.cc b/server/Background.cc new file mode 100644 index 00000000..7220abc1 --- /dev/null +++ b/server/Background.cc @@ -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 +#include +#include + +#include + +#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 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 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 index 00000000..68591f6a --- /dev/null +++ b/server/Background.h @@ -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 + +#include + +#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::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 tasks; + +}; + + +extern Backgrounds backgrounds; + + +#endif diff --git a/server/Client.cc b/server/Client.cc index 7208aa2d..4d319525 100644 --- a/server/Client.cc +++ b/server/Client.cc @@ -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::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 lock(mutex); - while (tasks.empty()) condition.wait(lock); - Task task = tasks.front(); tasks.pop(); - lock.unlock(); dispatch(task.conn, task.msg); diff --git a/server/Makefile.am b/server/Makefile.am index e8ebf430..8faab935 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -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 \ diff --git a/server/snapperd.cc b/server/snapperd.cc index 524feeb8..a71c4543 100644 --- a/server/snapperd.cc +++ b/server/snapperd.cc @@ -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; diff --git a/snapper/Makefile.am b/snapper/Makefile.am index 2f3452c3..55bf7416 100644 --- a/snapper/Makefile.am +++ b/snapper/Makefile.am @@ -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 diff --git a/snapper/Snapper.cc b/snapper/Snapper.cc index a1541647..32b47e4b 100644 --- a/snapper/Snapper.cc +++ b/snapper/Snapper.cc @@ -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) { diff --git a/snapper/Snapper.h b/snapper/Snapper.h index 579697e5..c9476903 100644 --- a/snapper/Snapper.h +++ b/snapper/Snapper.h @@ -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& getIgnorePatterns() const { return ignore_patterns; } static ConfigInfo getConfig(const string& config_name); diff --git a/snapper/SnapperDefines.h b/snapper/SnapperDefines.h index 3d453df9..c060ad13 100644 --- a/snapper/SnapperDefines.h +++ b/snapper/SnapperDefines.h @@ -35,11 +35,6 @@ #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" diff --git a/snapper/Snapshot.cc b/snapper/Snapshot.cc index 023ac8d0..a4a9ceb9 100644 --- a/snapper/Snapshot.cc +++ b/snapper/Snapshot.cc @@ -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. diff --git a/snapper/Snapshot.h b/snapper/Snapshot.h index 969236cf..e6cfdebf 100644 --- a/snapper/Snapshot.h +++ b/snapper/Snapshot.h @@ -111,7 +111,6 @@ namespace snapper void flushInfo(); - string infoDir() const; string snapshotDir() const; #ifndef SWIG