netatalk  4.6.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
subtests_cnid.h File Reference

Go to the source code of this file.

Functions

int utest_cnid_volume_tag_identity (void)
 cnid_volume_tag() names the CNID table, not the session's volume slot
int utest_cnid_wrapper_sets_errno (void)
 Every CNID_INVALID from the wrapper carries its own errno.
int utest_cnid_error_codes_distinct (void)
 The CNID error codes stay distinct and out of the errno range.
int utest_cnid_valide_byteorder (void)
 valide() compares CNIDs in the right byte order
int utest_cnid_resolve_dotdot_rejected (void)
 The wrapper's ".." rejection fails like a backend failure.
int utest_cnid_add_busy_not_fatal (struct vol *vol)
 A contended CNID database classifies as BUSY, not as a dead backend.
int utest_cnid_add_depletion_resets (struct vol *vol)
 Exhausting the CNID space reports CNID_ERR_RESET, not a recycled id.
int utest_cnid_uuid_case_keeps_table (struct vol *vol)
 A UUID differing only in case reuses the live table, never drops it.
int utest_cnid_resolve_notfound_errno (struct vol *vol)
 A not-found answer classifies out of the syscall errno range.
int utest_cnid_corrupt_row_classified (struct vol *vol)
 64-bit rows that do not fit a CNID classify as corrupt, not truncate
int utest_cnid_find_no_truncated_id (struct vol *vol)
 A search never returns a CNID narrowed out of a 64-bit rowid.
int utest_cnid_dup_row_no_truncated_delete (struct vol *vol)
 Duplicate-row cleanup never deletes through a truncated rowid.

Function Documentation

◆ utest_cnid_add_busy_not_fatal()

int utest_cnid_add_busy_not_fatal ( struct vol * vol)
extern

A contended CNID database classifies as BUSY, not as a dead backend.

A peer connection holding the write lock is ordinary contention between two sessions on one volume. afpd ends the session on CNID_ERR_DB (get_id() in etc/afpd/file.c), so contention must not report as one. The blocked add waits out the backend's busy timeout, so this test stalls for that long.

◆ utest_cnid_add_depletion_resets()

int utest_cnid_add_depletion_resets ( struct vol * vol)
extern

Exhausting the CNID space reports CNID_ERR_RESET, not a recycled id.

The 32-bit ceiling empties the table, so every CNID any session holds now names nothing or, as the table refills, another file. Returning a fresh id as though nothing happened is what the classification exists to prevent.

◆ utest_cnid_corrupt_row_classified()

int utest_cnid_corrupt_row_classified ( struct vol * vol)
extern

64-bit rows that do not fit a CNID classify as corrupt, not truncate

A narrowed rowid names an unrelated live file, to hand out or to delete through, so an out-of-range Id or Did fails as CNID_ERR_CORRUPT. The db file is mode 0666, so such a row is one plain INSERT away.

◆ utest_cnid_dup_row_no_truncated_delete()

int utest_cnid_dup_row_no_truncated_delete ( struct vol * vol)
extern

Duplicate-row cleanup never deletes through a truncated rowid.

Two rows can legitimately satisfy lookup's disjuncts, (Name, Did) and (DevNo, InodeNo), and the surplus one is deleted. A surplus Id that does not fit a CNID narrows onto an unrelated live row, so it is reported as corruption and both rows are left in place.

◆ utest_cnid_error_codes_distinct()

int utest_cnid_error_codes_distinct ( void )
extern

The CNID error codes stay distinct and out of the errno range.

The codes travel in errno and are compared against it, so each must be unique and clear of every system errno value. Their handling diverges sharply: get_id() (etc/afpd/file.c) ends the session on CNID_ERR_DB and fails just the one operation on the rest.

◆ utest_cnid_find_no_truncated_id()

int utest_cnid_find_no_truncated_id ( struct vol * vol)
extern

A search never returns a CNID narrowed out of a 64-bit rowid.

cnid_find() feeds FPCatSearch, and a client opens what the search reports, so a narrowed Id hands it an unrelated live file. The out-of-range row is left out of the results.

◆ utest_cnid_resolve_dotdot_rejected()

int utest_cnid_resolve_dotdot_rejected ( void )
extern

The wrapper's ".." rejection fails like a backend failure.

cnid_resolve() (libatalk/cnid/cnid.c) refuses a ".." name from the backend as a whole failure: NULL return, *id overwritten with CNID_INVALID in place of the parent DID the backend wrote, and errno set to CNID_ERR_CORRUPT.

◆ utest_cnid_resolve_notfound_errno()

int utest_cnid_resolve_notfound_errno ( struct vol * vol)
extern

A not-found answer classifies out of the syscall errno range.

The dbd wire constant CNID_DBD_RES_NOTFOUND equals EPERM, and callers that switch on raw errno map EPERM to AFPERR_ACCESS (movecwd() in etc/afpd/directory.c), so an absent row answers CNID_ERR_NOTFOUND. The CNID probed here is high in the range and has no row.

◆ utest_cnid_uuid_case_keeps_table()

int utest_cnid_uuid_case_keeps_table ( struct vol * vol)
extern

A UUID differing only in case reuses the live table, never drops it.

SQLite table names are case-insensitive, but the stale-volume scan compares VolUUID bytewise. A second session under a case-flipped spelling of the same UUID must therefore find the same table, and the CNIDs in it must survive.

◆ utest_cnid_valide_byteorder()

int utest_cnid_valide_byteorder ( void )
extern

valide() compares CNIDs in the right byte order

Backends return CNIDs in network byte order, and valide() (libatalk/cnid/cnid.c) screens them against the host-order CNID_START of 17. On a little-endian host 16 valid ids byte-swap to below that bound, the lowest being host id 0x01000000, and the reserved ids 1-16 swap to above it.

◆ utest_cnid_volume_tag_identity()

int utest_cnid_volume_tag_identity ( void )
extern

cnid_volume_tag() names the CNID table, not the session's volume slot

v_vid is a counter each child assigns in its own volume-load order, so the same vid names different volumes in different children. The tag is derived from the volume UUID, which every child that opens the volume agrees on.

◆ utest_cnid_wrapper_sets_errno()

int utest_cnid_wrapper_sets_errno ( void )
extern

Every CNID_INVALID from the wrapper carries its own errno.

Callers branch on the CNID_ERR_* values to choose between a permanent reply and a retryable one, and get_id() (etc/afpd/file.c) ends the session on CNID_ERR_DB, so a rejection sets errno itself rather than leaving an earlier operation's value in place. The poison value here, EPERM, is what a failed chown or seteuid leaves behind and is also CNID_DBD_RES_NOTFOUND's value.