]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- fix broken xa_change_t design and add debugging output for XAttributes()
authorOndrej Kozina <okozina@redhat.com>
Tue, 22 Jan 2013 13:49:27 +0000 (14:49 +0100)
committerOndrej Kozina <okozina@redhat.com>
Wed, 27 Feb 2013 16:24:56 +0000 (17:24 +0100)
snapper/File.cc
snapper/XAttributes.cc
snapper/XAttributes.h

index d0d75f6f5dde55f3051a74e345e8b04aa55dcdeb..ef5edc46d8785d7f65afc98308b252bf291e440f 100644 (file)
@@ -543,13 +543,19 @@ namespace snapper
             return false;
         }
 
+        y2deb("source file is: " << getAbsolutePath(LOC_PRE));
+        y2deb("destination file is: " << getAbsolutePath(LOC_SYSTEM));
+
         bool ret_val;
 
         try {
             XAttributes xa_src(src_fd), xa_dest(dest_fd);
+            y2deb("xa_src object: " << xa_src << std::endl << "xa_dest object: " << xa_dest);
 
             xa_dest.generateXaComparison(xa_src);
+            y2deb("xa_dest object after generateXaComparison(): " << xa_dest);
             ret_val = xa_dest.serializeTo(dest_fd);
+            y2deb("xa_dest object after serializeTo(): " << xa_dest);
         }
         catch (IOErrorException ioe) {
             ret_val = false;
index cfc42588649991e39efa5166a97bb14586b9235a..8a022c81674ba2145114d490e14adf0a0791b6bd 100644 (file)
@@ -143,6 +143,9 @@ namespace snapper
     XAttributes::generateXaComparison(const XAttributes &src_xa)
     {
         xa_change_t *change_map = new xa_change_t();
+        (*change_map)[XA_DELETE] = xa_name_vec_t();
+        (*change_map)[XA_REPLACE] = xa_name_vec_t();
+        (*change_map)[XA_CREATE] = xa_name_vec_t();
 
         delete this->xachmap;
 
@@ -162,7 +165,7 @@ namespace snapper
             {
                 if (src_cit->second != it->second)
                 {
-                    (*change_map)[XA_REPLACE] = src_cit->first;
+                    (*change_map)[XA_REPLACE].push_back(src_cit->first);
                     (*this->xamap)[src_cit->first] = src_cit->second;
                 }
                 src_cit++;
@@ -170,21 +173,21 @@ namespace snapper
             }
             else if (src_cit->first < it->first)
             {
-                (*change_map)[XA_CREATE] = src_cit->first;
+                (*change_map)[XA_CREATE].push_back(src_cit->first);
                 it = this->xamap->insert(xa_pair_t(src_cit->first, src_cit->second)).first;
 
                 src_cit++;
             }
             else
             {
-                (*change_map)[XA_DELETE] = src_cit->first;
+                (*change_map)[XA_DELETE].push_back(src_cit->first);
                 it = this->xamap->erase(it);
             }
         }
 
         while (src_cit != src_xa.xamap->end())
         {
-            (*change_map)[XA_CREATE] = src_cit->first;
+            (*change_map)[XA_CREATE].push_back(src_cit->first);
             it = this->xamap->insert(xa_pair_t(src_cit->first, src_cit->second)).first;
 
             src_cit++;
@@ -192,7 +195,7 @@ namespace snapper
 
         while (it != this->xamap->end())
         {
-            (*change_map)[XA_DELETE] = it->first;
+            (*change_map)[XA_DELETE].push_back(it->first);
             it = this->xamap->erase(it);
         }
 
@@ -207,55 +210,89 @@ namespace snapper
             y2war("Missing change map!");
             return false;
         }
-        
+
         xa_change_citer cit = this->xachmap->begin();
-        
+
         while(cit != this->xachmap->end())
         {
+            xa_name_vec_citer name_cit = cit->second.begin();
+
             switch (cit->first)
             {
                 case XA_DELETE:
-                    y2deb("delete xattribute: " << cit->second);
-                    if (fremovexattr(dest_fd, cit->second.c_str()))
+                    while (name_cit != cit->second.end())
                     {
-                        y2err("Couldn't remove xattribute '" << cit->second << "': " << stringerror(errno));
-                        return false;
+                        y2deb("delete xattribute: " << *name_cit);
+                        if (fremovexattr(dest_fd, (*name_cit).c_str()))
+                        {
+                            y2err("Couldn't remove xattribute '" << *name_cit << "': " << stringerror(errno));
+                            return false;
+                        }
+                        name_cit++;
                     }
                     break;
 
                 case XA_REPLACE:
+                    while (name_cit != cit->second.end())
                     {
-                        y2deb("replace xattribute: " << cit->second);
-                        xa_find_pair_t fnd = find(cit->second);
-                        if (!fnd.first || fnd.second.empty())
+                        y2deb("replace xattribute: " << *name_cit);
+                        xa_find_pair_t fnd = find(*name_cit);
+                        if (!fnd.first)
                         {
-                            y2war("Internal error: Couldn't find xattribute '" << cit->second << "'");
+                            y2err("Internal error: Couldn't find xattribute '" << *name_cit << "'");
                             return false;
                         }
-                        y2deb("new value: '" << fnd.second << "'");
-                        if (fsetxattr(dest_fd, cit->second.c_str(), &fnd.second.front(), fnd.second.size(), XATTR_REPLACE))
+                        if (fnd.second.empty())
                         {
-                            y2err("Couldn't replace xattribute '" << cit->second << "' by new value: " << stringerror(errno));
-                            return false;
+                            y2deb("new value for xattribute '" << *name_cit << "' is empty!");
+                            if (fsetxattr(dest_fd, (*name_cit).c_str(), NULL, 0, XATTR_REPLACE))
+                            {
+                                y2err("Couldn't replace xattribute '" << *name_cit << "' by new (empty) value: " << stringerror(errno));
+                                return false;
+                            }
+                        }
+                        else
+                        {
+                            y2deb("new value: '" << fnd.second << "'");
+                            if (fsetxattr(dest_fd, (*name_cit).c_str(), &fnd.second.front(), fnd.second.size(), XATTR_REPLACE))
+                            {
+                                y2err("Couldn't replace xattribute by new value: " << stringerror(errno));
+                                return false;
+                            }
                         }
+                        name_cit++;
                     }
                     break;
 
                 case XA_CREATE:
+                    while (name_cit != cit->second.end())
                     {
-                        y2deb("create xattribute: " << cit->second);
-                        xa_find_pair_t fnd = find(cit->second);
-                        if (!fnd.first || fnd.second.empty())
+                        y2deb("create xattribute: " << *name_cit);
+                        xa_find_pair_t fnd = find(*name_cit);
+                        if (!fnd.first)
                         {
-                            y2war("Internal error: Couldn't find xattribute '" << cit->second << "'");
+                            y2err("Internal error: Couldn't find xattribute '" << *name_cit << "'");
                             return false;
                         }
-                        y2deb("new value: '" << fnd.second << "'");
-                        if (fsetxattr(dest_fd, cit->second.c_str(), &fnd.second.front(), fnd.second.size(), XATTR_CREATE))
+                        if (fnd.second.empty())
                         {
-                            y2err("Couldn't create xattribute '" << cit->second << "': " << stringerror(errno));
-                            return false;
+                            y2deb("new value for xattribute '" << *name_cit << "' is empty!");
+                            if (fsetxattr(dest_fd, (*name_cit).c_str(), NULL, 0, XATTR_CREATE))
+                            {
+                                y2err("Couldn't create xattribute '" << *name_cit << "' by new (empty) value: " << stringerror(errno));
+                                return false;
+                            }
                         }
+                        else
+                        {
+                            y2deb("new value: '" << fnd.second << "'");
+                            if (fsetxattr(dest_fd, (*name_cit).c_str(), &fnd.second.front(), fnd.second.size(), XATTR_CREATE))
+                            {
+                                y2err("Couldn't create xattribute '" << *name_cit << "': " << stringerror(errno));
+                                return false;
+                            }
+                        }
+                        name_cit++;
                     }
                     break;
 
@@ -303,10 +340,7 @@ namespace snapper
         xa_map_citer it = xa.xamap->begin();
 
         if (it == xa.xamap->end())
-        {
             out << "(XA container is empty)";
-            return out;
-        }
 
         while (it != xa.xamap->end())
         {
@@ -314,6 +348,11 @@ namespace snapper
             it++;
         }
 
+        if (xa.xachmap)
+        {
+            out << "change content: " << std::endl << *xa.xachmap;
+        }
+
         return out;
     }
 
@@ -330,4 +369,35 @@ namespace snapper
 
         return out;
     }
+
+    ostream&
+    operator<<(ostream &out, const xa_change_t &xa_change)
+    {
+        xa_change_citer cit = xa_change.begin();
+
+        while (cit != xa_change.end())
+        {
+            xa_name_vec_citer name_cit = cit->second.begin();
+            switch (cit->first)
+            {
+                case XA_DELETE:
+                    out << "XA_DELETE";
+                    break;
+                case XA_REPLACE:
+                    out << "XA_REPLACE";
+                    break;
+                case XA_CREATE:
+                    out << "XA_CREATE";
+                    break;
+                default:
+                    out << "unknown";
+            }
+            out << " mark:" << std::endl;
+            while (name_cit != cit->second.end())
+                out << *name_cit++ << std::endl;
+            cit++;
+        }
+
+        return out;
+    }
 }
\ No newline at end of file
index a40c8e04ef396d4226444606781798614d0c04ad..59fc67ced33ca3868b24a49035de6667ccde4f33 100644 (file)
@@ -41,19 +41,8 @@ namespace snapper
        typedef pair<string, xa_value_t> xa_pair_t;
         typedef pair<uint8_t, string> xa_cmp_pair_t;
         typedef pair<bool, xa_value_t> xa_find_pair_t;
-        typedef map<uint8_t, string> xa_change_t;
-        // pair<name, mode>
-        //i.e:
-        // name=acl, mode="create,delete,replace"
-        // create - whole new XA
-        // delete - remove XA
-        // replace - change in xa_value
-        
+        typedef vector<string> xa_name_vec_t;
 
-       typedef xa_map_t::iterator xa_map_iter;
-       typedef xa_map_t::const_iterator xa_map_citer;
-        typedef xa_change_t::const_iterator xa_change_citer;
-        
         // this is ordered on purpose!
         // we can possibly avoid allocating new fs block if xattrs fits
         // into 100 bytes (ext2,3,4)
@@ -63,6 +52,19 @@ namespace snapper
             XA_REPLACE,
             XA_CREATE
         };
+        // pair<mode, xa_name_vec_t>
+        //i.e:
+        // mode=create/delete/replace, names="acl, selinux"
+        // create - whole new XA
+        // delete - remove XA
+        // replace - change in xa_value
+        typedef map<uint8_t, xa_name_vec_t> xa_change_t;
+
+        // iterators
+       typedef xa_map_t::iterator xa_map_iter;
+       typedef xa_map_t::const_iterator xa_map_citer;
+        typedef xa_change_t::const_iterator xa_change_citer;
+        typedef xa_name_vec_t::const_iterator xa_name_vec_citer;
 
        class XAttributes
        {
@@ -86,7 +88,8 @@ namespace snapper
                friend ostream& operator<<(ostream&, const XAttributes&);
        };
 
-       ostream& operator<<(ostream&, const xa_value_t&);
+        ostream& operator<<(ostream&, const xa_value_t&);
+        ostream& operator<<(ostream&, const xa_change_t&);
 }
 
 #endif