New API calls iso_node_get_projid(), iso_node_set_projid(), iso_local_get_projid(), iso_local_set_projid()

This commit is contained in:
Thomas Schmitt 2024-11-03 19:17:32 +01:00
parent 72f0365458
commit b7c1e03ff7
17 changed files with 603 additions and 44 deletions

View File

@ -26,8 +26,9 @@ libisofs_libisofs_la_LDFLAGS = \
# ts A90409: Enabling use of zlib. # ts A90409: Enabling use of zlib.
# ts B00927: Enabling use of libjte (Jigdo Template Extraction) # ts B00927: Enabling use of libjte (Jigdo Template Extraction)
# ts C40713: Enabling system adapter for Linux chattr(1) flags # ts C40713: Enabling system adapter for Linux chattr(1) flags
# ts C41009: Enabling system adapter for project id of XFS-style quota
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(LFA_DEF) \ libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(LFA_DEF) \
$(ZLIB_DEF) $(LIBJTE_DEF) $(PROJID_DEF) $(ZLIB_DEF) $(LIBJTE_DEF)
# ts A90114 : added aaip_0_2.* # ts A90114 : added aaip_0_2.*

View File

@ -302,6 +302,23 @@ else
fi fi
AC_SUBST(LFA_DEF) AC_SUBST(LFA_DEF)
dnl ts C41009
PROJID_DEF=
AC_ARG_ENABLE(projid,
[ --enable-projid Enable processing of XFS-style project id, default=yes],
, enable_projid=yes)
if test x"$enable_projid" = xyes; then
AC_CHECK_HEADER(linux/fs.h, PROJID_DEF="-DLibisofs_with_aaip_projiD",
PROJID_DEF=)
fi
if test x"$PROJID_DEF" = x; then
echo "disabled XFS-style project id"
else
echo "enabled XFS-style project id"
fi
AC_SUBST(PROJID_DEF)
dnl ts A90409 dnl ts A90409
AC_ARG_ENABLE(zlib, AC_ARG_ENABLE(zlib,
[ --enable-zlib Enable use of zlib by libisofs, default=yes], [ --enable-zlib Enable use of zlib by libisofs, default=yes],

View File

@ -176,6 +176,7 @@ Format of Value:
Example: Example:
(FS_SECRM_FL|FS_APPEND_FL|FS_NOCOMP_FL) = 0x421 (FS_SECRM_FL|FS_APPEND_FL|FS_NOCOMP_FL) = 0x421
{ 4 , 33 } { 4 , 33 }
Registered: Registered:
12 Jul 2024 by Thomas Schmitt for libisofs. 12 Jul 2024 by Thomas Schmitt for libisofs.
@ -250,6 +251,27 @@ Registered:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Name:
isofs.pi
Purpose:
Records the project id for XFS-style quota management.
See man xfs_quota(8).
Missing isofs.pi is defaulted to project id 0.
Format of Value:
A byte string which begins with the most significant byte.
Up to four bytes are permissible.
Example:
Project id 258
{ 1, 2 }
Registered:
09 Oct 2024 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name: Name:
isofs.st isofs.st

View File

@ -47,7 +47,9 @@
Bitfield corresponding to flag. Bitfield corresponding to flag.
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types. bit2= Linux-like file attribute flags (chattr) adapter is enabled
bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
int aaip_local_attr_support(int flag) int aaip_local_attr_support(int flag)
@ -95,6 +97,16 @@ int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
} }
/* Obtain the project id for XFS-style quota management.
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag)
{
*projid= 0;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -155,3 +167,12 @@ int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
} }
/* Set the project id for XFS-style quota management.
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}

View File

@ -57,7 +57,9 @@
Bitfield corresponding to flag. Bitfield corresponding to flag.
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types. bit2= Linux-like file attribute flags (chattr) adapter is enabled
bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
int aaip_local_attr_support(int flag) int aaip_local_attr_support(int flag)
@ -391,6 +393,8 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
bit6= do not obtain Linux style file attribute flags bit6= do not obtain Linux style file attribute flags
(chattr). (chattr).
This obtaining is not implemented here anyways. This obtaining is not implemented here anyways.
bit8= do not obtain XFS-style project id.
This obtaining is not implemented here anyways.
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return 1 ok @return 1 ok
2 ok, no permission to inspect non-user namespaces 2 ok, no permission to inspect non-user namespaces
@ -725,6 +729,16 @@ int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
} }
/* Obtain the project id for XFS-style quota management.
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag)
{
*projid= 0;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -1123,3 +1137,12 @@ int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
} }
/* Set the project id for XFS-style quota management.
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}

View File

@ -56,7 +56,8 @@
bit0= inquire availability of ACL bit0= inquire availability of ACL
bit1= inquire availability of xattr bit1= inquire availability of xattr
bit2= inquire availability of Linux-like file attribute flags bit2= inquire availability of Linux-like file attribute flags
bit3 - bit7= Reserved for future types. bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now. It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0 bit8 and higher: reserved, submit 0
@return @return
@ -64,7 +65,8 @@
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2= Linux-like file attribute flags adapter is enabled bit2= Linux-like file attribute flags adapter is enabled
bit3 - bit7= Reserved for future types. bit3= XFS-style project id is enabled
bit4 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
int aaip_local_attr_support(int flag) int aaip_local_attr_support(int flag)
@ -88,6 +90,15 @@ int aaip_local_attr_support(int flag)
ret|= 4; ret|= 4;
#endif #endif
#endif #endif
#endif
#ifdef Libisofs_with_aaip_projiD
#ifdef FS_IOC_FSGETXATTR
#ifdef FS_IOC_FSSETXATTR
if(flag & 8)
ret|= 8;
#endif
#endif
#endif #endif
return(ret); return(ret);
@ -283,6 +294,7 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
(chattr) (chattr)
bit7= Without bit6: Ignore non-settable flags and do bit7= Without bit6: Ignore non-settable flags and do
not record "isofs.fa" if all flags are zero not record "isofs.fa" if all flags are zero
bit8= do not obtain XFS-style project id
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return 1 ok @return 1 ok
(reserved for FreeBSD: 2 ok, no permission to inspect (reserved for FreeBSD: 2 ok, no permission to inspect
@ -316,6 +328,9 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
int max_bit, os_errno, lfa_length; int max_bit, os_errno, lfa_length;
unsigned char lfa_value[8]; unsigned char lfa_value[8];
#endif #endif
#ifdef Libisofs_with_aaip_projiD
uint32_t projid;
#endif
if(flag & (1 << 15)) { /* Free memory */ if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;} {ret= 1; goto ex;}
@ -386,6 +401,16 @@ ex:;
#endif #endif
#ifdef Libisofs_with_aaip_projiD
if(!(flag & 256)) {
ret= iso_local_get_projid(path, &projid, &os_errno, 0);
if(ret > 0 && projid != 0)
num_names++;
}
#endif /* Libisofs_with_aaip_projiD */
if(num_names == 0) if(num_names == 0)
{ret= 1; goto ex;} {ret= 1; goto ex;}
(*names)= calloc(num_names, sizeof(char *)); (*names)= calloc(num_names, sizeof(char *));
@ -463,7 +488,7 @@ try_lfa_flags:;
ret= 4; ret= 4;
} }
if(ret == 1 || ret == 2) { if(ret == 1 || ret == 2) {
ret= aaip_encode_lfa_flags(lfa_flags, lfa_value, &lfa_length, 0); ret= aaip_encode_uint64(lfa_flags, lfa_value, &lfa_length, 0);
if(ret > 0) { if(ret > 0) {
(*names)[*num_attrs]= strdup("isofs.fa"); (*names)[*num_attrs]= strdup("isofs.fa");
if((*names)[*num_attrs] == NULL) if((*names)[*num_attrs] == NULL)
@ -480,6 +505,29 @@ try_lfa_flags:;
#endif /* Libisofs_with_aaip_lfa_flagS */ #endif /* Libisofs_with_aaip_lfa_flagS */
#ifdef Libisofs_with_aaip_projiD
if(!(flag & 256)) {
ret= iso_local_get_projid(path, &projid, &os_errno, 0);
if(ret > 0 && projid != 0) {
/* Encode as big-endian number with no trailing 0-bytes */
ret= aaip_encode_uint64((uint64_t) projid, lfa_value, &lfa_length, 0);
if(ret > 0) {
(*names)[*num_attrs]= strdup("isofs.pi");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= calloc(lfa_length, 1);
if((*values)[*num_attrs] == NULL)
{ret= -1; goto ex;}
memcpy((*values)[*num_attrs], (char *) lfa_value, lfa_length);
(*value_lengths)[*num_attrs]= lfa_length;
(*num_attrs)++;
}
}
}
#endif /* Libisofs_with_aaip_projiD */
ret= 1; ret= 1;
ex:; ex:;
#ifdef Libisofs_with_aaip_acL #ifdef Libisofs_with_aaip_acL
@ -530,6 +578,7 @@ ex:;
@param lfa_flags Will get filled with the FS_*_FL @param lfa_flags Will get filled with the FS_*_FL
@param max_bit Will tell the highest bit that is possibly set @param max_bit Will tell the highest bit that is possibly set
(-1 = surely no bit is valid) (-1 = surely no bit is valid)
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes. @param flag Bitfield for control purposes.
bit0= consider ENOTTY from FS_IOC_GETFLAGS an error bit0= consider ENOTTY from FS_IOC_GETFLAGS an error
(else return 4 on ENOTTY) (else return 4 on ENOTTY)
@ -606,6 +655,64 @@ int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
} }
/* Obtain the project id for XFS-style quota management.
See man xfs_quota(8).
@param path Path to the file.
@param projid Will get filled with the project id.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, *projid is valid
0= local project id retrieval not enabled at compile
time
<0 error with system calls:
-1= error with open(2)
-2= error with ioctl(2)
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_projiD
#ifdef FS_IOC_FSGETXATTR
int fd;
struct fsxattr ioctl_result;
#endif
#endif
*projid= 0;
#ifdef Libisofs_with_aaip_projiD
#ifdef FS_IOC_FSGETXATTR
fd= open(path, O_RDONLY | O_NDELAY);
if(fd == -1) {
aaip_local_error("open", path, errno, 0);
*os_errno= errno;
return(-1);
}
ret= ioctl(fd, FS_IOC_FSGETXATTR, &ioctl_result);
close(fd);
if(ret == -1) {
if(!(flag & 4))
aaip_local_error("ioctl(FS_IOC_FSGETXATTR)", path, errno, 0);
*os_errno= errno;
return(-2);
}
*projid= ioctl_result.fsx_projid;
ret= 1;
#endif /* FS_IOC_FSGETXATTR */
#endif /* Libisofs_with_aaip_lfa_flagS */
return(ret);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -960,3 +1067,61 @@ int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
return(ret); return(ret);
} }
/* Set the project id for XFS-style quota management.
@param path Path to the file.
@param projid Contains the project id for the file.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, projid was written
0= local flags setting not enabled at compile time
-1= error with open(2)
-2= error with ioctl(FS_IOC_FSGETXATTR)
-3= error with ioctl(FS_IOC_FSSETXATTR)
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_projiD
#ifdef FS_IOC_FSGETXATTR
#ifdef FS_IOC_FSSETXATTR
int fd;
struct fsxattr ioctl_arg;
fd= open(path, O_RDONLY | O_NDELAY);
if(fd == -1) {
if(!(flag & 4))
aaip_local_error("open", path, errno, 0);
*os_errno= errno;
return(-1);
}
ret= ioctl(fd, FS_IOC_FSGETXATTR, &ioctl_arg);
if(ret == -1) {
if(!(flag & 4))
aaip_local_error("ioctl(FS_IOC_FSGETXATTR)", path, errno, 0);
*os_errno= errno;
close(fd);
return(-2);
}
ioctl_arg.fsx_projid= projid;
ret= ioctl(fd, FS_IOC_FSSETXATTR, &ioctl_arg);
close(fd);
if(ret == -1) {
if(!(flag & 4))
aaip_local_error("ioctl(FS_IOC_FSSETXATTR)", path, errno, 0);
*os_errno= errno;
return(-3);
}
ret= 1;
#endif /* FS_IOC_FSSETXATTR */
#endif /* FS_IOC_FSGETXATTR */
#endif /* Libisofs_with_aaip_lfa_flagS */
return(ret);
}

View File

@ -900,8 +900,8 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
} }
int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8], int aaip_encode_uint64(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag) int *length, int flag)
{ {
int i, l; int i, l;

View File

@ -162,8 +162,8 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
@param length Will return the number of filled-in value bytes @param length Will return the number of filled-in value bytes
@return <0 failure @return <0 failure
*/ */
int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8], int aaip_encode_uint64(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag); int *length, int flag);
/* ------ OS interface ------ */ /* ------ OS interface ------ */
@ -174,7 +174,8 @@ int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8],
bit0= inquire availability of ACL bit0= inquire availability of ACL
bit1= inquire availability of xattr bit1= inquire availability of xattr
bit2= inquire availability of Linux-like file attribute flags bit2= inquire availability of Linux-like file attribute flags
bit3 - bit7= Reserved for future types. bit3= inquire availability of XFS-style project id
bit4 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now. It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0 bit8 and higher: reserved, submit 0
@return @return
@ -182,7 +183,8 @@ int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8],
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2= Linux-like file attribute flags adapter is enabled bit2= Linux-like file attribute flags adapter is enabled
bit3 - bit7= Reserved for future types. bit3= XFS-style project id is enabled
bit4 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now. It is permissibile to set them to 1 already now.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
@ -227,6 +229,9 @@ int aaip_get_acl_text(char *path, char **text, int flag);
bit5= in case of symbolic link: inquire link target bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags bit6= do not obtain Linux style file attribute flags
(chattr) (chattr)
bit7= Without bit6: Ignore non-settable flags and do
not record "isofs.fa" if all flags are zero
bit8= do not obtain XFS-style project id
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return >0 ok @return >0 ok
<=0 error <=0 error
@ -265,6 +270,24 @@ int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag); int *os_errno, int flag);
/* Obtain the project id for XFS-style quota management.
See man xfs_quota(8).
@param path Path to the file.
@param projid Will get filled with the project id.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, *projid is valid
0= local project id retrieval not enabled at compile
time
<0 error with system calls:
-1= error with open(2)
-2= error with ioctl(2)
*/
int aaip_get_projid(char *path, uint32_t *projid, int *os_errno, int flag);
/* --------------------------------- Decoder ---------------------------- */ /* --------------------------------- Decoder ---------------------------- */
/* /*
@ -591,5 +614,20 @@ int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag); int *os_errno, int flag);
/* Set the project id for XFS-style quota management.
@param path Path to the file.
@param projid Contains the project id for the file.
@param os_errno Will get filled with errno in case of error.
@param flag Bitfield for control purposes.
bit2= do not issue own error messages with operating
system errors
@return 1= ok, projid was written
0= local flags setting not enabled at compile time
-1= error with open(2)
-2= error with ioctl(FS_IOC_FSGETXATTR)
-3= error with ioctl(FS_IOC_FSSETXATTR)
*/
int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag);
#endif /* ! Aaip_h_is_includeD */ #endif /* ! Aaip_h_is_includeD */

View File

@ -255,7 +255,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
(image->builder_ignore_ea << 2) | (image->builder_ignore_ea << 2) |
(image->builder_take_all_ea << 3) | (image->builder_take_all_ea << 3) |
((!image->builder_ignore_lfa_flags) << 4) | ((!image->builder_ignore_lfa_flags) << 4) |
(image->builder_ignore_ro_lfa_flags << 5) ); (image->builder_ignore_ro_lfa_flags << 5) |
((!image->builder_ignore_projid) << 6));
if(ret == 2) if(ret == 2)
image->blind_on_local_get_attrs = 1; image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) { if (ret > 0 && aa_string != NULL) {

View File

@ -507,14 +507,14 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
*aa_string = NULL; *aa_string = NULL;
if ((flag & (2 | 4 | 16) ) == (2 | 4)) { if ((flag & (2 | 4 | 16 | 64) ) == (2 | 4)) {
/* Neither ACL nor xattr shall be read, lfa_flags are not wanted */ /* Neither ACL nor xattr shall be read, lfa_flags are not wanted */
ret = 1; ret = 1;
goto ex; goto ex;
} }
/* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according /* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according
to AAIP ACL representation. Clean out st_mode ACL entries. to AAIP ACL representation. Clean out st_mode ACL entries.
Obtain Linux style attribute flags. Obtain Linux style attribute flags and XFS-style project id.
*/ */
path = iso_file_source_get_path(src); path = iso_file_source_get_path(src);
if (path == NULL) { if (path == NULL) {
@ -524,7 +524,8 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
ret = aaip_get_attr_list(path, &num_attrs, &names, ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values, &value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16 | (!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16 |
((!(flag & 16)) << 6) | ((!!(flag & 32)) << 7)); ((!(flag & 16)) << 6) | ((!!(flag & 32)) << 7) |
((!(flag & 64)) << 8));
if (ret <= 0) { if (ret <= 0) {
if (ret == -2) if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL; ret = ISO_AAIP_NO_GET_LOCAL;
@ -866,13 +867,14 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag)
int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names, int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag) size_t **value_lengths, char ***values, int flag)
{ {
int ret, lfa; int ret, lfa, prj;
lfa = (flag & 64) ^ 64; lfa = (flag & 64) ^ 64;
prj = (flag & (1 << 8)) ^ (1 << 8);
ret = aaip_get_attr_list(disk_path, ret = aaip_get_attr_list(disk_path,
num_attrs, names, value_lengths, values, num_attrs, names, value_lengths, values,
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | (flag & (1 | 4 | 8 | 32 | 256 | (1 << 15))) |
2 | 16 | lfa); 2 | 16 | lfa | prj);
if (ret <= 0) if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL; return ISO_AAIP_NO_GET_LOCAL;
return 1 + (ret == 2); return 1 + (ret == 2);
@ -958,7 +960,6 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
* 4= ok, file did not bear attribute flags. E.g. because not S_IFDIR or * 4= ok, file did not bear attribute flags. E.g. because not S_IFDIR or
* S_IFREG, or because unsuitable filesystem. * S_IFREG, or because unsuitable filesystem.
* lfa_flags is set to 0 * lfa_flags is set to 0
* 0= local flags retrieval not enabled at compile time
* <0= error with system calls * <0= error with system calls
*/ */
int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit, int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
@ -976,7 +977,7 @@ int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
ret = lstat(disk_path, &stbuf); ret = lstat(disk_path, &stbuf);
if (ret == -1) { if (ret == -1) {
*os_errno = errno; *os_errno = errno;
return -1; return ISO_FILE_DOESNT_EXIST;
} }
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32)) if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3; return 3;
@ -987,7 +988,7 @@ int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
if(ret == -1) if(ret == -1)
return ISO_LFA_NO_OPEN_LOCAL; return ISO_LFA_NO_OPEN_LOCAL;
if(ret < 0) if(ret < 0)
return ISO_LFA_NO_SET_LOCAL; return ISO_LFA_NO_GET_LOCAL;
return ret; return ret;
} }
@ -997,7 +998,7 @@ int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
* bit0= do not try to change known superuser flags * bit0= do not try to change known superuser flags
* bit1= change only known chattr settable flags * bit1= change only known chattr settable flags
* bit2= do not issue own error messages with operating system errors * bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: inquire link target * bit5= in case of symbolic link: operate on link target
* @return * @return
* 1 = ok, all lfa_flags bits were written * 1 = ok, all lfa_flags bits were written
* 2 = ok, but some FS_*_FL bits could not be mapped to local flags * 2 = ok, but some FS_*_FL bits could not be mapped to local flags
@ -1018,7 +1019,7 @@ int iso_local_set_lfa_flags(char *disk_path, uint64_t lfa_flags, int max_bit,
ret = lstat(disk_path, &stbuf); ret = lstat(disk_path, &stbuf);
if (ret == -1) { if (ret == -1) {
*os_errno = errno; *os_errno = errno;
return -1; return ISO_FILE_DOESNT_EXIST;
} }
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32)) if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3; return 3;
@ -1050,3 +1051,77 @@ int iso_local_set_lfa_flags(char *disk_path, uint64_t lfa_flags, int max_bit,
} }
/*
* @param flag
* Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: inquire link target
* @return
* 1= ok, projid is valid
* 3 = ok, symbolic link encountered, flag bit5 not set, projid set to 0
* <0= error with system calls
*/
int iso_local_get_projid(char *disk_path, uint32_t *projid, int *os_errno,
int flag)
{
int ret;
struct stat stbuf;
*projid = 0;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
ret = aaip_get_projid(disk_path, projid, os_errno, flag & 4);
if(ret == 0)
return ISO_PROJID_NOT_ENABLED;
if(ret == -1)
return ISO_PROJID_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_PROJID_NO_SET_LOCAL;
return ret;
}
/*
* @param flag Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: manipulate link target
* @return
* 1 = ok, projid was written
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*/
int iso_local_set_projid(char *disk_path, uint32_t projid, int *os_errno,
int flag)
{
int ret;
struct stat stbuf;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return ISO_FILE_DOESNT_EXIST;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
ret = aaip_set_projid(disk_path, projid, os_errno, flag & 4);
if(ret == 0)
return ISO_PROJID_NOT_ENABLED;
if (ret == -1)
return ISO_PROJID_NO_OPEN_LOCAL;
if(ret < 0)
return ISO_PROJID_NO_SET_LOCAL;
return ret;
}

View File

@ -202,6 +202,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->builder_ignore_ea = 1; img->builder_ignore_ea = 1;
img->builder_ignore_lfa_flags = 1; img->builder_ignore_lfa_flags = 1;
img->builder_ignore_ro_lfa_flags = 0; img->builder_ignore_ro_lfa_flags = 0;
img->builder_ignore_projid = 1;
img->truncate_mode = 1; img->truncate_mode = 1;
img->truncate_length = LIBISOFS_NODE_NAME_MAX; img->truncate_length = LIBISOFS_NODE_NAME_MAX;
img->truncate_buffer[0] = 0; img->truncate_buffer[0] = 0;
@ -631,9 +632,10 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
{ {
image->builder_ignore_acl = (what & 1); image->builder_ignore_acl = (what & 1);
image->builder_ignore_ea = !!(what & 2); image->builder_ignore_ea = !!(what & 2);
image->builder_ignore_lfa_flags= !(what & 4); image->builder_ignore_lfa_flags = !(what & 4);
image->builder_take_all_ea = !!(what & 8); image->builder_take_all_ea = !!(what & 8);
image->builder_ignore_ro_lfa_flags = !!(what & 32); image->builder_ignore_ro_lfa_flags = !!(what & 32);
image->builder_ignore_projid = !!(what & 64);
} }
@ -643,7 +645,8 @@ int iso_image_get_ignore_aclea(IsoImage *image)
(image->builder_ignore_ea << 1) | (image->builder_ignore_ea << 1) |
((!image->builder_ignore_lfa_flags) << 2) | ((!image->builder_ignore_lfa_flags) << 2) |
(image->builder_take_all_ea << 3) | (image->builder_take_all_ea << 3) |
(image->builder_ignore_ro_lfa_flags << 5); (image->builder_ignore_ro_lfa_flags << 5) |
((!image->builder_ignore_projid) << 6);
} }

View File

@ -145,6 +145,12 @@ struct Iso_Image
*/ */
unsigned int builder_ignore_ea : 1; unsigned int builder_ignore_ea : 1;
/**
* If not builder_ignore_ea : import all xattr namespaces from local
* filesystem, not only "user.
*/
unsigned int builder_take_all_ea : 1;
/** /**
* Whether to ignore Linux style file attribute flags (chattr). * Whether to ignore Linux style file attribute flags (chattr).
* Not in effect with loading a complete ISO image but only with image * Not in effect with loading a complete ISO image but only with image
@ -160,11 +166,11 @@ struct Iso_Image
*/ */
unsigned int builder_ignore_ro_lfa_flags : 1; unsigned int builder_ignore_ro_lfa_flags : 1;
/** /* Whether to ignore XFS-style project id.
* If not builder_ignore_ea : import all xattr namespaces from local * Not in effect with loading a complete ISO image but only with image
* filesystem, not only "user. * manipulation.
*/ */
unsigned int builder_take_all_ea : 1; unsigned int builder_ignore_projid : 1;
/** /**
* Files to exclude. Wildcard support is included. * Files to exclude. Wildcard support is included.

View File

@ -874,6 +874,8 @@ struct IsoFileSource_Iface
* attribute flags and do not record "isofs.fa" * attribute flags and do not record "isofs.fa"
* if the other flags are all zero * if the other flags are all zero
* @since 1.5.8 * @since 1.5.8
* bit6= Try to get XFS-style project id as "isofs.pi"
* @since 1.5.8
* @param aa_string Returns a pointer to the AAIP string data. If no AAIP * @param aa_string Returns a pointer to the AAIP string data. If no AAIP
* string is available, *aa_string becomes NULL. * string is available, *aa_string becomes NULL.
* (See doc/susp_aaip_*_*.txt for the meaning of AAIP and * (See doc/susp_aaip_*_*.txt for the meaning of AAIP and
@ -1328,6 +1330,10 @@ int iso_image_new(const char *name, IsoImage **image);
* bit5= with bit2: Ignore non-settable Linux-like file attribute flags * bit5= with bit2: Ignore non-settable Linux-like file attribute flags
* and do not record "isofs.fa" if the other flags are all zero * and do not record "isofs.fa" if the other flags are all zero
* @since 1.5.8 * @since 1.5.8
* bit6= read XFS-style project from the file object id and record
* "isofs.pi" if it is not 0.
* (I.e. a do-not-ignore, because ignoring was default before)
* @since 1.5.8
* all other bits are reserved * all other bits are reserved
* *
* @since 0.6.14 * @since 0.6.14
@ -7296,6 +7302,8 @@ int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz);
* attribute flags and do not record "isofs.fa" * attribute flags and do not record "isofs.fa"
* if the other flags are all zero * if the other flags are all zero
* @since 1.5.8 * @since 1.5.8
* bit6= Try to get XFS-style project id as "isofs.pi"
* @since 1.5.8
* @return 1 means success (*aa_string == NULL is possible) * @return 1 means success (*aa_string == NULL is possible)
* <0 means failure and must b a valid libisofs error code * <0 means failure and must b a valid libisofs error code
* (e.g. ISO_FILE_ERROR if no better one can be found). * (e.g. ISO_FILE_ERROR if no better one can be found).
@ -7860,13 +7868,51 @@ int iso_node_get_lfa_flags(IsoNode *node, uint64_t *lfa_flags, int *max_bit,
int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag); int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag);
/* ----- This is an interface to ACL and xattr of the local filesystem ----- */ /**
* Obtain the XFS-style project id of the given node.
* The result is 0 if no project id information is associated with the node.
*
* @param node
* The node that is to be inquired.
* @param projid
* Will get filled with the project id
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* 1 = ok, projid is valid
* < 0 = error
*
* @since 1.5.8
*/
int iso_node_get_projid(IsoNode *node, uint32_t *projid, int flag);
/** /**
* libisofs has an internal system dependent adapter to ACL and xattr * Set the Linux-like XFS-style project id of the given node.
* operations. For the sake of completeness and simplicity it exposes this *
* functionality to its applications which might want to get and set ACLs * @param node
* from local files. * The node that is to be manipulated.
* @param projid
* The project id to be set.
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* 1 = ok
* < 0 = error
*
* @since 1.5.8
*/
int iso_node_set_projid(IsoNode *node, uint32_t projid, int flag);
/* ---- This is an interface to file attributes of the local filesystem ---- */
/**
* libisofs has an internal system dependent adapter to perform operations on
* ACL, xattr, Linux-like file attribute flags, and XFS-style project ids.
* For the sake of completeness and simplicity it exposes this functionality
* to its applications which might want to get and set such attributes from
* local files.
*/ */
/** /**
@ -7879,7 +7925,11 @@ int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag);
* Bitfield for control purposes * Bitfield for control purposes
* bit0= inquire availability of ACL * bit0= inquire availability of ACL
* bit1= inquire availability of xattr * bit1= inquire availability of xattr
* bit2 - bit7= Reserved for future types. * bit2= inquire availability of Linux-like file attribute flags
* @since 1.5.8
* bit3= inquire availability of XFS-style project id
* @since 1.5.8
* bit4 - bit7= Reserved for future types.
* It is permissibile to set them to 1 already now. * It is permissibile to set them to 1 already now.
* bit8 and higher: reserved, submit 0 * bit8 and higher: reserved, submit 0
* @return * @return
@ -7888,7 +7938,9 @@ int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag);
* bit1= xattr adapter is enabled * bit1= xattr adapter is enabled
* bit2= Linux-like file attribute flags (chattr) adapter is enabled * bit2= Linux-like file attribute flags (chattr) adapter is enabled
* @since 1.5.8 * @since 1.5.8
* bit3 - bit7= Reserved for future types. * bit3= XFS-style project ids are enabled
* @since 1.5.8
* bit4 - bit7= Reserved for future types.
* It is permissibile to set them to 1 already now. * It is permissibile to set them to 1 already now.
* bit8 and higher: reserved, do not interpret these * bit8 and higher: reserved, do not interpret these
* *
@ -7896,6 +7948,7 @@ int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag);
*/ */
int iso_local_attr_support(int flag); int iso_local_attr_support(int flag);
/** /**
* Get an ACL of the given file in the local filesystem in long text form. * Get an ACL of the given file in the local filesystem in long text form.
* *
@ -7971,8 +8024,9 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
/** /**
* Get xattr, non-trivial ACLs, and possible Linux-like file attribute flags * Get xattr, non-trivial ACLs, possible Linux-like file attribute flags
* (chattr) of the given file in the local filesystem. * (chattr), and XFS-style project id of the given file in the local
* filesystem.
* The resulting data has finally to be disposed by a call to this function * The resulting data has finally to be disposed by a call to this function
* with flag bit15 set. * with flag bit15 set.
* *
@ -7998,6 +8052,9 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
* I.e. those with a name which does not begin by "user." * I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: inquire link target * bit5= in case of symbolic link: inquire link target
* bit6= obtain Linux-like file attribute flags (chattr) as "isofs.fa" * bit6= obtain Linux-like file attribute flags (chattr) as "isofs.fa"
* @since 1.5.8
* bit8= obtain XFS-style non-zero project id as "isofs.pi"
* @since 1.5.8
* bit15= free memory * bit15= free memory
* @return * @return
* 1 ok * 1 ok
@ -8238,6 +8295,55 @@ void iso_util_get_lfa_masks(uint64_t *user_settable, uint64_t *su_settable,
*/ */
uint64_t iso_util_get_effective_lfa_mask(uint64_t change_mask, int flag); uint64_t iso_util_get_effective_lfa_mask(uint64_t change_mask, int flag);
/**
* Obtain the XFS-style project id of the given file.
*
* @param disk_path
* Path to the file
* @param projid
* Will get filled with the project id number.
* @param os_errno
* Will get filled with errno if a system call fails.
* Else it will be filled with 0.
* @param flag
* Bitfield for control purposes
* bit2= do not issue own error messages with operating system errors
* bit5= in case of symbolic link: inquire link target
* @return
* 1 = ok, projid is valid
* 3 = ok, symbolic link encountered, flag bit5 not set, projid set to 0
* <0 = error with system calls
*
* @since 1.5.8
*/
int iso_local_get_projid(char *disk_path, uint32_t *projid, int *os_errno,
int flag);
/**
* Bring the given XFS-style project id into effect with the given file.
*
* @param disk_path
* Path to the file
* @param projid
* Project id
* @param os_errno
* Will get filled with errno if a system call fails.
* Else it will be filled with 0.
* @param flag
* Bitfield for control purposes
* bit2= do not issue own error messages with system call errors
* bit5= in case of symbolic link: operate on link target
* @return
* 1 = ok, projid was written
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*
* @since 1.5.8
*/
int iso_local_set_projid(char *disk_path, uint32_t projid, int *os_errno,
int flag);
/* Default in case that the compile environment has no macro PATH_MAX. /* Default in case that the compile environment has no macro PATH_MAX.
@ -9742,10 +9848,26 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
(SORRY,HIGH, -434) */ (SORRY,HIGH, -434) */
#define ISO_LFA_NO_SET_LOCAL 0xE030FE4E #define ISO_LFA_NO_SET_LOCAL 0xE030FE4E
/** Failure to open local file for setting Linux-like file attributes /** Failure to open local file for Linux-like file attributes
(SORRY,HIGH, -435) */ (SORRY,HIGH, -435) */
#define ISO_LFA_NO_OPEN_LOCAL 0xE030FE4D #define ISO_LFA_NO_OPEN_LOCAL 0xE030FE4D
/** Local XFS-style file project id processing not enabled at compile time
(SORRY,HIGH, -436) */
#define ISO_PROJID_NOT_ENABLED 0xE030FE4C
/** Error with getting XFS-style project id of local file
(SORRY,HIGH, -437) */
#define ISO_PROJID_NO_GET_LOCAL 0xE030FE4B
/** Error with setting XFS-style project id of local file
(SORRY,HIGH, -438) */
#define ISO_PROJID_NO_SET_LOCAL 0xE030FE4A
/** Failure to open local file for XFS-style project id
(SORRY,HIGH, -439) */
#define ISO_PROJID_NO_OPEN_LOCAL 0xE030FE49
/* Internal developer note: /* Internal developer note:

View File

@ -387,9 +387,13 @@ local: *;
LIBISOFS6_1.5.8 { LIBISOFS6_1.5.8 {
iso_local_get_lfa_flags; iso_local_get_lfa_flags;
iso_local_get_projid;
iso_local_set_lfa_flags; iso_local_set_lfa_flags;
iso_local_set_projid;
iso_node_get_lfa_flags; iso_node_get_lfa_flags;
iso_node_get_projid;
iso_node_set_lfa_flags; iso_node_set_lfa_flags;
iso_node_set_projid;
iso_util_decode_lfa_flags; iso_util_decode_lfa_flags;
iso_util_encode_lfa_flags; iso_util_encode_lfa_flags;
iso_util_get_effective_lfa_mask; iso_util_get_effective_lfa_mask;

View File

@ -585,6 +585,14 @@ const char *iso_error_to_msg(int errcode)
return "Error with setting Linux-like file attributes of local file"; return "Error with setting Linux-like file attributes of local file";
case ISO_LFA_NO_OPEN_LOCAL: case ISO_LFA_NO_OPEN_LOCAL:
return "Failure to open local file for Linux-like file attributes"; return "Failure to open local file for Linux-like file attributes";
case ISO_PROJID_NOT_ENABLED:
return "Local XFS-style file project id processing not enabled at compile time";
case ISO_PROJID_NO_GET_LOCAL:
return "Error with getting XFS-style project id of local file";
case ISO_PROJID_NO_SET_LOCAL:
return "Error with setting XFS-style project id of local file";
case ISO_PROJID_NO_OPEN_LOCAL:
return "Failure to open local file for XFS-style project id";
default: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -2058,6 +2058,7 @@ ex:;
/* @param flag /* @param flag
bit0= delete ACL, too bit0= delete ACL, too
bit1= delete file attribute flags (isofs.fa), too bit1= delete file attribute flags (isofs.fa), too
bit2= delete XFS-style project id (isofs.pi), too
*/ */
int iso_node_remove_fattr(IsoNode *node, int flag) int iso_node_remove_fattr(IsoNode *node, int flag)
{ {
@ -2074,7 +2075,8 @@ int iso_node_remove_fattr(IsoNode *node, int flag)
w = 0; w = 0;
for (i = 0; i < num_attrs; i++) { for (i = 0; i < num_attrs; i++) {
if (strncmp(names[i], "isofs.", 6) != 0 || if (strncmp(names[i], "isofs.", 6) != 0 ||
((flag & 2) && strcmp(names[i], "isofs.fa") == 0)) { ((flag & 2) && strcmp(names[i], "isofs.fa") == 0) ||
((flag & 4) && strcmp(names[i], "isofs.pi") == 0)) {
free(names[i]); free(names[i]);
names[i] = NULL; names[i] = NULL;
free(values[i]); free(values[i]);
@ -2462,7 +2464,7 @@ int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag)
char *valuept; char *valuept;
int ret, l; int ret, l;
ret = aaip_encode_lfa_flags(lfa_flags, value, &l, 0); ret = aaip_encode_uint64(lfa_flags, value, &l, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
value_lengths[0] = l; value_lengths[0] = l;
@ -2501,6 +2503,57 @@ int iso_node_get_lfa_flags(IsoNode *node, uint64_t *lfa_flags, int *max_bit,
} }
int iso_node_set_projid(IsoNode *node, uint32_t projid, int flag)
{
static char *names = "isofs.pi";
static size_t value_lengths[1];
unsigned char value[8];
char *valuept = NULL;
int ret, l;
value_lengths[0] = 0;
if(projid == 0) {
/* Delete isofs.pi */
ret = iso_node_set_attrs(node, (size_t) 1, &names,
value_lengths, &valuept, 2 | 4 | 8);
return ret;
}
ret = aaip_encode_uint64((uint64_t) projid, value, &l, 0);
if (ret < 0)
return ret;
value_lengths[0] = l;
valuept= (char *) value;
ret = iso_node_set_attrs(node, (size_t) 1,
&names, value_lengths, &valuept, 2 | 8);
return ret;
}
int iso_node_get_projid(IsoNode *node, uint32_t *projid, int flag)
{
int ret, i;
size_t value_len;
char *value = NULL;
*projid = 0;
ret = iso_node_lookup_attr(node, "isofs.pi", &value_len, &value, 0);
if (ret < 0)
return ret;
if (ret == 0)
return 1;
if (value_len <= 0)
return 1;
if (value_len > 4) {
value += value_len - 4;
value_len = 4;
}
for (i = 0; i < (int) value_len; i++)
*projid = (*projid << 8) | ((unsigned char *) value)[i];
return 1;
}
/* Function to identify and manage ZF parameters. /* Function to identify and manage ZF parameters.
* data is supposed to be a pointer to struct zisofs_zf_info * data is supposed to be a pointer to struct zisofs_zf_info
*/ */

View File

@ -1600,10 +1600,10 @@ try_again:
} }
} else if (retry == 2) { } else if (retry == 2) {
if ((t->opts->max_ce_drop_attr & 15) >= 2) { if ((t->opts->max_ce_drop_attr & 15) >= 2) {
ret = iso_node_remove_fattr(n->node, 1 | 2); ret = iso_node_remove_fattr(n->node, 1 | 2 | 4);
if (ret > 0) { if (ret > 0) {
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0, iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
"Removed ACL and attribute flags"); "Removed ACL, attribute flags, project id");
goto try_again; goto try_again;
} }
} }