preparing for bringing this all together

This commit is contained in:
Motiejus Jakštys 2022-02-28 06:14:00 +02:00 committed by Motiejus Jakštys
parent 0b0e917086
commit 40deb3f0be
2 changed files with 28 additions and 16 deletions

View File

@ -70,6 +70,11 @@ Tight packing places some constraints on the underlying data:
- Permitted comment ("gecos") length: 0-255 bytes. - Permitted comment ("gecos") length: 0-255 bytes.
- User name, groupname, gecos and shell must be utf8-encoded. - User name, groupname, gecos and shell must be utf8-encoded.
Sorting is stable. In v0:
- Groups are sorted by gid, ascending.
- Users are sorted by their name, ascending by the unicode codepoints
(locale-independent).
Checking out and building Checking out and building
------------------------- -------------------------
@ -182,10 +187,9 @@ the beginning of the section.
``` ```
const PackedGroup = packed struct { const PackedGroup = packed struct {
gid: u32, gid: u32,
// index to a separate structure with a list of members. The memberlist is // index to a separate structure with a list of members.
// 2^5-byte aligned (32b), this is an index there. members_offset: u32,
members_offset: u27, groupname_len: u8, // max is 32, but have too much space here.
groupname_len: u5,
// a groupname_len-sized string // a groupname_len-sized string
groupname []u8; groupname []u8;
} }
@ -281,7 +285,7 @@ Similarly, when user's groups are resolved in (2), they are not always necessary
(i.e. not part of `struct user*`), therefore the memberships themselves are (i.e. not part of `struct user*`), therefore the memberships themselves are
stored out of bound. stored out of bound.
`Groupmembers` and `Username2gids` store group and user memberships `Groupmembers` and `UserGids` store group and user memberships
respectively. Membership IDs are used in their entirety — not necessitating respectively. Membership IDs are used in their entirety — not necessitating
random access, thus suitable for tight packing and varint encoding. random access, thus suitable for tight packing and varint encoding.
@ -290,7 +294,7 @@ random access, thus suitable for tight packing and varint encoding.
- For each user — a list of gids, because `initgroups_dyn` (and friends) - For each user — a list of gids, because `initgroups_dyn` (and friends)
returns an array of gids. returns an array of gids.
An entry of `Groupmembers` and `Username2gids` looks like this piece of An entry of `Groupmembers` and `UserGids` looks like this piece of
pseudo-code: pseudo-code:
``` ```
@ -299,7 +303,7 @@ const PackedList = struct {
Members: [Length]varint, Members: [Length]varint,
} }
const Groupmembers = PackedList; const Groupmembers = PackedList;
const Username2gids = PackedList; const UserGids = PackedList;
``` ```
Indices Indices
@ -355,15 +359,24 @@ STATUS SECTION SIZE DESCRIPTION
idx_groupname2group len(group)*29/8 bdz->offset Groups idx_groupname2group len(group)*29/8 bdz->offset Groups
idx_uid2user len(user)*29/8 bdz->offset Users idx_uid2user len(user)*29/8 bdz->offset Users
idx_name2user len(user)*29/8 bdz->offset Users idx_name2user len(user)*29/8 bdz->offset Users
idx_username2gids len(user)*29/8 bdz->offset Username2gids idx_username2gids len(user)*29/8 bdz->offset UserGids
✅ ShellIndex len(shells)*2 Shell index array ✅ ShellIndex len(shells)*2 shell index array
✅ ShellBlob <= 4032 Shell data blob (max 63*64 bytes) ✅ ShellBlob <= 4032 shell data blob (max 63*64 bytes)
✅ Groups ? packed Group entries (8b padding) ✅ Groups ? packed Group entries (8b padding)
✅ Users ? packed User entries (8b padding) ✅ Users ? packed User entries (8b padding)
Groupmembers ? per-group memberlist (32b padding) Groupmembers ? per-group memberlist (no padding)
Username2gids ? Per-user gidlist entries (8b padding) UserGids ? per-user gidlist entries (8b padding)
``` ```
Section creation order:
1. Groupmembers, UserGids. No dependencies.
2. ShellIndex, ShellBlob. No dependencies.
3. `bdz_*`. No depdendencies.
4. Groups. Requires Groupmembers.
5. Users. Requires Groupmembers and ShellIndex.
6. `idx_*`. Requires offsets to Groups and Users.
[git-subtrac]: https://apenwarr.ca/log/20191109 [git-subtrac]: https://apenwarr.ca/log/20191109
[cmph]: http://cmph.sourceforge.net/ [cmph]: http://cmph.sourceforge.net/
[id]: https://linux.die.net/man/1/id [id]: https://linux.die.net/man/1/id

View File

@ -1,9 +1,8 @@
// //
// varint64 []const u8 variants // varint64 []const u8 variants
// //
// Thanks to https://github.com/gsquire/zig-snappy/blob/master/snappy.zig and golang's // Thanks to https://github.com/gsquire/zig-snappy/blob/master/snappy.zig and
// varint implementation. // golang's varint implementation.
const std = @import("std"); const std = @import("std");
// compresses a strictly incrementing sorted slice of integers using delta // compresses a strictly incrementing sorted slice of integers using delta
@ -96,7 +95,7 @@ pub const Varint = struct {
bytesRead: usize, bytesRead: usize,
}; };
const maxVarintLen64 = 10; pub const maxVarintLen64 = 10;
// https://golang.org/pkg/encoding/binary/#Uvarint // https://golang.org/pkg/encoding/binary/#Uvarint
pub fn uvarint(buf: []const u8) error{Overflow}!Varint { pub fn uvarint(buf: []const u8) error{Overflow}!Varint {