New -lfa_flags mode "restore_single"

This commit is contained in:
2024-09-08 12:22:27 +02:00
parent 66a7440b0c
commit b2ae46a4cf
9 changed files with 188 additions and 90 deletions

View File

@ -303,11 +303,16 @@ ex:;
}
/*
@flag bit0= do not report error in case of error worth of single flag try
@return 0=failure, 1=ok, 2=pardoned,
3=pardoned error worth of single flag try
*/
int Xorriso_report_chattr_outcome(struct XorrisO *xorriso, char *disk_path,
uint64_t lfa_flags, uint64_t lfa_mask,
int iso_ret, int os_errno, int flag)
{
int ret, eps_ret, sev;
int ret, eps_ret, sev, lfa_error= 0;
char msg[101], *lfa_text= NULL, severity[20];
if(iso_ret == 1)
@ -323,11 +328,15 @@ int Xorriso_report_chattr_outcome(struct XorrisO *xorriso, char *disk_path,
if(lfa_text == NULL)
lfa_text= strdup("-unknown-attributes-");
if(iso_ret < 0) {
if(iso_ret == (int) ISO_LFA_NO_SET_LOCAL) {
lfa_error= 1;
if(flag & 1)
{ret= 3; goto ex;}
}
strcpy(msg, "Could not set chattr '");
if(lfa_text != NULL)
strcat(msg, lfa_text);
strcat(msg, "'");
/* Adjust severity to event_pt.
Number 0x7f000000 comes from libisofs.h, iso_error_get_severity */
Xorriso__text_to_sev(severity, &sev, 0);
@ -355,7 +364,7 @@ ex:;
if(ret == 0) {
eps_ret= Xorriso_eval_problem_status(xorriso, 0, 1);
if(eps_ret >= 0)
ret= 2;
ret= 2 + !!lfa_error;
}
if(lfa_text != NULL)
free(lfa_text);
@ -363,6 +372,58 @@ ex:;
}
/*
@param flag bit0= try single attribute flags if the whole change_mask fails
possibly because of inappropriate attributes
@return 0=failure
1= ok
2= pardoned
3= pardoned error worth of single flag try
4= with bit0: partial success
*/
int Xorriso_local_set_lfa_flags(struct XorrisO *xorriso, char *disk_path,
uint64_t lfa_flags, int max_bit,
uint64_t change_mask, int *os_errno, int flag)
{
int ret, partial_success= 0, os_errno_mem, i, count;
uint64_t single_mask, single_lfa;
ret= iso_local_set_lfa_flags(disk_path, lfa_flags, max_bit, change_mask,
os_errno, 4);
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_flags, change_mask,
ret, *os_errno, flag & 1);
if(ret != 3 || !(flag & 1))
return(ret);
/* Try with single flag calls */
count= 0;
for(i= 0; i <= max_bit && i < 64; i++)
if(change_mask & (((uint64_t) 1) << i))
count++;
if(count < 2)
return(ret); /* was already a single flag call */
os_errno_mem= *os_errno;
for(i= 0; i <= max_bit && i < 64; i++) {
single_mask= ((uint64_t) 1) << i;
if(!(single_mask & change_mask))
continue;
single_lfa= lfa_flags & single_mask;
*os_errno= 0;
ret= iso_local_set_lfa_flags(disk_path, single_lfa, max_bit, single_mask,
os_errno, 4);
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, single_lfa,
single_mask, ret, *os_errno, 0);
if(ret <= 0)
return(ret);
if(ret == 1)
partial_success= 1;
}
*os_errno= os_errno_mem;
return(3 + !!partial_success);
}
uint64_t Xorriso__lfa_bits(char *lfa_text)
{
int ret;
@ -459,10 +520,9 @@ int Xorriso_early_chattr_CF(struct XorrisO *xorriso, IsoNode *node,
set_mask&= xorriso_mask;
if(set_mask == 0)
return(4);
ret= iso_local_set_lfa_flags(disk_path, lfa_flags, max_bit, set_mask,
os_errno, 4);
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_flags, set_mask,
ret, *os_errno, 0);
ret= Xorriso_local_set_lfa_flags(xorriso, disk_path, lfa_flags, max_bit,
set_mask, os_errno,
!!(xorriso->do_aaip & (1 << 16)));
if(ret <= 0)
return(ret);
return(1);
@ -668,10 +728,9 @@ cannot_set_perm:;
if(xorriso->do_aaip & (1 << 12)) {
if(mask != 0) {
ret= iso_local_set_lfa_flags(disk_path, lfa_flags, max_bit, mask,
&os_errno, 4);
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_flags,
mask, ret, os_errno, 0);
ret= Xorriso_local_set_lfa_flags(xorriso, disk_path, lfa_flags, max_bit,
mask, &os_errno,
!!(xorriso->do_aaip & (1 << 16)));
if(ret <= 0)
goto ex;
}