### Set up a Trivial Filesystem with libtrivfs Source: https://context7.com/llp-dev/hurd/llms.txt Configures global variables and hooks for a trivial filesystem. The `main` function demonstrates connecting to the bootstrap port and starting the server loop using `trivfs_startup`. ```c #include /* Mandatory global variables every trivfs server must define */ int trivfs_fstype = FSTYPE_MISC; int trivfs_fsid = 0; int trivfs_support_read = 1; int trivfs_support_write = 1; int trivfs_support_exec = 0; int trivfs_allow_open = O_READ | O_WRITE; /* Mandatory: modify stat info before presenting it to clients */ void trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *st) { st->st_size = 0; /* virtual; no real size */ st->st_blocks = 0; st->st_mode &= ~0111; /* clear execute bits */ } /* Optional open hook: invoked before a new open is granted */ error_t (*trivfs_check_open_hook) (struct trivfs_control *cntl, struct iouser *user, int flags) = my_check_open; /* --- trivfs_startup: connect to the bootstrap port and start serving --- */ int main (int argc, char **argv) { struct trivfs_control *fsys; mach_port_t bootstrap; task_get_bootstrap_port (mach_task_self (), &bootstrap); error_t err = trivfs_startup (bootstrap, O_RDWR, NULL, NULL, /* use default port classes */ NULL, NULL, &fsys); if (err) error (1, err, "trivfs_startup"); /* Run the server loop */ ports_manage_port_operations_multithread (fsys->pi.bucket, trivfs_demuxer, 2000, 0, NULL); return 0; } ``` -------------------------------- ### Start ext2fs.static as the bootstrap filesystem Source: https://context7.com/llp-dev/hurd/llms.txt Configures `ext2fs.static` as the primary filesystem during the Hurd boot process, passing necessary kernel command-line arguments and port information. ```sh # Start ext2fs.static as the bootstrap filesystem (from hurd.boot script) # /hurd/ext2fs.static --multiboot-command-line=${kernel-command-line} \ # --host-priv-port=${host-port} --device-master-port=${device-port} \ # --exec-server-task=${exec-task} -T device ${root-device} \ # $(task-create) $(task-resume) ``` -------------------------------- ### Filesystem Control Interface (`hurd/fsys.defs`) Source: https://context7.com/llp-dev/hurd/llms.txt Controls entire filesystem servers: starting them up, shutting them down, fetching their root, syncing, and configuring runtime options. ```APIDOC ## fsys_startup ### Description This function is typically called by filesystem translators during their bootstrap process to register themselves and obtain the underlying node port. ### Method `fsys_startup` ### Parameters - `bootstrap` (mach_port_t) - The bootstrap port of the task. - `flags` (int) - Flags for startup (e.g., `O_READ`). - `control_port` (mach_port_t) - The control port of the server. - `realnode` (mach_port_t *) - Pointer to store the port of the underlying node. ### Request Example ```c mach_port_t bootstrap = task_get_bootstrap_port (); mach_port_t realnode; fsys_startup (bootstrap, O_READ, my_control_port, &realnode); ``` ``` ```APIDOC ## fsys_getroot ### Description Obtains the root node port of a filesystem. ### Method `fsys_getroot` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `dotdot_port` (mach_port_t) - The parent port (unauthenticated). - `uids` (uid_t *) - Array of UIDs for authentication. - `num_uids` (size_t) - Number of UIDs. - `gids` (gid_t *) - Array of GIDs for authentication. - `num_gids` (size_t) - Number of GIDs. - `flags` (int) - Flags for opening the root (e.g., `O_RDONLY`). - `do_retry` (retry_type *) - Pointer to store retry information. - `retry_name` (char[1024]) - Buffer to store retry name. - `root` (mach_port_t *) - Pointer to store the root node port. ### Request Example ```c char retry_name[1024]; mach_port_t root; uid_t uids[] = { getuid() }; gid_t gids[] = { getgid() }; fsys_getroot (fsctrl, dotdot_port, uids, 1, gids, 1, O_RDONLY, &do_retry, retry_name, &root); ``` ``` ```APIDOC ## fsys_goaway ### Description Shuts down a filesystem gracefully. ### Method `fsys_goaway` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `flags` (int) - Flags for shutdown (e.g., `FSYS_GOAWAY_RECURSE`). ### Request Example ```c fsys_goaway (fsctrl, FSYS_GOAWAY_RECURSE); ``` ``` ```APIDOC ## fsys_syncfs ### Description Flushes all pending writes to storage for a filesystem. ### Method `fsys_syncfs` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `wait` (int) - Whether to wait for the sync to complete (1 for wait). - `sync_children` (int) - Whether to sync child filesystems (1 for sync). ### Request Example ```c fsys_syncfs (fsctrl, 1, 1); ``` ``` ```APIDOC ## fsys_set_options ### Description Configures runtime options for a filesystem. ### Method `fsys_set_options` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `opts` (const char *) - String containing the options. - `opts_len` (size_t) - Length of the options string. - `flags` (int) - Flags for setting options (e.g., 0 for this node only). ### Request Example ```c const char opts[] = "--readonly"; fsys_set_options (fsctrl, opts, sizeof(opts), 0); ``` ``` ```APIDOC ## fsys_get_options ### Description Retrieves the current runtime options of a filesystem. ### Method `fsys_get_options` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `cur_opts` (char **) - Pointer to a buffer that will be allocated to store the options string. - `opts_len` (mach_msg_type_number_t *) - Pointer to store the length of the options string. ### Request Example ```c char *cur_opts; mach_msg_type_number_t opts_len; fsys_get_options (fsctrl, &cur_opts, &opts_len); // cur_opts should be freed by the caller when done ``` ``` ```APIDOC ## fsys_getpriv ### Description Retrieves privileged host and device master ports associated with the filesystem. ### Method `fsys_getpriv` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `host_priv` (mach_port_t *) - Pointer to store the host privilege port. - `device_master` (mach_port_t *) - Pointer to store the device master port. - `fstask` (mach_port_t *) - Pointer to store the filesystem task port. ### Request Example ```c mach_port_t host_priv, device_master, fstask; fsys_getpriv (fsctrl, &host_priv, &device_master, &fstask); ``` ``` ```APIDOC ## fsys_get_source ### Description Queries the source of the filesystem, such as its device path. ### Method `fsys_get_source` ### Parameters - `fsctrl` (fsys_t) - The filesystem control port. - `source` (char[1024]) - Buffer to store the filesystem source string. ### Request Example ```c char source[1024]; fsys_get_source (fsctrl, source); printf ("filesystem source: %s\n", source); ``` ``` -------------------------------- ### Attach and start an active translator using settrans Source: https://context7.com/llp-dev/hurd/llms.txt Attaches and immediately starts an active translator for a given filesystem node. Useful for temporary filesystems or services. ```sh # Attach and immediately start an active translator settrans -a /mount/tmpfs /hurd/tmpfs --size=256M ``` -------------------------------- ### Create and Manage Ports with libports Source: https://context7.com/llp-dev/hurd/llms.txt Demonstrates the creation of port buckets, classes, and individual ports. Includes examples for obtaining Mach port rights, managing reference counts, and serving RPCs. Use this for building Mach RPC servers. ```c #include error_t err; /* --- Create a port bucket (a portset of related ports) --- */ struct port_bucket *bucket = ports_create_bucket (); /* --- Define a port class with a cleanup callback --- */ struct port_class *my_class = ports_create_class (my_cleanup_fn, /* called when last ref dropped */ my_dropweak_fn); /* called on weak-ref drop */ /* --- Allocate a port of a given class --- */ struct my_server_port { struct port_info pi; /* MUST be first member */ int my_data; }; struct my_server_port *p; err = ports_create_port (my_class, bucket, sizeof(*p), &p); p->my_data = 42; /* --- Get the Mach port right for the port --- */ mach_port_t send_right = ports_get_right (p); /* --- Start serving RPCs from a bucket --- */ ports_manage_port_operations_multithread (bucket, my_demuxer, /* mach_msg_header_t * -> bool */ 30 * 1000, /* idle thread timeout (ms) */ 5 * 60 * 1000, /* max server idle time (ms) */ NULL); /* global interrupt callback */ /* --- Reference counting --- */ ports_port_ref (p); /* add a hard reference */ ports_port_deref (p); /* release a hard reference */ ports_port_ref_weak (p); /* add a weak reference */ ports_port_deref_weak (p); /* --- Inhibit/resume RPCs on a bucket (for quiescing a server) --- */ err = ports_inhibit_bucket_rpcs (bucket); /* ... quiesce state ... */ ports_resume_bucket_rpcs (bucket); /* --- Iterate over all ports in a class --- */ err = ports_class_iterate (my_class, ^error_t (void *port) { struct my_server_port *sp = port; printf ("port data: %d\n", sp->my_data); return 0; }); ``` -------------------------------- ### Create and Manage a Pager using libpager Source: https://context7.com/llp-dev/hurd/llms.txt Demonstrates the process of creating and managing a pager, including starting workers, creating a pager instance, obtaining its memory object port, and mapping it into a task. Also shows how to inhibit and resume workers. ```c /* --- Create and manage a pager --- */ struct port_bucket *pager_bucket = ports_create_bucket (); struct pager_requests *preqs; pager_start_workers (pager_bucket, &preqs); struct user_pager_info upi = { .np = my_node }; struct pager *pg = pager_create (&upi, pager_bucket, TRUE, /* may_cache */ MEMORY_OBJECT_COPY_DELAY, FALSE); /* notify_on_evict */ /* Get the memory object port to hand to vm_map */ mach_port_t memobj = pager_get_port (pg); /* Map the pager's memory object into the current task */ vm_address_t addr = 0; vm_map (mach_task_self (), &addr, my_node->dn_stat.st_size, 0, TRUE /* anywhere */, memobj, 0, FALSE, VM_PROT_READ, VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_COPY); /* Inhibit workers before a quiesce */ pager_inhibit_workers (preqs); /* ... flush state ... */ pager_resume_workers (preqs); ``` -------------------------------- ### Start a passive filesystem translator Source: https://context7.com/llp-dev/hurd/llms.txt Launches a translator binary by supplying a callback function to open the underlying node. Ensure the translator binary path and arguments are correctly specified. ```c #include error_t err; /* --- Start a passive translator (by launching the binary) --- */ /* Supply a callback that opens the underlying node */ error_t my_open_fn (int flags, file_t *node, mach_msg_type_name_t *type, task_t task, void *cookie) { *node = file_name_lookup ((char *) cookie, flags, 0); *type = MACH_MSG_TYPE_COPY_SEND; return *node == MACH_PORT_NULL ? errno : 0; } fsys_t control; char argz[] = "/hurd/ext2fs\0/dev/hd1s1\0"; err = fshelp_start_translator (my_open_fn, "/dev/hd1s1", "/hurd/ext2fs", argz, sizeof(argz), 60000 /* timeout ms */, &control); ``` -------------------------------- ### libnetfs Standard Main Function Source: https://context7.com/llp-dev/hurd/llms.txt The standard main function for a netfs server. It initializes the root node and calls `netfs_main` to start the server. ```c /* Standard main for a netfs server */ int main (int argc, char **argv) { struct netnode *root_nn = new_netnode_for_root (); netfs_root_node = netfs_make_node (root_nn); return netfs_main (argc, argv); } ``` -------------------------------- ### Get and Encode Storage Information using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Illustrates how to initialize, allocate, and encode storage information for a store. The encoded information is stored in `enc.ports`, `enc.ints`, `enc.offsets`, and `enc.data`. ```c /* --- Get storage encoding (for file_get_storage_info) --- */ struct store_enc enc; store_enc_init (&enc, NULL, 0, NULL, 0, NULL, 0, NULL, 0); store_allocate_encoding (st, &enc); store_encode (st, &enc); /* enc.ports, enc.ints, enc.offsets, enc.data are now populated */ ``` -------------------------------- ### Create a Remap Store using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Shows how to create a remapped store that restricts access to a specific subrange of an existing store. The subrange is defined by start and length. ```c /* --- Create a remap store (restrict to a subrange) --- */ struct store_run runs[] = { { .start = 2048, .length = 4096 } }; struct store *remapped; err = store_remap (st, runs, 1, &remapped); ``` -------------------------------- ### libdiskfs Standard Main Function Source: https://context7.com/llp-dev/hurd/llms.txt The standard main function for a diskfs server. It initializes the store name and calls `diskfs_main` to start the server. ```c /* Standard main for a diskfs server */ int main (int argc, char **argv) { store_parsed_t store_parsed; diskfs_store_name = argv[argc - 1]; return diskfs_main (argc, argv, diskfs_default_pager, &store_parsed); } ``` -------------------------------- ### Write Blocks to a Store using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Illustrates writing a specified number of bytes from a buffer to a store at a given block address and run index. The example writes 512 zero bytes. ```c /* --- Write blocks to a store --- */ char zeros[512] = {0}; size_t written; err = store_write (st, 0, 0, zeros, 512, &written); ``` -------------------------------- ### Get Current Process Information Source: https://context7.com/llp-dev/hurd/llms.txt Retrieves the current process's PID, PPID, and orphan status. Requires the process port. ```c #include /* generated from process.defs */ process_t proc = getproc (); /* current process's proc port */ error_t err; /* --- proc_getpids: get own PID, PPID, orphan flag --- */ pid_t pid, ppid; int orphaned; err = proc_getpids (proc, &pid, &ppid, &orphaned); printf ("pid=%d ppid=%d orphaned=%d\n", pid, ppid, orphaned); ``` -------------------------------- ### libfshelp: Filesystem Helper Library Source: https://context7.com/llp-dev/hurd/llms.txt Utilities for managing filesystem translators, including starting passive and active translators, tracking active translators, and translator slot management. ```APIDOC ## `libfshelp` — Filesystem Helper Library (`libfshelp/fshelp.h`) Utilities shared across all filesystem implementations: starting passive and active translators, tracking active translators, and the `transbox` abstraction for translator slot management. ### Start a passive translator (by launching the binary) Supply a callback that opens the underlying node. ```c error_t my_open_fn (int flags, file_t *node, mach_msg_type_name_t *type, task_t task, void *cookie) { *node = file_name_lookup ((char *) cookie, flags, 0); *type = MACH_MSG_TYPE_COPY_SEND; return *node == MACH_PORT_NULL ? errno : 0; } fsys_t control; char argz[] = "/hurd/ext2fs\0/dev/hd1s1\0"; err = fshelp_start_translator (my_open_fn, "/dev/hd1s1", "/hurd/ext2fs", argz, sizeof(argz), 60000 /* timeout ms */, &control); ``` ### Track active translators by name ```c err = fshelp_set_active_translator (my_port_info, "/mount/usb0", &my_node->transbox); /* later, on unmount: */ err = fshelp_remove_active_translator (control_port); ``` ### List all active translators ```c char *list; size_t list_len; mach_port_t *controls; size_t ncontrols; err = fshelp_get_active_translators (&list, &list_len, &controls, &ncontrols); /* iterate list as an argz vector */ char *entry = NULL; while ((entry = argz_next (list, list_len, entry))) printf ("active: %s\n", entry); ``` ### Initialize and use a transbox (active translator slot) ```c struct transbox tbox; pthread_mutex_t tbox_lock = PTHREAD_MUTEX_INITIALIZER; fshelp_transbox_init (&tbox, &tbox_lock, my_fetch_root_cb1, my_node); mach_port_t trans_root; err = fshelp_fetch_root (&tbox, NULL /* cookie2 */, MACH_PORT_NULL /* dotdot */, my_user, O_RDONLY, &trans_root, my_fetch_root_cb2); ``` ``` -------------------------------- ### Set and Get Executable Path Source: https://context7.com/llp-dev/hurd/llms.txt Records or queries the binary path associated with a process. Use `proc_set_exe` to set the path and `proc_get_exe` to retrieve it. ```c /* --- proc_set_exe / proc_get_exe: record/query binary path --- */ err = proc_set_exe (proc, "/usr/bin/myserver"); char exe_path[1024]; err = proc_get_exe (proc, pid, exe_path); ``` -------------------------------- ### dir_lookup Source: https://context7.com/llp-dev/hurd/llms.txt Resolves a pathname starting from a directory. It takes a starting directory port, a path, and flags, returning a file_t port for the resolved path or retry information. ```APIDOC ## dir_lookup ### Description Resolves a pathname starting from a directory. ### Parameters - **start** (file_t) - The starting directory port. - **path** (const char*) - The pathname to resolve. - **flags** (int) - Flags for opening the file (e.g., O_RDONLY). - **mode** (int) - Mode for file creation if applicable. - **do_retry** (retry_type*) - Pointer to store retry information. - **retry_name** (char[1024]) - Buffer to store retry name if needed. - **result** (mach_port_t*) - Pointer to store the resulting file_t port. ### Example ```c file_t start = getdport (0); retry_type do_retry; char retry_name[1024]; mach_port_t result; error_t err = dir_lookup (start, "subdir/file.txt", O_RDONLY, 0, &do_retry, retry_name, &result); ``` ``` -------------------------------- ### Get Uname Information Source: https://context7.com/llp-dev/hurd/llms.txt Retrieves system information similar to the `uname` system call, including system name, node name, and release version. ```c /* --- proc_uname: get uname information --- */ struct utsname uts; err = proc_uname (proc, &uts); printf ("%s %s %s\n", uts.sysname, uts.nodename, uts.release); ``` -------------------------------- ### Filesystem Control Operations in Hurd Source: https://context7.com/llp-dev/hurd/llms.txt Controls entire filesystem servers: starting them up, shutting them down, fetching their root, syncing, and configuring runtime options. ```c #include /* generated from fsys.defs */ fsys_t fsctrl; /* the filesystem control port */ error_t err; /* --- fsys_startup: translator calls this on its bootstrap port --- */ /* (Normally called from inside trivfs_startup / diskfs_startup, not directly by user code.) */ mach_port_t bootstrap = task_get_bootstrap_port (); mach_port_t realnode; err = fsys_startup (bootstrap, O_READ, my_control_port, /* this server's control port */ &realnode); /* gets the underlying node back */ ``` ```c /* --- fsys_getroot: obtain the root node of a filesystem --- */ retry_type do_retry; char retry_name[1024]; mach_port_t root; uid_t uids[] = { getuid() }; gid_t gids[] = { getgid() }; err = fsys_getroot (fsctrl, dotdot_port, /* unauthenticated parent port */ uids, 1, gids, 1, O_RDONLY, &do_retry, retry_name, &root); ``` ```c /* --- fsys_goaway: shut down a filesystem gracefully --- */ err = fsys_goaway (fsctrl, FSYS_GOAWAY_RECURSE); ``` ```c /* --- fsys_syncfs: flush all pending writes to storage --- */ err = fsys_syncfs (fsctrl, 1 /* wait */, 1 /* sync children */); ``` ```c /* --- fsys_set_options / fsys_get_options: runtime configuration --- */ const char opts[] = "--readonly"; err = fsys_set_options (fsctrl, opts, sizeof(opts), 0 /* this node only */); ``` ```c char *cur_opts; mach_msg_type_number_t opts_len; err = fsys_get_options (fsctrl, &cur_opts, &opts_len); ``` ```c /* --- fsys_getpriv: get privileged host and device master ports --- */ mach_port_t host_priv, device_master, fstask; err = fsys_getpriv (fsctrl, &host_priv, &device_master, &fstask); ``` ```c /* --- fsys_get_source: query source (e.g., device path) --- */ char source[1024]; err = fsys_get_source (fsctrl, source); printf ("filesystem source: %s\n", source); ``` -------------------------------- ### dir_readdir: Iterate directory entries Source: https://context7.com/llp-dev/hurd/llms.txt Iterates through directory entries. Allows specifying a starting index and the number of entries to read, with no buffer size limit. ```c /* --- dir_readdir: iterate directory entries --- */ file_t dir; /* previously opened directory port */ char *data; mach_msg_type_number_t data_len; int amount; err = dir_readdir (dir, &data, &data_len, 0, /* starting entry index */ -1, /* read as many as convenient */ 0, /* no buffer size limit */ &amount); /* walk returned data as struct dirent using d_reclen */ ``` -------------------------------- ### dir_lookup: Resolve pathname from a directory Source: https://context7.com/llp-dev/hurd/llms.txt Resolves a pathname starting from a given directory port. Use `FS_RETRY_NORMAL` and an empty `retry_name` to indicate that the result is ready. ```c #include #include /* --- dir_lookup: resolve a pathname starting from a directory --- */ file_t start = getdport (0); /* current working directory */ retry_type do_retry; char retry_name[1024]; mach_port_t result; error_t err = dir_lookup (start, "subdir/file.txt", O_RDONLY, 0, &do_retry, retry_name, &result); /* do_retry == FS_RETRY_NORMAL and retry_name == "" means result is ready */ ``` -------------------------------- ### Start an active translator specified in a passive record Source: https://context7.com/llp-dev/hurd/llms.txt Initiates the translator defined in a node's passive record. This is typically used after a passive translator has been attached. ```sh # Start the active translator specified in the node's passive record settrans -s /mount/disk ``` -------------------------------- ### Get Detailed Process Information Source: https://context7.com/llp-dev/hurd/llms.txt Fetches detailed information for a specific PID, including task info and thread details. The `flags` parameter controls what information is retrieved. The returned data must be cast to `struct procinfo`. ```c /* --- proc_getprocinfo: detailed info for a PID --- */ int flags = PI_FETCH_TASKINFO | PI_FETCH_THREADS; int *procinfo_data; mach_msg_type_number_t procinfo_len; char *threadwaits; mach_msg_type_number_t waits_len; err = proc_getprocinfo (proc, pid, &flags, &procinfo_data, &procinfo_len, &threadwaits, &waits_len); struct procinfo *pi = (struct procinfo *) procinfo_data; printf ("nthreads=%d state=0x%x\n", pi->nthreads, pi->state); ``` -------------------------------- ### Open and Access a Store using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Demonstrates opening a store by name (auto-detecting type) and accessing its size and block size. Supports various store types like devices and files. ```c #include struct store *st; error_t err; /* --- Open a store by name (auto-detect type) --- */ err = store_open ("device:hd0s1", 0 /* flags */, NULL, &st); /* or: */ err = store_open ("file:/tmp/disk.img", STORE_READONLY, NULL, &st); printf ("size=%lld block_size=%zu\n", (long long) st->size, st->block_size); ``` -------------------------------- ### Attach a passive translator using settrans Source: https://context7.com/llp-dev/hurd/llms.txt Attaches a passive translator to a filesystem node. The translator is stored in the inode and started on demand. ```sh # Attach a passive translator (stored in the inode, started on demand) settrans -p /mount/disk /hurd/ext2fs /dev/hd0s1 ``` -------------------------------- ### exec_init Source: https://context7.com/llp-dev/hurd/llms.txt Initializes the exec server by providing it with its authentication handle and the process server port, typically called at boot time. ```APIDOC ## exec_init ### Description Initializes the exec server with its authentication handle at boot time. ### Parameters - **execserver** (file_t) - The port for the exec server. - **auth_handle** (auth_t) - The authentication handle for the exec server. - **proc_server** (mach_port_t) - The port for the process server. ### Returns - **error_t** - An error code indicating success or failure. ``` -------------------------------- ### Initialize Exec Server with exec_init Source: https://context7.com/llp-dev/hurd/llms.txt Initialize the exec server with its authentication handle and process server port using `exec_init`. This function is typically called at boot time. ```c /* exec_init: give the exec server its auth handle at boot time */ err = exec_init (execserver, auth_handle, proc_server); ``` -------------------------------- ### Initialize and use a transbox for translator slot management Source: https://context7.com/llp-dev/hurd/llms.txt Initializes a transbox for managing translator slots and fetches the root of a filesystem. Requires callback functions for root fetching. ```c /* --- Initialize and use a transbox (active translator slot) --- */ struct transbox tbox; pthread_mutex_t tbox_lock = PTHREAD_MUTEX_INITIALIZER; fshelp_transbox_init (&tbox, &tbox_lock, my_fetch_root_cb1, my_node); mach_port_t trans_root; err = fshelp_fetch_root (&tbox, NULL /* cookie2 */, MACH_PORT_NULL /* dotdot */, my_user, O_RDONLY, &trans_root, my_fetch_root_cb2); ``` -------------------------------- ### Create a Concat Store using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Demonstrates creating a composite store that concatenates multiple child stores. Requires opening child stores first. ```c /* --- Create a concat store from two sub-stores --- */ struct store *children[2]; store_open ("device:hd0s1", 0, NULL, &children[0]); store_open ("device:hd0s2", 0, NULL, &children[1]); struct store *concat; err = store_concat_create (children, 2, 0, NULL, &concat); ``` -------------------------------- ### Read Blocks from a Store using libstore Source: https://context7.com/llp-dev/hurd/llms.txt Shows how to read a specified number of bytes from a store at a given block address and run index. The buffer for the read data is a vm_deallocate'd region. ```c /* --- Read blocks from a store --- */ void *buf; size_t len; err = store_read (st, 512 / st->block_size, /* block address */ 0, /* run index */ 4096, /* desired bytes */ &buf, &len); /* buf is a vm_deallocate'd region */ ``` -------------------------------- ### libstore: Storage Abstraction Library Source: https://context7.com/llp-dev/hurd/llms.txt Provides a uniform block-I/O interface over various storage types like devices, files, and memory objects. It allows opening, reading, writing, and managing different types of stores. ```APIDOC ## `libstore` — Storage Abstraction Library (`libstore/store.h`) ### Description Provides a uniform block-I/O interface over devices, files, memory objects, tasks, and composite stores (concat, interleave, layer, remap). ### Functions #### `store_open` Opens a store by name, automatically detecting the type. **Parameters:** - `name` (const char *): The name of the store to open (e.g., "device:hd0s1", "file:/tmp/disk.img"). - `flags` (uint32_t): Flags for opening the store (e.g., `STORE_READONLY`). - `options` (void *): Optional configuration options. - `st` (struct store **): Pointer to a `struct store` pointer to store the opened store. **Example:** ```c struct store *st; error_t err = store_open ("device:hd0s1", 0 /* flags */, NULL, &st); ``` #### `store_read` Reads blocks from a store. **Parameters:** - `st` (struct store *): The store to read from. - `block_address` (uint64_t): The starting block address. - `run_index` (uint64_t): The run index for the read operation. - `desired_bytes` (size_t): The number of bytes to read. - `buf` (void **): Pointer to a buffer to store the read data. This buffer will be allocated and must be deallocated by the caller. - `len` (size_t *): Pointer to a size_t to store the number of bytes actually read. **Example:** ```c void *buf; size_t len; err = store_read (st, 512 / st->block_size, 0, 4096, &buf, &len); /* buf is a vm_deallocate'd region */ ``` #### `store_write` Writes blocks to a store. **Parameters:** - `st` (struct store *): The store to write to. - `block_address` (uint64_t): The starting block address. - `run_index` (uint64_t): The run index for the write operation. - `data` (const void *): Pointer to the data to write. - `length` (size_t): The number of bytes to write. - `written` (size_t *): Pointer to a size_t to store the number of bytes actually written. **Example:** ```c char zeros[512] = {0}; size_t written; err = store_write (st, 0, 0, zeros, 512, &written); ``` #### `store_concat_create` Creates a composite store that concatenates multiple sub-stores. **Parameters:** - `children` (struct store **): An array of `struct store` pointers representing the sub-stores. - `num_children` (size_t): The number of sub-stores. - `flags` (uint32_t): Flags for the concatenated store. - `options` (void *): Optional configuration options. - `concat` (struct store **): Pointer to a `struct store` pointer to store the new concatenated store. **Example:** ```c struct store *children[2]; store_open ("device:hd0s1", 0, NULL, &children[0]); store_open ("device:hd0s2", 0, NULL, &children[1]); struct store *concat; err = store_concat_create (children, 2, 0, NULL, &concat); ``` #### `store_remap` Creates a composite store that restricts access to a subrange of an existing store. **Parameters:** - `st` (struct store *): The original store. - `runs` (const struct store_run *): An array of `struct store_run` defining the remapped ranges. - `num_runs` (size_t): The number of remapped ranges. - `remapped` (struct store **): Pointer to a `struct store` pointer to store the new remapped store. **Example:** ```c struct store_run runs[] = { { .start = 2048, .length = 4096 } }; struct store *remapped; err = store_remap (st, runs, 1, &remapped); ``` #### `store_enc_init` Initializes a `struct store_enc` for encoding storage information. **Parameters:** - `enc` (struct store_enc *): Pointer to the `struct store_enc` to initialize. - `ports` (void *): Placeholder for port information. - `num_ports` (size_t): Number of ports. - `ints` (void *): Placeholder for integer information. - `num_ints` (size_t): Number of integers. - `offsets` (void *): Placeholder for offset information. - `num_offsets` (size_t): Number of offsets. - `data` (void *): Placeholder for data information. - `num_data` (size_t): Number of data elements. **Example:** ```c struct store_enc enc; store_enc_init (&enc, NULL, 0, NULL, 0, NULL, 0, NULL, 0); ``` #### `store_allocate_encoding` Allocates storage encoding information for a store. **Parameters:** - `st` (struct store *): The store for which to allocate encoding. - `enc` (struct store_enc *): Pointer to the `struct store_enc` to populate. **Example:** ```c store_allocate_encoding (st, &enc); ``` #### `store_encode` Encodes storage information for a store. **Parameters:** - `st` (struct store *): The store to encode. - `enc` (struct store_enc *): Pointer to the `struct store_enc` to populate. **Example:** ```c store_encode (st, &enc); /* enc.ports, enc.ints, enc.offsets, enc.data are now populated */ ``` #### `store_free` Frees a store and its associated resources. **Parameters:** - `st` (struct store *): The store to free. **Example:** ```c store_free (st); ``` ``` -------------------------------- ### Initialize an integer-keyed hash table Source: https://context7.com/llp-dev/hurd/llms.txt Initializes a hash table for mapping integer keys to pointer values. Can be initialized statically or dynamically on the heap. ```c #include struct hurd_ihash ht; error_t err; /* --- Initialize (static or dynamic) --- */ hurd_ihash_init (&ht, HURD_IHASH_NO_LOCP); /* or on heap: */ struct hurd_ihash *htp = hurd_ihash_create (HURD_IHASH_NO_LOCP); ``` -------------------------------- ### libnetfs Callbacks Source: https://context7.com/llp-dev/hurd/llms.txt This section details the callback functions required for implementing a network filesystem translator using libnetfs. ```APIDOC ## netfs_validate_stat ### Description Required callback to fill in the nn_stat and nn_translated fields for a given node NP. ### Parameters - **np** (struct node *) - The network node. - **cred** (struct iouser *) - User credentials. ### Return Value error_t - Returns 0 on success. ``` ```APIDOC ## netfs_attempt_lookup ### Description Required callback to create a new node for a directory entry. ### Parameters - **user** (struct iouser *) - The user performing the lookup. - **dir** (struct node *) - The directory node. - **name** (char *) - The name of the entry to look up. - **npp** (struct node **) - Output parameter for the new node. ### Return Value error_t - Returns 0 on success. ``` ```APIDOC ## netfs_attempt_read ### Description Required callback to read data from node NP at OFFSET. ### Parameters - **cred** (struct iouser *) - User credentials. - **np** (struct node *) - The network node to read from. - **offset** (loff_t) - The offset to start reading from. - **len** (size_t *) - Pointer to the number of bytes to read (will be updated with actual bytes read). - **data** (void *) - Buffer to store the read data. ### Return Value error_t - Returns 0 on success. ``` -------------------------------- ### List All Live Processes Source: https://context7.com/llp-dev/hurd/llms.txt Retrieves a list of all currently active process IDs. The returned array must be deallocated using `vm_deallocate`. Requires the process port. ```c /* --- proc_getallpids: list all live processes --- */ pid_t *pids; mach_msg_type_number_t npids; err = proc_getallpids (proc, &pids, &npids); for (mach_msg_type_number_t i = 0; i < npids; i++) printf ("pid: %d\n", pids[i]); vm_deallocate (mach_task_self (), (vm_address_t) pids, npids * sizeof(pid_t)); ``` -------------------------------- ### file_exec_paths: Overlay task with executable Source: https://context7.com/llp-dev/hurd/llms.txt Overlays a Mach task with an executable file. Requires building `argv` and `envp` as raw byte blobs for the RPC call. Various parameters control task creation and resource management. ```c /* --- file_exec_paths: overlay a task with an executable file --- */ file_t exec_file; /* task_t new_task; */ /* const char *argv[] = { "/bin/ls", "-la", NULL }; */ /* const char *envp[] = { "HOME=/root", NULL }; */ /* Build argv/envp as raw byte blobs for the RPC ... */ /* err = file_exec_paths (exec_file, new_task, EXEC_NEWTASK | EXEC_DEFAULTS, "/bin/ls", "/bin/ls", (data_t) argv_blob, argv_blob_len, (data_t) envp_blob, envp_blob_len, fd_ports, n_fds, port_array, n_ports, int_array, n_ints, dealloc_names, n_dealloc, destroy_names, n_destroy); */ ``` -------------------------------- ### exec_exec_paths Source: https://context7.com/llp-dev/hurd/llms.txt Loads an ELF image into a target task, setting up its virtual memory map and transferring control. This function is typically called by the filesystem after authentication. ```APIDOC ## exec_exec_paths ### Description Loads an ELF image into a target task. This function is unusual to call directly from user code; `file_exec_paths` is normally used. ### Parameters - **execserver** (file_t) - The port for the exec server. - **binary** (file_t) - An open file descriptor for the binary to execute. - **target_task** (task_t) - The task to load the binary into. - **flags** (int) - Flags controlling execution behavior (e.g., EXEC_DEFAULTS). - **short_path** (const char *) - The short path name of the executable. - **absolute_path** (const char *) - The absolute path name of the executable. - **argv_blob** (char *) - A null-separated byte array representing the argument list. - **argv_blob_size** (size_t) - The size of the argv_blob. - **envp_blob** (char *) - A null-separated byte array representing the environment variables. - **envp_blob_size** (size_t) - The size of the envp_blob. - **dtable** (port_t *) - Array of ports for the file descriptor table. - **n_fds** (mach_msg_type_number_t) - Number of file descriptors. - **portarray** (port_t *) - Array of ports to be made available to the new process. - **n_ports** (mach_msg_type_number_t) - Number of ports in portarray. - **intarray** (int *) - Array of integers to be passed to the new process. - **n_ints** (mach_msg_type_number_t) - Number of integers in intarray. - **dealloc_names** (char **) - Array of names to deallocate after execution. - **n_dealloc** (mach_msg_type_number_t) - Number of names to deallocate. - **destroy_names** (char **) - Array of names to destroy after execution. - **n_destroy** (mach_msg_type_number_t) - Number of names to destroy. ### Returns - **error_t** - An error code indicating success or failure. ``` -------------------------------- ### libdiskfs Callbacks Source: https://context7.com/llp-dev/hurd/llms.txt This section outlines the essential callback functions that a developer must implement to create a disk-based filesystem translator using libdiskfs. ```APIDOC ## diskfs_lookup_hard ### Description Required callback to look up a NAME in directory DP. It should return the node in *NP, locked. ### Parameters - **dp** (struct node *) - The directory node. - **name** (const char *) - The name to look up. - **type** (enum lookup_type) - The type of lookup. - **np** (struct node **) - Output parameter for the found node. - **ds** (struct dirstat *) - Directory stat information. - **cred** (struct protid *) - Credentials for the lookup. ### Return Value error_t - Returns 0 on success. ``` ```APIDOC ## diskfs_node_rdwr ### Description Required callback to read or write file data from/to node NP at OFFSET. ### Parameters - **np** (struct node *) - The node to read or write from. - **uio** (struct uio *) - User I/O structure for data transfer. - **iswrite** (int) - Flag indicating if this is a write operation (1) or read (0). - **unused** (int) - Unused parameter. ### Return Value error_t - Returns 0 on success. ``` ```APIDOC ## diskfs_alloc_node ### Description Required callback to allocate a new on-disk node with the given mode. ### Parameters - **dp** (struct node *) - The parent directory node. - **mode** (mode_t) - The mode for the new node. - **npp** (struct node **) - Output parameter for the newly allocated node. ### Return Value error_t - Returns 0 on success. ``` ```APIDOC ## diskfs_write_disknode ### Description Required callback to write (flush) a node's stat data to disk. ### Parameters - **np** (struct node *) - The node whose stat data needs to be written. - **wait** (int) - Flag indicating whether to wait for the write to complete. ### Return Value error_t - Returns 0 on success. ``` -------------------------------- ### Execute Program with exec_exec_paths Source: https://context7.com/llp-dev/hurd/llms.txt Load an ELF image into a target task using `exec_exec_paths`. This function is typically called by the filesystem after authentication and is used to execute programs with specified arguments and environment variables. ```c #include /* generated from exec.defs */ /* exec_exec_paths: load an ELF image into oldtask. The filesystem calls this after performing authentication. Directly calling exec_exec_paths from user code is unusual; normally file_exec_paths is used instead. */ file_t execserver; /* /hurd/exec port */ file_t binary; /* open file_t for the binary */ task_t target_task; /* Build argv and envp as null-separated byte arrays */ char argv_blob[] = "/usr/bin/cat\0/etc/motd\0"; char envp_blob[] = "PATH=/bin:/usr/bin\0TERM=vt100\0"; err = exec_exec_paths (execserver, binary, target_task, EXEC_DEFAULTS, "/usr/bin/cat", /* short path */ "/usr/bin/cat", /* absolute path */ argv_blob, sizeof(argv_blob), envp_blob, sizeof(envp_blob), dtable, n_fds, portarray, n_ports, intarray, n_ints, dealloc_names, n_dealloc, destroy_names, n_destroy); ``` -------------------------------- ### proc_uname Source: https://context7.com/llp-dev/hurd/llms.txt Retrieves system name information. ```APIDOC ## proc_uname ### Description Retrieves system name information, similar to the `uname` system call. ### Parameters - **proc** (process_t) - The port for the process server. - **uts** (struct utsname *) - Output parameter for the `utsname` structure containing system information. ### Return Value - **error_t** - An error code indicating success or failure. ```