switch (fs.st_mode & S_IFMT)
{
case S_IFDIR: {
- rmdir(getAbsolutePath(LOC_SYSTEM).c_str());
+ if (rmdir(getAbsolutePath(LOC_SYSTEM).c_str()) != 0)
+ {
+ y2err("rmdir failed for " << getAbsolutePath(LOC_SYSTEM));
+ if (getSnapper()->getRollbackCallback())
+ getSnapper()->getRollbackCallback()->deleteError(name);
+ }
} break;
case S_IFREG: {
- unlink(getAbsolutePath(LOC_SYSTEM).c_str());
+ if (unlink(getAbsolutePath(LOC_SYSTEM).c_str()) != 0)
+ {
+ y2err("unlink failed for " << getAbsolutePath(LOC_SYSTEM));
+ if (getSnapper()->getRollbackCallback())
+ getSnapper()->getRollbackCallback()->deleteError(name);
+ }
} break;
case S_IFLNK: {
- unlink(getAbsolutePath(LOC_SYSTEM).c_str());
+ if (unlink(getAbsolutePath(LOC_SYSTEM).c_str()) != 0)
+ {
+ y2err("unlink failed for " << getAbsolutePath(LOC_SYSTEM));
+ if (getSnapper()->getRollbackCallback())
+ getSnapper()->getRollbackCallback()->deleteError(name);
+ }
} break;
}
}
if (getPreToPostStatus() & PERMISSIONS)
{
- chmod(getAbsolutePath(LOC_SYSTEM).c_str(), fs.st_mode);
+ if (chmod(getAbsolutePath(LOC_SYSTEM).c_str(), fs.st_mode) != 0)
+ {
+ y2err("chmod failed for " << getAbsolutePath(LOC_SYSTEM));
+ if (getSnapper()->getRollbackCallback())
+ getSnapper()->getRollbackCallback()->modifyError(name);
+ }
}
if (getPreToPostStatus() & (USER | GROUP))
{
- lchown(getAbsolutePath(LOC_SYSTEM).c_str(), fs.st_uid, fs.st_gid);
+ if (lchown(getAbsolutePath(LOC_SYSTEM).c_str(), fs.st_uid, fs.st_gid) != 0)
+ {
+ y2err("lchown failed for " << getAbsolutePath(LOC_SYSTEM));
+ if (getSnapper()->getRollbackCallback())
+ getSnapper()->getRollbackCallback()->modifyError(name);
+ }
}
}
virtual void createInfo(const string& name) = 0;
virtual void modifyInfo(const string& name) = 0;
virtual void deleteInfo(const string& name) = 0;
+
+ virtual void createError(const string& name) = 0;
+ virtual void modifyError(const string& name) = 0;
+ virtual void deleteError(const string& name) = 0;
};
permissions2
owner1
owner2
+error1
noinst_SCRIPTS = run-all
-noinst_PROGRAMS = simple1 permissions1 permissions2 owner1 owner2
+noinst_PROGRAMS = simple1 permissions1 permissions2 owner1 owner2 error1
simple1_SOURCES = simple1.cc common.h common.cc
owner1_SOURCES = owner1.cc common.h common.cc
owner2_SOURCES = owner2.cc common.h common.cc
+error1_SOURCES = error1.cc common.h common.cc
+
EXTRA_DIST = $(noinst_SCRIPTS)
Snapshots::iterator first;
Snapshots::iterator second;
+unsigned int numCreateErrors, numModifyErrors, numDeleteErrors;
+
struct CompareCallbackImpl : public CompareCallback
{
void start() { cout << "running rollback..." << endl; }
void stop() { cout << "rollback done" << endl; }
- void createInfo(const string& name) { cout << "create " << name << endl; }
- void modifyInfo(const string& name) { cout << "modify " << name << endl; }
- void deleteInfo(const string& name) { cout << "delete " << name << endl; }
+ void createInfo(const string& name) { cout << "creating " << name << endl; }
+ void modifyInfo(const string& name) { cout << "modifying " << name << endl; }
+ void deleteInfo(const string& name) { cout << "deleting " << name << endl; }
+
+ void createError(const string& name) { cout << "failed to create " << name << endl; numCreateErrors++; }
+ void modifyError(const string& name) { cout << "failed to modify " << name << endl; numModifyErrors++; }
+ void deleteError(const string& name) { cout << "failed to delete " << name << endl; numDeleteErrors++; }
};
RollbackCallbackImpl rollback_callback_impl;
void
rollback()
{
+ numCreateErrors = numModifyErrors = numDeleteErrors = 0;
+
Comparison comparison(sh, first, second);
Files& files = comparison.getFiles();
}
+void
+check_rollback_errors(unsigned int numCreate, unsigned int numModify, unsigned int numDelete)
+{
+ check_equal(numCreateErrors, numCreate);
+ check_equal(numModifyErrors, numModify);
+ check_equal(numDeleteErrors, numDelete);
+}
+
+
void
check_first()
{
void check_rollback_statistics(unsigned int numCreate, unsigned int numModify,
unsigned int numDelete);
void rollback();
+void check_rollback_errors(unsigned int numCreate, unsigned int numModify,
+ unsigned int numDelete);
void check_first();
void run_command(const char* command);
--- /dev/null
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "common.h"
+
+using namespace std;
+
+
+int
+main()
+{
+ setup();
+
+ first_snapshot();
+
+ run_command("mkdir not-empty");
+
+ second_snapshot();
+
+ run_command("touch not-empty/bad");
+
+ check_rollback_statistics(0, 0, 1);
+
+ rollback();
+
+ check_rollback_errors(0, 0, 1);
+
+ exit(EXIT_SUCCESS);
+}
rollback();
+ check_rollback_errors(0, 0, 0);
+
check_first();
exit(EXIT_SUCCESS);
rollback();
+ check_rollback_errors(0, 0, 0);
+
check_first();
exit(EXIT_SUCCESS);
rollback();
+ check_rollback_errors(0, 0, 0);
+
check_first();
exit(EXIT_SUCCESS);
rollback();
+ check_rollback_errors(0, 0, 0);
+
check_first();
exit(EXIT_SUCCESS);
run owner1
run owner2
+run error1
+
rollback();
+ check_rollback_errors(0, 0, 0);
+
check_first();
exit(EXIT_SUCCESS);
struct RollbackCallbackImpl : public RollbackCallback
{
- void start() { if (!verbose) cout << "running rollback..." << flush; }
- void stop() { if (!verbose) cout << " done" << endl; }
+ void start() { cout << "running rollback..." << endl; }
+ void stop() { cout << "rollback done" << endl; }
- void createInfo(const string& name) { if (verbose) cout << "create " << name << endl; }
- void modifyInfo(const string& name) { if (verbose) cout << "modify " << name << endl; }
- void deleteInfo(const string& name) { if (verbose) cout << "delete " << name << endl; }
+ void createInfo(const string& name) { if (verbose) cout << "creating " << name << endl; }
+ void modifyInfo(const string& name) { if (verbose) cout << "modifying " << name << endl; }
+ void deleteInfo(const string& name) { if (verbose) cout << "deleting " << name << endl; }
+
+ void createError(const string& name) { cerr << "failed to create " << name << endl; }
+ void modifyError(const string& name) { cerr << "failed to modify " << name << endl; }
+ void deleteError(const string& name) { cerr << "failed to delete " << name << endl; }
};
RollbackCallbackImpl rollback_callback_impl;