]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/3.0.1-xattr-error.patch
Added preliminary AFS acl support. The code may need some testing on a real AFS enabl...
[bacula/bacula] / bacula / patches / 3.0.1-xattr-error.patch
1
2  This patch can be applied to version 3.0.1 and modifies xattr
3  handling to print warning or error messages when problems are
4  found without canceling the Job. This patch *must* be applied
5  after 3.0.1-acl-error.patch.  It should fix the re-opened
6  bug #1305.
7
8  Apply it to version 3.0.1 with:
9
10  cd <bacula-source>
11  patch -p0 <3.0.1-xattr.patch
12  ./configure <your-options>
13  make
14  ...
15  make install
16
17
18 Index: src/filed/xattr.c
19 ===================================================================
20 --- src/filed/xattr.c   (revision 8923)
21 +++ src/filed/xattr.c   (working copy)
22 @@ -96,7 +96,6 @@
23     if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
24        Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
25              sd->bstrerror());
26 -
27        return false;
28     }
29  
30 @@ -112,7 +111,6 @@
31        sd->msglen = 0;
32        Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
33              sd->bstrerror());
34 -
35        return false;
36     }
37  
38 @@ -121,10 +119,8 @@
39     if (!sd->signal(BNET_EOD)) {
40        Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
41              sd->bstrerror());
42 -
43        return false;
44     }
45 -
46     Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
47  
48     return true;
49 @@ -265,8 +261,7 @@
50           jcr->last_fname, be.bstrerror());
51        Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
52           jcr->last_fname, be.bstrerror());
53 -
54 -      return false;
55 +      return true;                       /* non-fatal return */
56     } else if (xattr_list_len == 0) {
57        return true;
58     }
59 @@ -274,11 +269,7 @@
60     /*
61      * Allocate room for the extented attribute list.
62      */
63 -   if ((xattr_list = (char *)malloc(xattr_list_len + 1)) == (char *)NULL) {
64 -      Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_list_len + 1);
65 -
66 -      return false;
67 -   }
68 +   xattr_list = (char *)malloc(xattr_list_len + 1);
69     memset((caddr_t)xattr_list, 0, xattr_list_len + 1);
70  
71     /*
72 @@ -291,10 +282,8 @@
73           jcr->last_fname, be.bstrerror());
74        Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
75           jcr->last_fname, be.bstrerror());
76 -
77        free(xattr_list);
78 -
79 -      return false;
80 +      return true;                    /* non-fatal return */
81     }
82     xattr_list[xattr_list_len] = '\0';
83  
84 @@ -328,11 +317,7 @@
85      * Allocate enough room to hold all extended attributes.
86      * After allocating the storage make sure its empty by zeroing it.
87      */
88 -   if ((xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t))) == (xattr_t *)NULL) {
89 -      Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), count * sizeof(xattr_t));
90 -
91 -      return false;
92 -   }
93 +   xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t));
94     memset((caddr_t)xattr_value_list, 0, count * sizeof(xattr_t));
95  
96     /*
97 @@ -345,7 +330,6 @@
98  #if defined(HAVE_LINUX_OS)
99        if (ff_pkt->flags & FO_ACL && !strcmp(bp, "system.posix_acl_access")) {
100           bp = strchr(bp, '\0') + 1;
101 -
102           continue;
103        }
104  #endif
105 @@ -360,11 +344,7 @@
106         * Allocate space for storing the name.
107         */
108        current_xattr->name_length = strlen(bp);
109 -      if ((current_xattr->name = (char *)malloc(current_xattr->name_length)) == (char *)NULL) {
110 -         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr->name_length);
111 -
112 -         goto bail_out;
113 -      }
114 +      current_xattr->name = (char *)malloc(current_xattr->name_length);
115        memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
116  
117        expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
118 @@ -379,18 +359,13 @@
119              jcr->last_fname, be.bstrerror());
120           Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
121              jcr->last_fname, be.bstrerror());
122 -
123           goto bail_out;
124        }
125  
126        /*
127         * Allocate space for storing the value.
128         */
129 -      if ((current_xattr->value = (char *)malloc(xattr_value_len)) == (char *)NULL) {
130 -         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_value_len);
131 -
132 -         goto bail_out;
133 -      }
134 +      current_xattr->value = (char *)malloc(xattr_value_len);
135        memset((caddr_t)current_xattr->value, 0, xattr_value_len);
136  
137        xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
138 @@ -400,7 +375,6 @@
139              jcr->last_fname, be.bstrerror());
140           Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
141              jcr->last_fname, be.bstrerror());
142 -
143           goto bail_out;
144        }
145  
146 @@ -416,7 +390,6 @@
147        if (expected_serialize_len >= MAX_XATTR_STREAM) {
148           Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
149              jcr->last_fname, MAX_XATTR_STREAM);
150 -
151           goto bail_out;
152        }
153        
154 @@ -435,7 +408,6 @@
155           jcr->last_fname);
156        Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n",
157           jcr->last_fname);
158 -
159        goto bail_out;
160     }
161  
162 @@ -450,15 +422,14 @@
163  bail_out:
164     xattr_drop_internal_table(xattr_value_list);
165     free(xattr_list);
166 -
167 -   return false;
168 +   return true;                    /* non-fatal return */
169  }
170  
171  static bool generic_xattr_parse_streams(JCR *jcr)
172  {
173     unser_declare;
174     xattr_t current_xattr;
175 -   bool retval = true;
176 +   bool retval = true;                /* default non-fatal */
177  
178     /*
179      * Parse the stream and perform the setxattr calls on the file.
180 @@ -478,8 +449,7 @@
181              jcr->last_fname);
182           Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n",
183              jcr->last_fname);
184 -
185 -         return false;
186 +         return true;                 /* non-fatal return */
187        }
188  
189        /*
190 @@ -490,11 +460,7 @@
191        /*
192         * Allocate room for the name and decode its content.
193         */
194 -      if ((current_xattr.name = (char *)malloc(current_xattr.name_length + 1)) == (char *)NULL) {
195 -         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.name_length + 1);
196 -
197 -         return false;
198 -      }
199 +      current_xattr.name = (char *)malloc(current_xattr.name_length + 1);
200        unser_bytes(current_xattr.name, current_xattr.name_length);
201  
202        /*
203 @@ -510,11 +476,7 @@
204        /*
205         * Allocate room for the value and decode its content.
206         */
207 -      if ((current_xattr.value = (char *)malloc(current_xattr.value_length)) == (char *)NULL) {
208 -         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.value_length);
209 -
210 -         return false;
211 -      }
212 +      current_xattr.value = (char *)malloc(current_xattr.value_length);
213        unser_bytes(current_xattr.value, current_xattr.value_length);
214  
215        /*
216 @@ -529,12 +491,6 @@
217              jcr->last_fname, be.bstrerror());
218           Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
219              jcr->last_fname, be.bstrerror());
220 -
221 -         /*
222 -          * Reset the return flag to false to indicate one or more extended attributes
223 -          * could not be restored.
224 -          */
225 -         retval = false;
226        }
227  
228        /*
229 @@ -560,7 +516,10 @@
230     case STREAM_XATTR_DARWIN:
231        return generic_xattr_parse_streams(jcr);
232     default:
233 -      return false;
234 +      Jmsg2(jcr, M_WARNING, 0,
235 +         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
236 +         jcr->last_fname, stream);
237 +      return true;                    /* non-fatal error */
238     }
239  }
240  #elif defined(HAVE_FREEBSD_OS)
241 @@ -575,7 +534,10 @@
242     case STREAM_XATTR_FREEBSD:
243        return generic_xattr_parse_streams(jcr);
244     default:
245 -      return false;
246 +      Jmsg2(jcr, M_WARNING, 0, 
247 +         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
248 +         jcr->last_fname, stream);
249 +      return true;                    /* non-fatal error */
250     }
251  }
252  #elif defined(HAVE_LINUX_OS)
253 @@ -590,7 +552,10 @@
254     case STREAM_XATTR_LINUX:
255        return generic_xattr_parse_streams(jcr);
256     default:
257 -      return false;
258 +      Jmsg2(jcr, M_WARNING, 0, 
259 +         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
260 +         jcr->last_fname, stream);
261 +      return true;                    /* non-fatal error */
262     }
263  }
264  #elif defined(HAVE_NETBSD_OS)
265 @@ -605,7 +570,10 @@
266     case STREAM_XATTR_NETBSD:
267        return generic_xattr_parse_streams(jcr);
268     default:
269 -      return false;
270 +      Jmsg2(jcr, M_WARNING, 0, 
271 +         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
272 +         jcr->last_fname, stream);
273 +      return true;                    /* non-fatal error */
274     }
275  }
276  #endif
277 @@ -726,10 +694,11 @@
278  {
279     xattr_link_cache_entry_t *ptr;
280  
281 -   for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next)
282 -      if (ptr->inum == inum)
283 +   for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next) {
284 +      if (ptr->inum == inum) {
285           return ptr;
286 -
287 +      }
288 +   }
289     return NULL;
290  }
291  
292 @@ -737,16 +706,16 @@
293  {
294     xattr_link_cache_entry_t *ptr;
295  
296 -   if ((ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry))) != NULL) {
297 -      memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
298 -      ptr->inum = inum;
299 -      strncpy(ptr->target, target, sizeof(ptr->target));
300 -      if (xattr_link_cache_head == NULL)
301 -         xattr_link_cache_head = ptr;
302 -      if (xattr_link_cache_tail != NULL)
303 -         xattr_link_cache_tail->next = ptr;
304 -      xattr_link_cache_tail = ptr;
305 +   ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry));
306 +   memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
307 +   ptr->inum = inum;
308 +   strncpy(ptr->target, target, sizeof(ptr->target));
309 +   if (xattr_link_cache_head == NULL) {
310 +      xattr_link_cache_head = ptr;
311     }
312 +   if (xattr_link_cache_tail != NULL)
313 +      xattr_link_cache_tail->next = ptr;
314 +   }
315  }
316  
317  static void drop_xattr_link_cache(void)
318 @@ -757,7 +726,6 @@
319        next = ptr->next;
320        free(ptr);
321     }
322 -
323     xattr_link_cache_head = NULL;
324     xattr_link_cache_tail = NULL;
325  }
326 @@ -828,9 +796,9 @@
327     }
328  
329  cleanup:
330 -   if (response != NULL)
331 +   if (response != NULL) {
332        nvlist_free(response);
333 -
334 +   }
335     return retval;
336  }
337  #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
338 @@ -847,19 +815,17 @@
339  
340     for (n = 0; n < count; n++) {
341        ace = &entries[n];
342 -
343        if (!(ace->a_type == USER_OBJ ||
344              ace->a_type == GROUP_OBJ ||
345              ace->a_type == OTHER_OBJ ||
346              ace->a_type == CLASS_OBJ))
347          return false;
348     }
349 -
350     return true;
351  }
352  #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */
353  
354 -static bool solaris_archive_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
355 +static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
356  {
357  #ifdef HAVE_ACL
358  #ifdef HAVE_EXTENDED_ACL
359 @@ -881,8 +847,7 @@
360              attrname, jcr->last_fname, be.bstrerror());
361           Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
362              attrname, jcr->last_fname, be.bstrerror());
363 -
364 -         return false;
365 +         return true;                    /* non-fatal */
366        }
367  
368        if (aclp != NULL) {
369 @@ -912,10 +877,11 @@
370     /*
371      * See if this attribute has an ACL
372      */
373 -   if (fd != -1)
374 +   if (fd != -1) {
375        n = facl(fd, GETACLCNT, 0, NULL);
376 -   else
377 +   } else {
378        n = acl(attrname, GETACLCNT, 0, NULL);
379 +   }
380  
381     if (n >= MIN_ACL_ENTRIES) {
382        acls = (aclent_t *)malloc(n * sizeof(aclent_t));
383 @@ -926,9 +892,8 @@
384              attrname, jcr->last_fname, be.bstrerror());
385           Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
386              attrname, jcr->last_fname, be.bstrerror());
387 -
388           free(acls);
389 -         return false;
390 +         return true;                 /* non-fatal */
391        }
392  
393        /*
394 @@ -941,9 +906,8 @@
395                 attrname, jcr->last_fname, be.bstrerror());
396              Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
397                 attrname, jcr->last_fname, be.bstrerror());
398 -
399              free(acls);
400 -            return false;
401 +            return true;                 /* non-fatal */
402           }
403        } else {
404           *acl_text = NULL;
405 @@ -956,18 +920,19 @@
406  
407     return true;
408  #endif /* HAVE_EXTENDED_ACL */
409 +
410  #else /* HAVE_ACL */
411 -   return NULL;
412 +   return false;                         /* fatal return */
413  #endif /* HAVE_ACL */
414  }
415  
416  /*
417   * Forward declaration for recursive function call.
418   */
419 -static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
420 +static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
421  
422  /*
423 - * Archive an extended or extensible attribute.
424 + * Save an extended or extensible attribute.
425   * This is stored as an opaque stream of bytes with the following encoding:
426   *
427   * <xattr_name>\0<stat_buffer>\0<acl_string>\0<actual_xattr_data>
428 @@ -981,7 +946,7 @@
429   * acl_string is an acl text when a non trivial acl is set on the xattr.
430   * actual_xattr_data is the content of the xattr file.
431   */
432 -static bool solaris_archive_xattr(JCR *jcr, int fd, const char *xattr_namespace,
433 +static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
434                                    const char *attrname, bool toplevel_hidden_dir, int stream)
435  {
436     int cnt;
437 @@ -993,7 +958,7 @@
438     char *acl_text = NULL;
439     char attribs[MAXSTRING];
440     char buffer[BUFSIZ];
441 -   bool retval = false;
442 +   bool retval = true;                /* default is non-fatal */
443  
444     snprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname);
445  
446 @@ -1006,7 +971,6 @@
447           target_attrname, jcr->last_fname, be.bstrerror());
448        Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
449           target_attrname, jcr->last_fname, be.bstrerror());
450 -
451        goto cleanup;
452     }
453  
454 @@ -1022,7 +986,7 @@
455        /*
456         * Get any acl on the xattr.
457         */
458 -      if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
459 +      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
460           goto cleanup;
461  
462        /*
463 @@ -1033,15 +997,16 @@
464        cnt = snprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c",
465                       target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
466        break;
467 +
468     case S_IFDIR:
469        /*
470         * Get any acl on the xattr.
471         */
472 -      if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
473 +      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
474           goto cleanup;
475  
476        /*
477 -       * See if this is the toplevel_hidden_dir being archived.
478 +       * See if this is the toplevel_hidden_dir being saved.
479         */
480        if (toplevel_hidden_dir) {
481           /*
482 @@ -1054,7 +1019,6 @@
483                                                         "%s%c%s%c%s%c",
484                                                         target_attrname, 0, attribs, 0,
485                                                         (acl_text) ? acl_text : "", 0);
486 -
487           goto cleanup;
488        } else {
489           /*
490 @@ -1088,7 +1052,7 @@
491              retval = send_xattr_stream(jcr, stream);
492  
493              /*
494 -             * For a hard linked file we are ready now, no need to recursively archive the attributes.
495 +             * For a hard linked file we are ready now, no need to recursively save the attributes.
496               */
497              goto cleanup;
498           }
499 @@ -1103,8 +1067,9 @@
500        /*
501         * Get any acl on the xattr.
502         */
503 -      if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
504 +      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text)) {
505           goto cleanup;
506 +      }
507  
508        /*
509         * Encode the stat struct into an ASCII representation.
510 @@ -1123,10 +1088,10 @@
511              target_attrname, jcr->last_fname, be.bstrerror());
512           Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
513              target_attrname, jcr->last_fname, be.bstrerror());
514 -
515           goto cleanup;
516        }
517        break;
518 +
519     case S_IFLNK:
520        /*
521         * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
522 @@ -1138,7 +1103,6 @@
523              target_attrname, jcr->last_fname, be.bstrerror());
524           Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
525              target_attrname, jcr->last_fname, be.bstrerror());
526 -
527           goto cleanup;
528        }
529  
530 @@ -1154,9 +1118,10 @@
531        retval = send_xattr_stream(jcr, stream);
532  
533        /*
534 -       * For a soft linked file we are ready now, no need to recursively archive the attributes.
535 +       * For a soft linked file we are ready now, no need to recursively save the attributes.
536         */
537        goto cleanup;
538 +
539     default:
540        goto cleanup;
541     }
542 @@ -1167,7 +1132,7 @@
543     if (nr_xattr_saved == 0) {
544        pm_memcpy(jcr->xattr_data, toplevel_hidden_dir_xattr_data, toplevel_hidden_dir_xattr_data_len);
545        jcr->xattr_data_len = toplevel_hidden_dir_xattr_data_len;
546 -      send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
547 +      retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
548     }
549  
550     pm_memcpy(jcr->xattr_data, buffer, cnt);
551 @@ -1185,7 +1150,6 @@
552           if (st.st_size >= MAX_XATTR_STREAM) {
553              Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
554                 jcr->last_fname, MAX_XATTR_STREAM);
555 -
556              goto cleanup;
557           }
558  
559 @@ -1200,24 +1164,26 @@
560                 target_attrname, jcr->last_fname);
561              Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n",
562                 target_attrname, jcr->last_fname);
563 -
564              goto cleanup;
565           }
566        }
567        break;
568 +
569     default:
570        break;
571     }
572  
573 -   retval = send_xattr_stream(jcr, stream);
574 -   nr_xattr_saved++;
575 +   if (retval) {
576 +      retval = send_xattr_stream(jcr, stream);
577 +      nr_xattr_saved++;
578 +   }
579  
580     /*
581 -    * Recursivly call solaris_archive_extended_attributes for archiving the attributes
582 +    * Recursivly call solaris_save_extended_attributes for archiving the attributes
583      * available on this extended attribute.
584      */
585     if (retval) {
586 -      retval = solaris_archive_xattrs(jcr, xattr_namespace, attrname);
587 +      retval = solaris_save_xattrs(jcr, xattr_namespace, attrname);
588        
589        /*
590         * The recursive call could change our working dir so change back to the wanted workdir.
591 @@ -1228,28 +1194,28 @@
592              jcr->last_fname, be.bstrerror());
593           Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
594              jcr->last_fname, fd, be.bstrerror());
595 -
596           goto cleanup;
597        }
598     }
599  
600  cleanup:
601 -   if (acl_text)
602 +   if (acl_text) {
603        free(acl_text);
604 -   if (attrfd != -1)
605 +   }
606 +   if (attrfd != -1) {
607        close(attrfd);
608 -
609 +   }
610     return retval;
611  }
612  
613 -static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
614 +static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
615  {
616     const char *name;
617     int fd, filefd = -1, attrdirfd = -1;
618     DIR *dirp;
619     struct dirent *dp;
620     char current_xattr_namespace[PATH_MAX];
621 -   bool retval = false;
622 +   bool retval = true;                   /* default non-fatal error */
623   
624     /*
625      * Determine what argument to use. Use attr_parent when set
626 @@ -1258,18 +1224,19 @@
627      */
628     if (attr_parent) {
629        name = attr_parent;
630 -      if (xattr_namespace)
631 +      if (xattr_namespace) {
632           snprintf(current_xattr_namespace, sizeof(current_xattr_namespace), "%s%s/",
633                    xattr_namespace, attr_parent);
634 -      else
635 -         strcpy(current_xattr_namespace, "/");
636 +      } else {
637 +         strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
638 +      }
639     } else {
640        name = jcr->last_fname;
641 -      strcpy(current_xattr_namespace, "/");
642 +      strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
643     }
644  
645     /*
646 -    * Open the file on which to archive the xattrs read-only.
647 +    * Open the file on which to save the xattrs read-only.
648      */
649     if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
650        berrno be;
651 @@ -1277,7 +1244,6 @@
652           jcr->last_fname, be.bstrerror());
653        Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
654           jcr->last_fname, be.bstrerror());
655 -
656        goto cleanup;
657     }
658  
659 @@ -1301,13 +1267,12 @@
660           Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
661              name, jcr->last_fname, be.bstrerror());
662        }
663 -
664        goto cleanup;
665     }
666  
667    /*
668     * We need to change into the attribute directory to determine if each of the
669 -   * attributes should be archived.
670 +   * attributes should be saved.
671     */
672     if (fchdir(attrdirfd) < 0) {
673        berrno be;
674 @@ -1315,7 +1280,6 @@
675           jcr->last_fname, be.bstrerror());
676        Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
677           jcr->last_fname, attrdirfd, be.bstrerror());
678 -
679        goto cleanup;
680     }
681  
682 @@ -1325,7 +1289,7 @@
683      * And as we want this entry before anything else we better just save its data.
684      */
685     if (!attr_parent)
686 -      solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
687 +      solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
688                              true, STREAM_XATTR_SOLARIS);
689  
690     if ((fd = dup(attrdirfd)) == -1 ||
691 @@ -1381,23 +1345,22 @@
692           if (!solaris_has_non_transient_extensible_attributes(filefd)) {
693              Dmsg3(400, "Skipping transient extensible attributes %s%s on file \"%s\"\n",
694                 current_xattr_namespace, dp->d_name, jcr->last_fname);
695 -
696              continue;
697           }
698  
699           /*
700 -          * Archive the xattr.
701 +          * Save the xattr.
702            */
703 -         solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
704 +         solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
705                                 false, STREAM_XATTR_SOLARIS_SYS);
706           continue;
707        }
708  #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
709  
710        /*
711 -       * Archive the xattr.
712 +       * Save the xattr.
713         */
714 -      solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
715 +      solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
716                              false, STREAM_XATTR_SOLARIS);
717     }
718  
719 @@ -1409,7 +1372,6 @@
720        close(attrdirfd);
721     if (filefd != -1)
722        close(filefd);
723 -
724     return retval;
725  }
726  
727 @@ -1421,7 +1383,9 @@
728     acl_t *aclp = NULL;
729  
730     if ((error = acl_fromtext(acl_text, &aclp)) != 0) {
731 -      return false;
732 +      Jmsg1(jcr, M_ERROR, 0, _("Unable to convert acl from text on file \"%s\"\n"
733 +               jcr->last_fname));
734 +      return true;                    /* non-fatal */
735     }
736  
737     if ((fd != -1 && facl_set(fd, aclp) != 0) ||
738 @@ -1431,14 +1395,14 @@
739           attrname, jcr->last_fname, be.bstrerror());
740        Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
741           attrname, jcr->last_fname, be.bstrerror());
742 -
743 -      return false;
744 +      return true;                    /* non-fatal */
745     }
746  
747 -   if (aclp)
748 +   if (aclp) {
749        acl_free(aclp);
750 -
751 +   }
752     return true;
753 +
754  #else /* HAVE_EXTENDED_ACL */
755     int n;
756     aclent_t *acls = NULL;
757 @@ -1452,16 +1416,17 @@
758              attrname, jcr->last_fname, be.bstrerror());
759           Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
760              attrname, jcr->last_fname, be.bstrerror());
761 -
762 -         return false;
763 +         return true;                   /* non-fatal */
764        }
765     }
766  
767 -   if (acls)
768 +   if (acls) {
769        free(acls);
770 -
771 +   }
772     return true;
773 +
774  #endif /* HAVE_EXTENDED_ACL */
775 +
776  }
777  #endif /* HAVE_ACL */
778  
779 @@ -1476,7 +1441,7 @@
780     int32_t inum;
781     struct stat st;
782     struct timeval times[2];
783 -   bool retval = false;
784 +   bool retval = true;             /* default non-fatal */
785  
786     /*
787      * Parse the xattr stream. First the part that is the same for all xattrs.
788 @@ -1505,7 +1470,6 @@
789           jcr->last_fname, be.bstrerror());
790        Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
791           jcr->last_fname, be.bstrerror());
792 -
793        goto cleanup;
794     }
795  
796 @@ -1518,7 +1482,6 @@
797           jcr->last_fname, be.bstrerror());
798        Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n",
799           jcr->last_fname, be.bstrerror());
800 -
801        goto cleanup;
802     }
803  
804 @@ -1528,7 +1491,6 @@
805           jcr->last_fname, be.bstrerror());
806        Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
807           jcr->last_fname, attrdirfd, be.bstrerror());
808 -
809        goto cleanup;
810     }
811  
812 @@ -1546,7 +1508,6 @@
813              target_attrname, jcr->last_fname, be.bstrerror());
814           Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
815              target_attrname, jcr->last_fname, be.bstrerror());
816 -
817           goto cleanup;
818        }
819  
820 @@ -1562,7 +1523,6 @@
821              target_attrname, jcr->last_fname, be.bstrerror());
822           Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
823              target_attrname, jcr->last_fname, be.bstrerror());
824 -
825           goto cleanup;
826        }
827  
828 @@ -1578,7 +1538,6 @@
829              target_attrname, jcr->last_fname, be.bstrerror());
830           Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n",
831              target_attrname, jcr->last_fname, attrdirfd, be.bstrerror());
832 -
833           goto cleanup;
834        }
835  
836 @@ -1616,8 +1575,7 @@
837              target_attrname, jcr->last_fname, be.bstrerror());
838           Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n",
839              target_attrname,  jcr->last_fname, be.bstrerror());
840 -
841 -            goto cleanup;
842 +         goto cleanup;
843        }
844        break;
845     case S_IFCHR:
846 @@ -1632,7 +1590,6 @@
847              target_attrname, jcr->last_fname, be.bstrerror());
848           Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n",
849              target_attrname,  jcr->last_fname, be.bstrerror());
850 -
851           goto cleanup;
852        }
853        break;
854 @@ -1649,7 +1606,6 @@
855                 target_attrname, jcr->last_fname, be.bstrerror());
856              Dmsg3(100, "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n",
857                 target_attrname,  jcr->last_fname, be.bstrerror());
858 -
859              goto cleanup;
860           }
861        }
862 @@ -1668,7 +1624,6 @@
863                 target_attrname, linked_target, jcr->last_fname, be.bstrerror());
864              Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n",
865                 target_attrname, linked_target, jcr->last_fname, be.bstrerror());
866 -
867              goto cleanup;
868           }
869  
870 @@ -1699,7 +1654,6 @@
871                 target_attrname, jcr->last_fname, be.bstrerror());
872              Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
873                 target_attrname, jcr->last_fname, be.bstrerror());
874 -
875              goto cleanup;
876           }
877        }
878 @@ -1720,7 +1674,6 @@
879                 target_attrname, jcr->last_fname);
880              Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n",
881                 target_attrname, jcr->last_fname);
882 -
883              goto cleanup;
884           }
885  
886 @@ -1732,7 +1685,6 @@
887                    target_attrname, jcr->last_fname, be.bstrerror());
888                 Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n",
889                    target_attrname, jcr->last_fname, be.bstrerror());
890 -
891                 goto cleanup;
892              }
893  
894 @@ -1754,7 +1706,6 @@
895              target_attrname, linked_target, jcr->last_fname, be.bstrerror());
896           Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n",
897              target_attrname, linked_target, jcr->last_fname, be.bstrerror());
898 -
899           goto cleanup;
900        }
901  
902 @@ -1787,7 +1738,6 @@
903              Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n",
904                 target_attrname, jcr->last_fname, be.bstrerror());
905           }
906 -
907           goto cleanup;
908        }
909     }
910 @@ -1813,7 +1763,6 @@
911              target_attrname, jcr->last_fname, be.bstrerror());
912           Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n",
913              target_attrname, jcr->last_fname, be.bstrerror());
914 -
915           goto cleanup;
916        }
917     }
918 @@ -1831,13 +1780,15 @@
919        jcr->last_fname);
920  
921  cleanup:
922 -   if (attrfd != -1)
923 +   if (attrfd != -1) {
924        close(attrfd);
925 -   if (attrdirfd != -1)
926 +   }
927 +   if (attrdirfd != -1) {
928        close(attrdirfd);
929 -   if (filefd != -1)
930 +   }
931 +   if (filefd != -1) {
932        close(filefd);
933 -
934 +   }
935     return retval;
936  }
937  
938 @@ -1859,8 +1810,7 @@
939                 jcr->last_fname);
940           Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
941              jcr->last_fname);
942 -
943 -         return false;
944 +         return true;
945        }
946  
947        is_extensible = true;
948 @@ -1873,13 +1823,11 @@
949                 jcr->last_fname);
950           Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
951              jcr->last_fname);
952 -
953 -         return false;
954 +         return true;
955        }
956 -
957        break;
958     default:
959 -      return false;
960 +      return true;
961     }
962  
963     /*
964 @@ -1889,7 +1837,6 @@
965     getcwd(cwd, sizeof(cwd));
966     retval = solaris_restore_xattrs(jcr, is_extensible);
967     chdir(cwd);
968 -
969     return retval;
970  }
971  
972 @@ -1906,13 +1853,12 @@
973        nr_xattr_saved = 0;
974  
975        /*
976 -       * As we change the cwd in the archive function save the current cwd
977 -       * for restore after return from the solaris_archive_xattrs function.
978 +       * As we change the cwd in the save function save the current cwd
979 +       * for restore after return from the solaris_save_xattrs function.
980         */
981        getcwd(cwd, sizeof(cwd));
982 -      retval = solaris_archive_xattrs(jcr, NULL, NULL);
983 +      retval = solaris_save_xattrs(jcr, NULL, NULL);
984        chdir(cwd);
985 -
986        drop_xattr_link_cache();
987     }
988  
989 @@ -1928,7 +1874,10 @@
990     case STREAM_XATTR_SOLARIS:
991        return solaris_extract_xattr(jcr, stream);
992     default:
993 -      return false;
994 +      Jmsg2(jcr, M_WARNING, 0,
995 +         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
996 +         jcr->last_fname, stream);
997 +      return true;                    /* non-fatal error */
998     }
999  }
1000  #endif